1bdd1243dSDimitry Andric //===- XtensaTargetMachine.cpp - Define TargetMachine for Xtensa ----------===// 2bdd1243dSDimitry Andric // 3bdd1243dSDimitry Andric // The LLVM Compiler Infrastructure 4bdd1243dSDimitry Andric // 5bdd1243dSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 6bdd1243dSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 7bdd1243dSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 8bdd1243dSDimitry Andric // 9bdd1243dSDimitry Andric //===----------------------------------------------------------------------===// 10bdd1243dSDimitry Andric // 11bdd1243dSDimitry Andric // Implements the info about Xtensa target spec. 12bdd1243dSDimitry Andric // 13bdd1243dSDimitry Andric //===----------------------------------------------------------------------===// 14bdd1243dSDimitry Andric 15bdd1243dSDimitry Andric #include "XtensaTargetMachine.h" 16bdd1243dSDimitry Andric #include "TargetInfo/XtensaTargetInfo.h" 17bdd1243dSDimitry Andric #include "llvm/CodeGen/Passes.h" 18bdd1243dSDimitry Andric #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" 19bdd1243dSDimitry Andric #include "llvm/CodeGen/TargetPassConfig.h" 20bdd1243dSDimitry Andric #include "llvm/MC/TargetRegistry.h" 21bdd1243dSDimitry Andric #include "llvm/Transforms/Scalar.h" 22bdd1243dSDimitry Andric #include <optional> 23bdd1243dSDimitry Andric 24bdd1243dSDimitry Andric using namespace llvm; 25bdd1243dSDimitry Andric 26bdd1243dSDimitry Andric extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeXtensaTarget() { 27bdd1243dSDimitry Andric // Register the target. 28bdd1243dSDimitry Andric RegisterTargetMachine<XtensaTargetMachine> A(getTheXtensaTarget()); 29bdd1243dSDimitry Andric } 30bdd1243dSDimitry Andric 31bdd1243dSDimitry Andric static std::string computeDataLayout(const Triple &TT, StringRef CPU, 32bdd1243dSDimitry Andric const TargetOptions &Options, 33bdd1243dSDimitry Andric bool IsLittle) { 34bdd1243dSDimitry Andric std::string Ret = "e-m:e-p:32:32-i8:8:32-i16:16:32-i64:64-n32"; 35bdd1243dSDimitry Andric return Ret; 36bdd1243dSDimitry Andric } 37bdd1243dSDimitry Andric 38bdd1243dSDimitry Andric static Reloc::Model getEffectiveRelocModel(bool JIT, 39bdd1243dSDimitry Andric std::optional<Reloc::Model> RM) { 40bdd1243dSDimitry Andric if (!RM || JIT) 41bdd1243dSDimitry Andric return Reloc::Static; 42bdd1243dSDimitry Andric return *RM; 43bdd1243dSDimitry Andric } 44bdd1243dSDimitry Andric 45bdd1243dSDimitry Andric XtensaTargetMachine::XtensaTargetMachine(const Target &T, const Triple &TT, 46bdd1243dSDimitry Andric StringRef CPU, StringRef FS, 47bdd1243dSDimitry Andric const TargetOptions &Options, 48bdd1243dSDimitry Andric std::optional<Reloc::Model> RM, 49bdd1243dSDimitry Andric std::optional<CodeModel::Model> CM, 505f757f3fSDimitry Andric CodeGenOptLevel OL, bool JIT, 51bdd1243dSDimitry Andric bool IsLittle) 52bdd1243dSDimitry Andric : LLVMTargetMachine(T, computeDataLayout(TT, CPU, Options, IsLittle), TT, 53bdd1243dSDimitry Andric CPU, FS, Options, getEffectiveRelocModel(JIT, RM), 54bdd1243dSDimitry Andric getEffectiveCodeModel(CM, CodeModel::Small), OL), 55bdd1243dSDimitry Andric TLOF(std::make_unique<TargetLoweringObjectFileELF>()) { 56bdd1243dSDimitry Andric initAsmInfo(); 57bdd1243dSDimitry Andric } 58bdd1243dSDimitry Andric 59bdd1243dSDimitry Andric XtensaTargetMachine::XtensaTargetMachine(const Target &T, const Triple &TT, 60bdd1243dSDimitry Andric StringRef CPU, StringRef FS, 61bdd1243dSDimitry Andric const TargetOptions &Options, 62bdd1243dSDimitry Andric std::optional<Reloc::Model> RM, 63bdd1243dSDimitry Andric std::optional<CodeModel::Model> CM, 645f757f3fSDimitry Andric CodeGenOptLevel OL, bool JIT) 65bdd1243dSDimitry Andric : XtensaTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, JIT, true) {} 66bdd1243dSDimitry Andric 67*0fca6ea1SDimitry Andric const XtensaSubtarget * 68*0fca6ea1SDimitry Andric XtensaTargetMachine::getSubtargetImpl(const Function &F) const { 69*0fca6ea1SDimitry Andric Attribute CPUAttr = F.getFnAttribute("target-cpu"); 70*0fca6ea1SDimitry Andric Attribute FSAttr = F.getFnAttribute("target-features"); 71*0fca6ea1SDimitry Andric 72*0fca6ea1SDimitry Andric auto CPU = CPUAttr.isValid() ? CPUAttr.getValueAsString().str() : TargetCPU; 73*0fca6ea1SDimitry Andric auto FS = FSAttr.isValid() ? FSAttr.getValueAsString().str() : TargetFS; 74*0fca6ea1SDimitry Andric 75*0fca6ea1SDimitry Andric auto &I = SubtargetMap[CPU + FS]; 76*0fca6ea1SDimitry Andric if (!I) { 77*0fca6ea1SDimitry Andric // This needs to be done before we create a new subtarget since any 78*0fca6ea1SDimitry Andric // creation will depend on the TM and the code generation flags on the 79*0fca6ea1SDimitry Andric // function that reside in TargetOptions. 80*0fca6ea1SDimitry Andric resetTargetOptions(F); 81*0fca6ea1SDimitry Andric I = std::make_unique<XtensaSubtarget>(TargetTriple, CPU, FS, *this); 82*0fca6ea1SDimitry Andric } 83*0fca6ea1SDimitry Andric return I.get(); 84*0fca6ea1SDimitry Andric } 85*0fca6ea1SDimitry Andric 86*0fca6ea1SDimitry Andric namespace { 87*0fca6ea1SDimitry Andric /// Xtensa Code Generator Pass Configuration Options. 88*0fca6ea1SDimitry Andric class XtensaPassConfig : public TargetPassConfig { 89*0fca6ea1SDimitry Andric public: 90*0fca6ea1SDimitry Andric XtensaPassConfig(XtensaTargetMachine &TM, PassManagerBase &PM) 91*0fca6ea1SDimitry Andric : TargetPassConfig(TM, PM) {} 92*0fca6ea1SDimitry Andric 93*0fca6ea1SDimitry Andric XtensaTargetMachine &getXtensaTargetMachine() const { 94*0fca6ea1SDimitry Andric return getTM<XtensaTargetMachine>(); 95*0fca6ea1SDimitry Andric } 96*0fca6ea1SDimitry Andric 97*0fca6ea1SDimitry Andric bool addInstSelector() override; 98*0fca6ea1SDimitry Andric }; 99*0fca6ea1SDimitry Andric } // end anonymous namespace 100*0fca6ea1SDimitry Andric 101*0fca6ea1SDimitry Andric bool XtensaPassConfig::addInstSelector() { 102*0fca6ea1SDimitry Andric addPass(createXtensaISelDag(getXtensaTargetMachine(), getOptLevel())); 103*0fca6ea1SDimitry Andric return false; 104*0fca6ea1SDimitry Andric } 105*0fca6ea1SDimitry Andric 106bdd1243dSDimitry Andric TargetPassConfig *XtensaTargetMachine::createPassConfig(PassManagerBase &PM) { 107*0fca6ea1SDimitry Andric return new XtensaPassConfig(*this, PM); 108bdd1243dSDimitry Andric } 109