Path: blob/main/contrib/llvm-project/llvm/lib/Target/M68k/M68kTargetMachine.cpp
35266 views
//===-- M68kTargetMachine.cpp - M68k Target Machine -------------*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7///8/// \file9/// This file contains implementation for M68k target machine.10///11//===----------------------------------------------------------------------===//1213#include "M68kTargetMachine.h"14#include "M68k.h"15#include "M68kMachineFunction.h"16#include "M68kSubtarget.h"17#include "M68kTargetObjectFile.h"18#include "TargetInfo/M68kTargetInfo.h"19#include "llvm/CodeGen/GlobalISel/IRTranslator.h"20#include "llvm/CodeGen/GlobalISel/InstructionSelect.h"21#include "llvm/CodeGen/GlobalISel/Legalizer.h"22#include "llvm/CodeGen/GlobalISel/RegBankSelect.h"23#include "llvm/CodeGen/Passes.h"24#include "llvm/CodeGen/TargetPassConfig.h"25#include "llvm/InitializePasses.h"26#include "llvm/MC/TargetRegistry.h"27#include "llvm/PassRegistry.h"28#include <memory>29#include <optional>3031using namespace llvm;3233#define DEBUG_TYPE "m68k"3435extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeM68kTarget() {36RegisterTargetMachine<M68kTargetMachine> X(getTheM68kTarget());37auto *PR = PassRegistry::getPassRegistry();38initializeGlobalISel(*PR);39initializeM68kDAGToDAGISelLegacyPass(*PR);40initializeM68kExpandPseudoPass(*PR);41initializeM68kGlobalBaseRegPass(*PR);42initializeM68kCollapseMOVEMPass(*PR);43}4445namespace {4647std::string computeDataLayout(const Triple &TT, StringRef CPU,48const TargetOptions &Options) {49std::string Ret = "";50// M68k is Big Endian51Ret += "E";5253// FIXME how to wire it with the used object format?54Ret += "-m:e";5556// M68k pointers are always 32 bit wide even for 16-bit CPUs.57// The ABI only specifies 16-bit alignment.58// On at least the 68020+ with a 32-bit bus, there is a performance benefit59// to having 32-bit alignment.60Ret += "-p:32:16:32";6162// Bytes do not require special alignment, words are word aligned and63// long words are word aligned at minimum.64Ret += "-i8:8:8-i16:16:16-i32:16:32";6566// FIXME no floats at the moment6768// The registers can hold 8, 16, 32 bits69Ret += "-n8:16:32";7071Ret += "-a:0:16-S16";7273return Ret;74}7576Reloc::Model getEffectiveRelocModel(const Triple &TT,77std::optional<Reloc::Model> RM) {78// If not defined we default to static79if (!RM.has_value())80return Reloc::Static;8182return *RM;83}8485CodeModel::Model getEffectiveCodeModel(std::optional<CodeModel::Model> CM,86bool JIT) {87if (!CM) {88return CodeModel::Small;89} else if (CM == CodeModel::Large) {90llvm_unreachable("Large code model is not supported");91} else if (CM == CodeModel::Kernel) {92llvm_unreachable("Kernel code model is not implemented yet");93}94return CM.value();95}96} // end anonymous namespace9798M68kTargetMachine::M68kTargetMachine(const Target &T, const Triple &TT,99StringRef CPU, StringRef FS,100const TargetOptions &Options,101std::optional<Reloc::Model> RM,102std::optional<CodeModel::Model> CM,103CodeGenOptLevel OL, bool JIT)104: LLVMTargetMachine(T, computeDataLayout(TT, CPU, Options), TT, CPU, FS,105Options, getEffectiveRelocModel(TT, RM),106::getEffectiveCodeModel(CM, JIT), OL),107TLOF(std::make_unique<M68kELFTargetObjectFile>()),108Subtarget(TT, CPU, FS, *this) {109initAsmInfo();110}111112M68kTargetMachine::~M68kTargetMachine() {}113114const M68kSubtarget *115M68kTargetMachine::getSubtargetImpl(const Function &F) const {116Attribute CPUAttr = F.getFnAttribute("target-cpu");117Attribute FSAttr = F.getFnAttribute("target-features");118119auto CPU = CPUAttr.isValid() ? CPUAttr.getValueAsString().str() : TargetCPU;120auto FS = FSAttr.isValid() ? FSAttr.getValueAsString().str() : TargetFS;121122auto &I = SubtargetMap[CPU + FS];123if (!I) {124// This needs to be done before we create a new subtarget since any125// creation will depend on the TM and the code generation flags on the126// function that reside in TargetOptions.127resetTargetOptions(F);128I = std::make_unique<M68kSubtarget>(TargetTriple, CPU, FS, *this);129}130return I.get();131}132133MachineFunctionInfo *M68kTargetMachine::createMachineFunctionInfo(134BumpPtrAllocator &Allocator, const Function &F,135const TargetSubtargetInfo *STI) const {136return M68kMachineFunctionInfo::create<M68kMachineFunctionInfo>(Allocator, F,137STI);138}139140//===----------------------------------------------------------------------===//141// Pass Pipeline Configuration142//===----------------------------------------------------------------------===//143144namespace {145class M68kPassConfig : public TargetPassConfig {146public:147M68kPassConfig(M68kTargetMachine &TM, PassManagerBase &PM)148: TargetPassConfig(TM, PM) {}149150M68kTargetMachine &getM68kTargetMachine() const {151return getTM<M68kTargetMachine>();152}153154const M68kSubtarget &getM68kSubtarget() const {155return *getM68kTargetMachine().getSubtargetImpl();156}157void addIRPasses() override;158bool addIRTranslator() override;159bool addLegalizeMachineIR() override;160bool addRegBankSelect() override;161bool addGlobalInstructionSelect() override;162bool addInstSelector() override;163void addPreSched2() override;164void addPreEmitPass() override;165};166} // namespace167168TargetPassConfig *M68kTargetMachine::createPassConfig(PassManagerBase &PM) {169return new M68kPassConfig(*this, PM);170}171172void M68kPassConfig::addIRPasses() {173addPass(createAtomicExpandLegacyPass());174TargetPassConfig::addIRPasses();175}176177bool M68kPassConfig::addInstSelector() {178// Install an instruction selector.179addPass(createM68kISelDag(getM68kTargetMachine()));180addPass(createM68kGlobalBaseRegPass());181return false;182}183184bool M68kPassConfig::addIRTranslator() {185addPass(new IRTranslator());186return false;187}188189bool M68kPassConfig::addLegalizeMachineIR() {190addPass(new Legalizer());191return false;192}193194bool M68kPassConfig::addRegBankSelect() {195addPass(new RegBankSelect());196return false;197}198199bool M68kPassConfig::addGlobalInstructionSelect() {200addPass(new InstructionSelect());201return false;202}203204void M68kPassConfig::addPreSched2() { addPass(createM68kExpandPseudoPass()); }205206void M68kPassConfig::addPreEmitPass() {207addPass(createM68kCollapseMOVEMPass());208}209210211