diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index 7416f4757f8c63c5e934995ebc702e2aff23a160..4b1c89039d908aea537083889d3eeca26c5652d4 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -390,6 +390,8 @@ def TargetAArch64 : TargetArch<["aarch64"]>; def TargetAnyArm : TargetArch; def TargetAVR : TargetArch<["avr"]>; def TargetBPF : TargetArch<["bpfel", "bpfeb"]>; +// OHOS_LOCAL +def TargetXVM : TargetArch<["xvm"]>; def TargetMips32 : TargetArch<["mips", "mipsel"]>; def TargetAnyMips : TargetArch<["mips", "mipsel", "mips64", "mips64el"]>; def TargetMSP430 : TargetArch<["msp430"]>; @@ -1934,6 +1936,16 @@ def WebAssemblyExportName : InheritableAttr, let Subjects = SubjectList<[Function], ErrorDiag>; } +// OHOS_LOCAL begin +def XVMExportName : InheritableAttr, + TargetSpecificAttr { + let Spellings = [Clang<"xvm_export_name">]; + let Args = [StringArgument<"ExportName">]; + let Documentation = [Undocumented]; + let Subjects = SubjectList<[Function], ErrorDiag>; +} +// OHOS_LOCAL end + def WebAssemblyImportModule : InheritableAttr, TargetSpecificAttr { let Spellings = [Clang<"import_module">]; diff --git a/clang/lib/Basic/CMakeLists.txt b/clang/lib/Basic/CMakeLists.txt index 3e052c0cf995709ae9023b98f728a9463cf0a4f4..ff83f996353502e5aebaf3f0d7655db41e7d7bed 100644 --- a/clang/lib/Basic/CMakeLists.txt +++ b/clang/lib/Basic/CMakeLists.txt @@ -98,6 +98,8 @@ add_clang_library(clangBasic Targets/WebAssembly.cpp Targets/X86.cpp Targets/XCore.cpp + # OHOS_LOCAL + Targets/XVM.cpp TokenKinds.cpp TypeTraits.cpp Version.cpp diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp index d2eac5cae7b6ae9cd9fe044a2e2ca317b00f52cd..4a136b1c3e396f98fd20a9230dca83ed54719660 100644 --- a/clang/lib/Basic/Targets.cpp +++ b/clang/lib/Basic/Targets.cpp @@ -40,6 +40,8 @@ #include "Targets/WebAssembly.h" #include "Targets/X86.h" #include "Targets/XCore.h" +// OHOS_LOCAL +#include "Targets/XVM.h" #include "clang/Basic/Diagnostic.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/Triple.h" @@ -119,6 +121,10 @@ TargetInfo *AllocateTarget(const llvm::Triple &Triple, case llvm::Triple::xcore: return new XCoreTargetInfo(Triple, Opts); + // OHOS_LOCAL begin + case llvm::Triple::xvm: + return new XVMTargetInfo(Triple, Opts); + // OHOS_LOCAL end case llvm::Triple::hexagon: if (os == llvm::Triple::Linux && diff --git a/clang/lib/Basic/Targets/XVM.cpp b/clang/lib/Basic/Targets/XVM.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6e61b363303d89a0e79217d4f16d50f262c57f0f --- /dev/null +++ b/clang/lib/Basic/Targets/XVM.cpp @@ -0,0 +1,46 @@ +//===--- XVM.cpp - Implement XVM target feature support -------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file implements XVM TargetInfo objects. +// +//===----------------------------------------------------------------------===// + +#include "XVM.h" +#include "Targets.h" +#include "clang/Basic/MacroBuilder.h" +#include "clang/Basic/TargetBuiltins.h" +#include "llvm/ADT/StringRef.h" + +using namespace clang; +using namespace clang::targets; + +const Builtin::Info XVMTargetInfo::BuiltinInfo[] = { +#define BUILTIN(ID, TYPE, ATTRS) \ + {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr}, +#include "clang/Basic/Builtins.def" +}; + +void XVMTargetInfo::getTargetDefines(const LangOptions &Opts, + MacroBuilder &Builder) const { + Builder.defineMacro("__xvm__"); + Builder.defineMacro("__XVM__"); +} + +static constexpr llvm::StringLiteral ValidCPUNames[] = {"xvm", "XVM"}; + +bool XVMTargetInfo::isValidCPUName(StringRef Name) const { + return llvm::is_contained(ValidCPUNames, Name); +} + +void XVMTargetInfo::fillValidCPUList(SmallVectorImpl &Values) const { + Values.append(std::begin(ValidCPUNames), std::end(ValidCPUNames)); +} + +ArrayRef XVMTargetInfo::getTargetBuiltins() const { + return llvm::makeArrayRef(BuiltinInfo, 1); +} diff --git a/clang/lib/Basic/Targets/XVM.h b/clang/lib/Basic/Targets/XVM.h new file mode 100644 index 0000000000000000000000000000000000000000..d5ef06081cf57e32faa7b922476fdec96523f78e --- /dev/null +++ b/clang/lib/Basic/Targets/XVM.h @@ -0,0 +1,89 @@ +//===--- XVM.h - Declare XVM target feature support -------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file declares XVM TargetInfo objects. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_LIB_BASIC_TARGETS_XVM_H +#define LLVM_CLANG_LIB_BASIC_TARGETS_XVM_H + +#include "clang/Basic/TargetInfo.h" +#include "clang/Basic/TargetOptions.h" +#include "llvm/ADT/Triple.h" +#include "llvm/Support/Compiler.h" + +namespace clang { +namespace targets { + +class LLVM_LIBRARY_VISIBILITY XVMTargetInfo : public TargetInfo { + static const Builtin::Info BuiltinInfo[]; + +public: + XVMTargetInfo(const llvm::Triple &Triple, const TargetOptions &) + : TargetInfo(Triple) { + LongWidth = LongAlign = PointerWidth = PointerAlign = 64; + SizeType = UnsignedLong; + PtrDiffType = SignedLong; + IntPtrType = SignedLong; + IntMaxType = SignedLong; + Int64Type = SignedLong; + RegParmMax = 5; + resetDataLayout("e-m:e-p:64:64-i64:64-n64-S128"); + MaxAtomicPromoteWidth = 64; + MaxAtomicInlineWidth = 64; + TLSSupported = false; + } + + void getTargetDefines(const LangOptions &Opts, + MacroBuilder &Builder) const override; + + ArrayRef getTargetBuiltins() const override; + + const char *getClobbers() const override { return ""; } + + BuiltinVaListKind getBuiltinVaListKind() const override { + return TargetInfo::VoidPtrBuiltinVaList; + } + + bool isValidGCCRegisterName(StringRef Name) const override { return true; } + ArrayRef getGCCRegNames() const override { return None; } + + bool validateAsmConstraint(const char *&Name, + TargetInfo::ConstraintInfo &Info) const override { + return true; + } + + ArrayRef getGCCRegAliases() const override { + return None; + } + + bool allowDebugInfoForExternalRef() const override { return true; } + + CallingConvCheckResult checkCallingConvention(CallingConv CC) const override { + switch (CC) { + default: + return CCCR_Warning; + case CC_C: + case CC_OpenCLKernel: + return CCCR_OK; + } + } + + bool isValidCPUName(StringRef Name) const override; + + void fillValidCPUList(SmallVectorImpl &Values) const override; + + bool setCPU(const std::string &Name) override { + StringRef CPUName(Name); + return isValidCPUName(CPUName); + } +}; +} // namespace targets +} // namespace clang +#endif // LLVM_CLANG_LIB_BASIC_TARGETS_XVM_H diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp index 3e667abc6f1c269dfe25ddca83eff27807551828..2de773e38519ef46ba3cdb81a0f0e0be7b914d7e 100644 --- a/clang/lib/CodeGen/TargetInfo.cpp +++ b/clang/lib/CodeGen/TargetInfo.cpp @@ -5491,6 +5491,108 @@ PPC64TargetCodeGenInfo::initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF, /*IsAIX*/ false); } +// OHOS_LOCAL begin +//===----------------------------------------------------------------------===// +// XVM ABI Implementation +//===----------------------------------------------------------------------===// +class XVMABIInfo : public DefaultABIInfo { +public: + enum ClassifyType { + Return, + Argument, + }; + + XVMABIInfo(CodeGen::CodeGenTypes &CGT) : DefaultABIInfo(CGT) {} + + ABIArgInfo classifyReturnAndArgumentType(QualType RetTy, ClassifyType type) const; + + void computeInfo(CGFunctionInfo &FI) const override { + if (!getCXXABI().classifyReturnType(FI)) + FI.getReturnInfo() = classifyReturnAndArgumentType(FI.getReturnType(), Return); + for (auto &I : FI.arguments()) + I.info = classifyReturnAndArgumentType(I.type, Argument); + } + + Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, + QualType Ty) const override { + return EmitVAArgInstr(CGF, VAListAddr, Ty, classifyReturnAndArgumentType(Ty, Argument)); + } +}; + +class XVMTargetCodeGenInfo : public TargetCodeGenInfo { +public: + XVMTargetCodeGenInfo(CodeGen::CodeGenTypes &CGT) + : TargetCodeGenInfo(std::make_unique(CGT)) {} + + void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, + CodeGen::CodeGenModule &CGM) const override { + TargetCodeGenInfo::setTargetAttributes(D, GV, CGM); + if (const auto *FD = dyn_cast_or_null(D)) { + if (const auto *Attr = FD->getAttr()) { + llvm::Function *Fn = cast(GV); + llvm::AttrBuilder B(GV->getContext()); + B.addAttribute("xvm-export-name", Attr->getExportName()); + Fn->addFnAttrs(B); + } + } + } +}; + +ABIArgInfo XVMABIInfo::classifyReturnAndArgumentType(QualType RetTy, ClassifyType type) const { + if (RetTy->isVoidType()) + return ABIArgInfo::getIgnore(); + + if (const auto *VT = RetTy->getAs()) { + llvm::report_fatal_error("Unsupported: No vector type as return is supported for now"); + } + // Non-Aggregate Type + if (!isAggregateTypeForABI(RetTy)) { + // Treat an enum type as its underlying type. + if (const EnumType *EnumTy = RetTy->getAs()) + RetTy = EnumTy->getDecl()->getIntegerType(); + + if (const auto *EIT = RetTy->getAs()) + if (EIT->getNumBits() > + getContext().getTypeSize(getContext().getTargetInfo().hasInt128Type() + ? getContext().Int128Ty + : getContext().LongLongTy)) + return getNaturalAlignIndirect(RetTy); + + return (isPromotableIntegerTypeForABI(RetTy) ? ABIArgInfo::getExtend(RetTy) + : ABIArgInfo::getDirect()); + } + // Aggregate Type + uint64_t Size = getContext().getTypeSize(RetTy); + if (isEmptyRecord(getContext(), RetTy, true) || Size == 0) + return ABIArgInfo::getIgnore(); + + const Type *Base = nullptr; + uint64_t Members = 0; + /* + In Aarch64, this isHomogeneousAggregate is only called to check for + Homogenous Float Aggregates (HFAs), since XVM doesn't have floats + or doubles, do not need to check if it is HA. + Side Note: Both isHomogeneousAggregateBaseType and isHomogeneousAggregateSmallEnough + are handled with isHomogeneousAggregate + + isHomogeneousAggregateSmallEnough should check whether or not the HA contains at most 4 + members because the AAPCS defines a homogeneous aggregate (HA) + as an aggregate type containing between one and four members + */ + if (isHomogeneousAggregate(RetTy, Base, Members)) + return ABIArgInfo::getDirect(); + + if (Size <= 64 && type == Return) { + if (getDataLayout().isLittleEndian()) { + return ABIArgInfo::getDirect( + llvm::IntegerType::get(getVMContext(), Size)); + } + //FIXME: todo for BE + } + return getNaturalAlignIndirect(RetTy); +} +// OHOS_LOCAL end + //===----------------------------------------------------------------------===// // AArch64 ABI Implementation //===----------------------------------------------------------------------===// @@ -11562,6 +11664,11 @@ const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() { default: return SetCGInfo(new DefaultTargetCodeGenInfo(Types)); + // OHOS_LOCAL begin + case llvm::Triple::xvm: + return SetCGInfo(new XVMTargetCodeGenInfo(Types)); + // OHOS_LOCAL end + case llvm::Triple::le32: return SetCGInfo(new PNaClTargetCodeGenInfo(Types)); case llvm::Triple::m68k: diff --git a/clang/lib/Driver/CMakeLists.txt b/clang/lib/Driver/CMakeLists.txt index 7be7f959e896f7c3eb6b0bc30b639607a090a51b..00da647e4c66f6360c6d69cc4fdd3d28c2a6329e 100644 --- a/clang/lib/Driver/CMakeLists.txt +++ b/clang/lib/Driver/CMakeLists.txt @@ -75,6 +75,8 @@ add_clang_library(clangDriver ToolChains/OpenBSD.cpp ToolChains/PS4CPU.cpp ToolChains/RISCVToolchain.cpp + # OHOS_LOCAL + ToolChains/XVMToolchain.cpp ToolChains/Solaris.cpp ToolChains/SPIRV.cpp ToolChains/TCE.cpp diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index cbd2ff494de91b77695f271efc6a7f434c79064d..4717ae56d3a791a1b0bad7ba29d19af198955e27 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -32,6 +32,8 @@ #include "ToolChains/Hurd.h" #include "ToolChains/Lanai.h" #include "ToolChains/Linux.h" +// OHOS_LOCAL +#include "ToolChains/XVMToolchain.h" #include "ToolChains/MSP430.h" #include "ToolChains/MSVC.h" #include "ToolChains/MinGW.h" @@ -6095,6 +6097,11 @@ const ToolChain &Driver::getToolChain(const ArgList &Args, case llvm::Triple::wasm64: TC = std::make_unique(*this, Target, Args); break; + // OHOS_LOCAL begin + case llvm::Triple::xvm: + TC = std::make_unique(*this, Target, Args); + break; + // OHOS_LOCAL end case llvm::Triple::avr: TC = std::make_unique(*this, Target, Args); break; diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp index d20aa1390f0b130dbdb5db850e9feb8ebfd20552..6e7fccf898715cfc12afd4ba97b8fe31447d5bf2 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -436,6 +436,13 @@ std::string tools::getCPUName(const Driver &D, const ArgList &Args, return A->getValue(); return ""; + // OHOS_LOCAL begin + case llvm::Triple::xvm: + if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) + return A->getValue(); + return ""; + // OHOS_LOCAL END + case llvm::Triple::sparc: case llvm::Triple::sparcel: case llvm::Triple::sparcv9: diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp index f8dfb189eaf6ae03a8f3caadc7a0648a3e646eaf..e320fee08547666e8ff94f9de3a45ccbd014e253 100644 --- a/clang/lib/Driver/ToolChains/Gnu.cpp +++ b/clang/lib/Driver/ToolChains/Gnu.cpp @@ -2851,6 +2851,8 @@ bool Generic_GCC::IsIntegratedAssemblerDefault() const { case llvm::Triple::avr: case llvm::Triple::bpfel: case llvm::Triple::bpfeb: + // OHOS_LOCAL + case llvm::Triple::xvm: case llvm::Triple::csky: case llvm::Triple::hexagon: case llvm::Triple::lanai: diff --git a/clang/lib/Driver/ToolChains/XVMToolchain.cpp b/clang/lib/Driver/ToolChains/XVMToolchain.cpp new file mode 100644 index 0000000000000000000000000000000000000000..bae9da13d0952bf4b1385dc0a677b9b973ce202e --- /dev/null +++ b/clang/lib/Driver/ToolChains/XVMToolchain.cpp @@ -0,0 +1,201 @@ +//===--- XVMToolchain.h - XVMToolchain ToolChain Implementations --------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "XVMToolchain.h" +#include "CommonArgs.h" +#include "clang/Config/config.h" +#include "clang/Driver/Distro.h" +#include "clang/Driver/Driver.h" +#include "clang/Driver/Options.h" +#include "clang/Driver/SanitizerArgs.h" +#include "llvm/Option/ArgList.h" +#include "llvm/ProfileData/InstrProf.h" +#include "llvm/Support/Path.h" +#include "llvm/Support/ScopedPrinter.h" +#include "llvm/Support/VirtualFileSystem.h" +#include + +#include "clang/Driver/Compilation.h" +#include "clang/Driver/InputInfo.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/raw_ostream.h" + +using namespace clang::driver; +using namespace clang::driver::toolchains; +using namespace clang::driver::tools; +using namespace clang; +using namespace llvm::opt; + +// using tools::addPathIfExists; + +XVMToolchain::XVMToolchain(const Driver &D, const llvm::Triple &Triple, + const ArgList &Args) + : Generic_ELF(D, Triple, Args) { + getProgramPaths().push_back(D.Dir); + getFilePaths().push_back(computeSysRoot() + "/lib"); +} + +Tool *XVMToolchain::buildLinker() const { + return new tools::XVM::Linker(*this); +} + +void XVMToolchain::AddClangSystemIncludeArgs(const ArgList &DriverArgs, + ArgStringList &CC1Args) const { + if (DriverArgs.hasArg(options::OPT_nostdinc)) + return; + + if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) { + SmallString<128> Dir(getDriver().ResourceDir); + llvm::sys::path::append(Dir, "include"); + addSystemInclude(DriverArgs, CC1Args, Dir.str()); + } + + if (!DriverArgs.hasArg(options::OPT_nostdlibinc)) { + SmallString<128> Dir(computeSysRoot()); + llvm::sys::path::append(Dir, "include"); + addSystemInclude(DriverArgs, CC1Args, Dir.str()); + } +} + +std::string XVMToolchain::computeSysRoot() const { + if (!getDriver().SysRoot.empty()) + return getDriver().SysRoot; + + SmallString<128> SysRootDir; + llvm::sys::path::append(SysRootDir, getDriver().Dir, "..", + getDriver().getTargetTriple()); + + if (!llvm::sys::fs::exists(SysRootDir)) + return std::string(); + + return std::string(SysRootDir.str()); +} + +std::string XVM::Linker::getLinkerPath(const ArgList &Args) const { + const ToolChain &ToolChain = getToolChain(); + const Driver &D = ToolChain.getDriver(); + StringRef UseLinker; + std::string ArgAsString; + std::string xvm_ld_executable; + + // Try to use the one passed in + if (const Arg* A = Args.getLastArg(options::OPT_fuse_ld_EQ)) { + UseLinker = A->getValue(); + ArgAsString = A->getAsString(Args); + if (llvm::sys::path::is_absolute(UseLinker)) { + if (llvm::sys::fs::can_execute(UseLinker)) + return std::string(UseLinker); + } + // Try one more time for the passed in + if (!UseLinker.empty()) { + const char * ByteArray = UseLinker.data(); + if (*ByteArray == '/') { + xvm_ld_executable = D.Dir + std::string(UseLinker); + } else { + xvm_ld_executable = D.Dir + "/" + std::string(UseLinker); + } + if (llvm::sys::path::is_absolute(xvm_ld_executable)) { + if (llvm::sys::fs::can_execute(xvm_ld_executable)) + return xvm_ld_executable; + } + } + } + // Try the pre-set one + xvm_ld_executable = D.Dir + LdName; + if (llvm::sys::path::is_absolute(xvm_ld_executable) && + llvm::sys::fs::can_execute(xvm_ld_executable)) + return xvm_ld_executable; + // Return the default one + return ToolChain.GetProgramPath(ToolChain.getDefaultLinker()); +} + +void XVM::Linker::ConstructJobForLTO(Compilation &C, const JobAction &JA, + const InputInfo &Output, + const InputInfoList &Inputs, + const ArgList &Args, + const char *LinkingOutput) const { + const ToolChain &ToolChain = getToolChain(); + const Driver &D = ToolChain.getDriver(); + ArgStringList CmdArgs; + if (!D.SysRoot.empty()) + CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot)); + Args.AddAllArgs(CmdArgs, options::OPT_L); + + std::string LinkerExec = getLinkerPath(Args); + CmdArgs.push_back("-m"); + CmdArgs.push_back(Args.MakeArgString(ToolChain.getTripleString().data())); + CmdArgs.push_back("-o"); + CmdArgs.push_back(Output.getFilename()); + for (auto Input : Inputs) { + if (Input.isFilename()) { + CmdArgs.push_back(Input.getFilename()); + } else { + if (std::strcmp(Input.getInputArg().getValue(0), "--lto-emit-asm") == 0) { + CmdArgs.push_back("--lto-emit-asm"); + } + } + } + C.addCommand(std::make_unique( + JA, *this, ResponseFileSupport::AtFileCurCP(), Args.MakeArgString(LinkerExec), + CmdArgs, Inputs, Output)); +} + +void XVM::Linker::ConstructJobForNonLTO(Compilation &C, const JobAction &JA, + const InputInfo &Output, + const InputInfoList &Inputs, + const ArgList &Args, + const char *LinkingOutput) const { + const ToolChain &ToolChain = getToolChain(); + const Driver &D = ToolChain.getDriver(); + ArgStringList CmdArgs; + if (!D.SysRoot.empty()) + CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot)); + Args.AddAllArgs(CmdArgs, options::OPT_L); + + std::string TmpLinkOutput; + std::string Linker = D.Dir + LlvmLinkName; + for (auto Input : Inputs) { + if (Input.isFilename()) { + CmdArgs.push_back(Input.getFilename()); + TmpLinkOutput = Input.getFilename(); + } + } + TmpLinkOutput += ".ir"; + CmdArgs.push_back("-o"); + CmdArgs.push_back(Args.MakeArgString(TmpLinkOutput.data())); + C.addCommand(std::make_unique( + JA, *this, ResponseFileSupport::AtFileCurCP(), Args.MakeArgString(Linker), + CmdArgs, Inputs, Output)); + + // construct llc cmd arguments + CmdArgs.clear(); + CmdArgs.push_back("-march"); + CmdArgs.push_back(Args.MakeArgString(ToolChain.getTripleString().data())); + CmdArgs.push_back(Args.MakeArgString(TmpLinkOutput.data())); + CmdArgs.push_back("-o"); + CmdArgs.push_back(Output.getFilename()); + std::string Llc_executable = D.Dir + LlcName; + C.addCommand(std::make_unique( + JA, *this, ResponseFileSupport::AtFileCurCP(), Args.MakeArgString(Llc_executable), + CmdArgs, Inputs, Output)); +} + +void XVM::Linker::ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, + const InputInfoList &Inputs, + const ArgList &Args, + const char *LinkingOutput) const { + if (Args.hasArg(options::OPT_flto) || + Args.hasArg(options::OPT_flto_EQ) || + Args.hasArg(options::OPT_flto_EQ_auto) || + Args.hasArg(options::OPT_flto_EQ_jobserver)) { + ConstructJobForLTO(C, JA, Output, Inputs, Args, LinkingOutput); + } else { + ConstructJobForNonLTO(C, JA, Output, Inputs, Args, LinkingOutput); + } +} diff --git a/clang/lib/Driver/ToolChains/XVMToolchain.h b/clang/lib/Driver/ToolChains/XVMToolchain.h new file mode 100644 index 0000000000000000000000000000000000000000..68059a7eb6e90d9baaa58c95cec3a5384d191cb5 --- /dev/null +++ b/clang/lib/Driver/ToolChains/XVMToolchain.h @@ -0,0 +1,74 @@ +//===--- XVMToolchain.h - XVMToolchain ToolChain Implementations --------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_XVMLTOLINUX_H +#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_XVMLTOLINUX_H + +#include "Gnu.h" +#include "clang/Driver/ToolChain.h" + +namespace clang { +namespace driver { +namespace toolchains { + +class LLVM_LIBRARY_VISIBILITY XVMToolchain : public Generic_ELF { +public: + XVMToolchain(const Driver &D, const llvm::Triple &Triple, + const llvm::opt::ArgList &Args); + + void + AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const override; + std::string computeSysRoot() const override; + +protected: + Tool *buildLinker() const override; +}; + +} // end namespace toolchains + +namespace tools { + +namespace XVM { + +class LLVM_LIBRARY_VISIBILITY Linker : public Tool { +public: + Linker(const ToolChain &TC) : Tool("XVM::Linker", "ld", TC) {} + bool hasIntegratedCPP() const override { return false; } + bool isLinkJob() const override { return true; } + void ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, const InputInfoList &Inputs, + const llvm::opt::ArgList &TCArgs, + const char *LinkingOutput) const override; +private: + std::string getLinkerPath(const llvm::opt::ArgList &Args) const; + void ConstructJobForLTO(Compilation &C, const JobAction &JA, + const InputInfo &Output, const InputInfoList &Inputs, + const llvm::opt::ArgList &TCArgs, + const char *LinkingOutput) const; + void ConstructJobForNonLTO(Compilation &C, const JobAction &JA, + const InputInfo &Output, const InputInfoList &Inputs, + const llvm::opt::ArgList &TCArgs, + const char *LinkingOutput) const; + // The tool name used for lto linking + const char * LdName = "/ld.lld"; + // The tool name used for linking *.ll/*.bc files; + const char * LlvmLinkName = "/llvm-link"; + // The tool name used for the final xvm llvm-backend + const char * LlcName = "/llc"; +}; + +} // end namespace XVM + +} // end namespace tools + +} // end namespace driver +} // end namespace clang + + +#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_XVMLTOLINUX_H diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index ed6d1cc923cc01c1f0b5147f423c070195be92e2..00120cc54c4b646eb5502729f71deba275a90dde 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -7315,6 +7315,24 @@ static void handleWebAssemblyExportNameAttr(Sema &S, Decl *D, const ParsedAttr & D->addAttr(UsedAttr::CreateImplicit(S.Context)); } +// OHOS_LOCAL begin +static void handleXVMExportNameAttr(Sema &S, Decl *D, const ParsedAttr &AL) { + if (!isFunctionOrMethod(D)) { + S.Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type) + << "'xvm_export_name'" << ExpectedFunction; + return; + } + + StringRef Str; + SourceLocation ArgLoc; + if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &ArgLoc)) + return; + + D->addAttr(::new (S.Context) XVMExportNameAttr(S.Context, AL, Str)); + D->addAttr(UsedAttr::CreateImplicit(S.Context)); +} +// OHOS_LOCAL end + WebAssemblyImportModuleAttr * Sema::mergeImportModuleAttr(Decl *D, const WebAssemblyImportModuleAttr &AL) { auto *FD = cast(D); @@ -8486,6 +8504,11 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL, case ParsedAttr::AT_WebAssemblyExportName: handleWebAssemblyExportNameAttr(S, D, AL); break; + // OHOS_LOCAL begin + case ParsedAttr::AT_XVMExportName: + handleXVMExportNameAttr(S, D, AL); + break; + // OHOS_LOCAL end case ParsedAttr::AT_WebAssemblyImportModule: handleWebAssemblyImportModuleAttr(S, D, AL); break; diff --git a/clang/test/CodeGen/XVM/xvm-export-name.c b/clang/test/CodeGen/XVM/xvm-export-name.c new file mode 100644 index 0000000000000000000000000000000000000000..916510f0c51aeea47c0f9404481d412647659b5e --- /dev/null +++ b/clang/test/CodeGen/XVM/xvm-export-name.c @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -triple xvm-unknown-unknown-xvm -emit-llvm -O0 -o - %s | FileCheck %s + +__attribute__((xvm_export_name("bar"))) int foo(void); + +int foo(void) { return 42; } + +// CHECK: define dso_local i32 @foo() [[A:#[0-9]+]] +// CHECK: attributes [[A]] = {{{.*}} "xvm-export-name"="bar" {{.*}}} diff --git a/clang/test/Misc/pragma-attribute-supported-attributes-list.test b/clang/test/Misc/pragma-attribute-supported-attributes-list.test index 6192296477c5156b877178475a955fe558157a54..1a5775f4e14bf5cbb83b6276df8a93a234578e63 100644 --- a/clang/test/Misc/pragma-attribute-supported-attributes-list.test +++ b/clang/test/Misc/pragma-attribute-supported-attributes-list.test @@ -199,5 +199,6 @@ // CHECK-NEXT: WorkGroupSizeHint (SubjectMatchRule_function) // CHECK-NEXT: XRayInstrument (SubjectMatchRule_function, SubjectMatchRule_objc_method) // CHECK-NEXT: XRayLogArgs (SubjectMatchRule_function, SubjectMatchRule_objc_method) +// CHECK-NEXT: XVMExportName (SubjectMatchRule_function) // CHECK-NEXT: ZeroCallUsedRegs (SubjectMatchRule_function) // CHECK-NEXT: End of supported attributes. diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp index abcc8a984a65905cc2b62a84903015a86b588c7b..185757ad8c29a94775e0b8694a71972659ec2b46 100644 --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -151,6 +151,8 @@ static std::tuple parseEmulation(StringRef emul) { .Case("elf64btsmip", {ELF64BEKind, EM_MIPS}) .Case("elf64ltsmip", {ELF64LEKind, EM_MIPS}) .Case("elf64lriscv", {ELF64LEKind, EM_RISCV}) + // OHOS_LOCAL + .Case("xvm", {ELF64LEKind, EM_XVM}) .Case("elf64ppc", {ELF64BEKind, EM_PPC64}) .Case("elf64lppc", {ELF64LEKind, EM_PPC64}) .Cases("elf_amd64", "elf_x86_64", {ELF64LEKind, EM_X86_64}) diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index 473809b05e9c2a3f5ac86a32d0e0f97376e219b7..ba317d1e4bb06d373f4c63609769e77968b21ecd 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -1538,6 +1538,10 @@ static uint16_t getBitcodeMachineKind(StringRef path, const Triple &t) { return t.isOSIAMCU() ? EM_IAMCU : EM_386; case Triple::x86_64: return EM_X86_64; + // OHOS_LOCAL begin + case Triple::xvm: + return EM_XVM; + // OHOS_LOCAL end default: error(path + ": could not infer e_machine from bitcode target triple " + t.str()); diff --git a/llvm/CMakeLists.txt b/llvm/CMakeLists.txt index 2bbdfcae6ae8fed17ad69c324adc53804899f10f..34c1f19a9f95a1866b5778f079893b548f6927eb 100644 --- a/llvm/CMakeLists.txt +++ b/llvm/CMakeLists.txt @@ -384,6 +384,8 @@ set(LLVM_ALL_TARGETS WebAssembly X86 XCore + # OHOS_LOCAL + XVM ) # List of targets with JIT support: diff --git a/llvm/include/llvm/ADT/Triple.h b/llvm/include/llvm/ADT/Triple.h index 72657016efcfa3f527be4f6ce206935f1631ea9e..a021f862c4dbd7c79c02236aaaadbbe2731d61ba 100644 --- a/llvm/include/llvm/ADT/Triple.h +++ b/llvm/include/llvm/ADT/Triple.h @@ -85,6 +85,8 @@ public: x86, // X86: i[3-9]86 x86_64, // X86-64: amd64, x86_64 xcore, // XCore: xcore + // OHOS_LOCAL + xvm, // XVM nvptx, // NVPTX: 32-bit nvptx64, // NVPTX: 64-bit le32, // le32: generic little-endian 32-bit CPU (PNaCl) diff --git a/llvm/include/llvm/BinaryFormat/ELF.h b/llvm/include/llvm/BinaryFormat/ELF.h index 556fe9c6a1a042caac23002459a5c12fefc438ef..234c946b2014b812c789004bf2c163b594371382 100644 --- a/llvm/include/llvm/BinaryFormat/ELF.h +++ b/llvm/include/llvm/BinaryFormat/ELF.h @@ -320,6 +320,8 @@ enum { EM_VE = 251, // NEC SX-Aurora VE EM_CSKY = 252, // C-SKY 32-bit processor EM_LOONGARCH = 258, // LoongArch + // OHOS_LOCAL + EM_XVM = 265, // OS kernel xvm virtual machine }; // Object file classes. @@ -394,6 +396,13 @@ enum { #include "ELFRelocs/PowerPC.def" }; +// OHOS_LOCAL begin +// ELF Relocation types for XVM +enum { +#include "ELFRelocs/XVM.def" +}; +// OHOS_LOCAL end + // Specific e_flags for PPC64 enum { // e_flags bits specifying ABI: diff --git a/llvm/include/llvm/BinaryFormat/ELFRelocs/XVM.def b/llvm/include/llvm/BinaryFormat/ELFRelocs/XVM.def new file mode 100644 index 0000000000000000000000000000000000000000..1c32c326dfe82efb466c9bc312d217b1e1ee371b --- /dev/null +++ b/llvm/include/llvm/BinaryFormat/ELFRelocs/XVM.def @@ -0,0 +1,11 @@ +#ifndef ELF_RELOC +#error "ELF_RELOC must be defined" +#endif + +// No relocation +ELF_RELOC(R_XVM_NONE, 0) +ELF_RELOC(R_XVM_64_64, 1) +ELF_RELOC(R_XVM_64_ABS64, 2) +ELF_RELOC(R_XVM_64_ABS32, 3) +ELF_RELOC(R_XVM_64_NODYLD32, 4) +ELF_RELOC(R_XVM_64_32, 10) diff --git a/llvm/include/llvm/Object/ELFObjectFile.h b/llvm/include/llvm/Object/ELFObjectFile.h index ed2f70b0da251e6c1a0ea451491240827dfeb860..f50e34e1d6a5001b7a2e920895b1ff135a10fdc9 100644 --- a/llvm/include/llvm/Object/ELFObjectFile.h +++ b/llvm/include/llvm/Object/ELFObjectFile.h @@ -1242,6 +1242,10 @@ StringRef ELFObjectFile::getFileFormatName() const { return "elf64-ve"; case ELF::EM_LOONGARCH: return "elf64-loongarch"; + // OHOS_LOCAL begin + case ELF::EM_XVM: + return "elf64-xvm"; + // OHOS_LOCAL end default: return "elf64-unknown"; } @@ -1322,6 +1326,11 @@ template Triple::ArchType ELFObjectFile::getArch() const { case ELF::EM_BPF: return IsLittleEndian ? Triple::bpfel : Triple::bpfeb; + // OHOS_LOCAL begin + case ELF::EM_XVM: + return Triple::xvm; + // OHOS_LOCAL end + case ELF::EM_VE: return Triple::ve; case ELF::EM_CSKY: diff --git a/llvm/lib/Object/ELF.cpp b/llvm/lib/Object/ELF.cpp index 0d5aa91c1348eb9335de5ae7aaa4d4ede5b5eef3..3139ca3c6dcbb29022fb5b7b5eeb40bf1d468c30 100644 --- a/llvm/lib/Object/ELF.cpp +++ b/llvm/lib/Object/ELF.cpp @@ -145,6 +145,13 @@ StringRef llvm::object::getELFRelocationTypeName(uint32_t Machine, break; } break; + // OHOS_LOCAL begin + case ELF::EM_XVM: + switch (Type) { +#include "llvm/BinaryFormat/ELFRelocs/XVM.def" + } + break; + // OHOS_LOCAL end case ELF::EM_MSP430: switch (Type) { #include "llvm/BinaryFormat/ELFRelocs/MSP430.def" diff --git a/llvm/lib/Support/Triple.cpp b/llvm/lib/Support/Triple.cpp index d163bcff0d3fced5e041cc596907fbd68c7748a4..8acfe4c47ce732745857d48280ea3094afef1187 100644 --- a/llvm/lib/Support/Triple.cpp +++ b/llvm/lib/Support/Triple.cpp @@ -83,6 +83,8 @@ StringRef Triple::getArchTypeName(ArchType Kind) { case x86: return "i386"; case x86_64: return "x86_64"; case xcore: return "xcore"; + // OHOS_LOCAL + case xvm: return "xvm"; } llvm_unreachable("Invalid ArchType!"); @@ -137,6 +139,9 @@ StringRef Triple::getArchTypePrefix(ArchType Kind) { case xcore: return "xcore"; + // OHOS_LOCAL + case xvm: return "xvm"; + // NVPTX intrinsics are namespaced under nvvm. case nvptx: return "nvvm"; case nvptx64: return "nvvm"; @@ -349,6 +354,8 @@ Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) { .Case("i386", x86) .Case("x86-64", x86_64) .Case("xcore", xcore) + // OHOS_LOCAL + .Case("xvm", xvm) .Case("nvptx", nvptx) .Case("nvptx64", nvptx64) .Case("le32", le32) @@ -487,6 +494,8 @@ static Triple::ArchType parseArch(StringRef ArchName) { .Case("tce", Triple::tce) .Case("tcele", Triple::tcele) .Case("xcore", Triple::xcore) + // OHOS_LOCAL + .Case("xvm", Triple::xvm) .Case("nvptx", Triple::nvptx) .Case("nvptx64", Triple::nvptx64) .Case("le32", Triple::le32) @@ -839,6 +848,8 @@ static Triple::ObjectFormatType getDefaultFormat(const Triple &T) { case Triple::thumbeb: case Triple::ve: case Triple::xcore: + // OHOS_LOCAL + case Triple::xvm: return Triple::ELF; case Triple::ppc64: @@ -1440,6 +1451,8 @@ static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) { case llvm::Triple::ve: case llvm::Triple::wasm64: case llvm::Triple::x86_64: + // OHOS_LOCAL + case llvm::Triple::xvm: return 64; } llvm_unreachable("Invalid architecture value"); @@ -1468,6 +1481,8 @@ Triple Triple::get32BitArchVariant() const { case Triple::msp430: case Triple::systemz: case Triple::ve: + // OHOS_LOCAL + case Triple::xvm: T.setArch(UnknownArch); break; @@ -1581,6 +1596,8 @@ Triple Triple::get64BitArchVariant() const { case Triple::ve: case Triple::wasm64: case Triple::x86_64: + // OHOS_LOCAL + case Triple::xvm: // Already 64-bit. break; @@ -1764,6 +1781,8 @@ bool Triple::isLittleEndian() const { case Triple::x86: case Triple::x86_64: case Triple::xcore: + // OHOS_LOCAL + case Triple::xvm: return true; default: return false; diff --git a/llvm/lib/Target/XVM/CMakeLists.txt b/llvm/lib/Target/XVM/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..0f5ef89440fd00a1890c299e43d389c4e462675f --- /dev/null +++ b/llvm/lib/Target/XVM/CMakeLists.txt @@ -0,0 +1,58 @@ + +if(LLVM_BUILD_LLVM_DYLIB) + ADD_DEFINITIONS("-DXVM_DYLIB_MODE=1") +endif() + +add_llvm_component_group(XVM) + +set(LLVM_TARGET_DEFINITIONS XVM.td) + +tablegen(LLVM XVMGenAsmWriter.inc -gen-asm-writer) +tablegen(LLVM XVMGenCallingConv.inc -gen-callingconv) +tablegen(LLVM XVMGenDAGISel.inc -gen-dag-isel) +tablegen(LLVM XVMGenInstrInfo.inc -gen-instr-info) +tablegen(LLVM XVMGenMCCodeEmitter.inc -gen-emitter) +tablegen(LLVM XVMGenRegisterInfo.inc -gen-register-info) +tablegen(LLVM XVMGenSubtargetInfo.inc -gen-subtarget) + +add_public_tablegen_target(XVMCommonTableGen) + +add_llvm_target(XVMCodeGen + XVMAsmPrinter.cpp + XVMFrameLowering.cpp + XVMInstrInfo.cpp + XVMISelDAGToDAG.cpp + XVMISelLowering.cpp + XVMRegisterInfo.cpp + XVMSubtarget.cpp + XVMTargetMachine.cpp + XVMMCInstLower.cpp + XVMCFGSort.cpp + XVMSortRegion.cpp + XVMCFGStackify.cpp + XVMCFGStructure.cpp + XVMExpandPseudoInsts.cpp + XVMSelectionDAGInfo.cpp + XVMUpdateRefInstrForMI.cpp + + LINK_COMPONENTS + Analysis + AsmPrinter + CodeGen + Core + MC + XVMDesc + XVMInfo + IPO + Scalar + SelectionDAG + Support + Target + TransformUtils + + ADD_TO_COMPONENT + XVM + ) + +add_subdirectory(TargetInfo) +add_subdirectory(MCTargetDesc) diff --git a/llvm/lib/Target/XVM/MCTargetDesc/CMakeLists.txt b/llvm/lib/Target/XVM/MCTargetDesc/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..04738c3f0a8cb98011dc86c9ed5225ba3d29d07c --- /dev/null +++ b/llvm/lib/Target/XVM/MCTargetDesc/CMakeLists.txt @@ -0,0 +1,18 @@ + +if(LLVM_BUILD_LLVM_DYLIB) + ADD_DEFINITIONS("-DXVM_DYLIB_MODE=1") +endif() + +add_llvm_component_library(LLVMXVMDesc + XVMMCTargetDesc.cpp + XVMInstPrinter.cpp + XVMTargetStreamer.cpp + + LINK_COMPONENTS + MC + XVMInfo + Support + + ADD_TO_COMPONENT + XVM + ) diff --git a/llvm/lib/Target/XVM/MCTargetDesc/XVMInstPrinter.cpp b/llvm/lib/Target/XVM/MCTargetDesc/XVMInstPrinter.cpp new file mode 100644 index 0000000000000000000000000000000000000000..cf1caaffbc811244a5088eeb90cebe8b5bf0bfcf --- /dev/null +++ b/llvm/lib/Target/XVM/MCTargetDesc/XVMInstPrinter.cpp @@ -0,0 +1,15 @@ +//===-- XVMInstPrinter.cpp - Convert XVM MCInst to asm syntax -------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This class prints an XVM MCInst to a .s file. +// +//===----------------------------------------------------------------------===// +#ifdef XVM_DYLIB_MODE +// Insert the XVM backend code here + +#endif diff --git a/llvm/lib/Target/XVM/MCTargetDesc/XVMInstPrinter.h b/llvm/lib/Target/XVM/MCTargetDesc/XVMInstPrinter.h new file mode 100644 index 0000000000000000000000000000000000000000..33e8860810f0a33d5dfd0ba1147d7d4d8cf4f326 --- /dev/null +++ b/llvm/lib/Target/XVM/MCTargetDesc/XVMInstPrinter.h @@ -0,0 +1,46 @@ +//===-- XVMInstPrinter.h - Convert XVM MCInst to asm syntax -------*- C++ -*--// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This class prints a XVM MCInst to a .s file. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_XVM_MCTARGETDESC_XVMINSTPRINTER_H +#define LLVM_LIB_TARGET_XVM_MCTARGETDESC_XVMINSTPRINTER_H + +#include "llvm/MC/MCInstPrinter.h" + +namespace llvm { +class XVMInstPrinter : public MCInstPrinter { +public: + XVMInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII, + const MCRegisterInfo &MRI) + : MCInstPrinter(MAI, MII, MRI) {} + + void printInst(const MCInst *MI, uint64_t Address, StringRef Annot, + const MCSubtargetInfo &STI, raw_ostream &O) override; + void printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O, + const char *Modifier = nullptr); + void printMemOperand(const MCInst *MI, int OpNo, raw_ostream &O, + const char *Modifier = nullptr); + void printImm64Operand(const MCInst *MI, unsigned OpNo, raw_ostream &O); + void printBrTargetOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O); + + void printCallInstructionImm(const MCInst *MI, raw_ostream &O); + void printCallInstructionReg(const MCInst *MI, raw_ostream &O); + void printMovWithFuncID(const MCInst *MI, raw_ostream &O); + void printDataRefWithGlobalID(const MCInst *MI, raw_ostream &O); + + // Autogenerated by tblgen. + std::pair getMnemonic(const MCInst *MI) override; + void printInstruction(const MCInst *MI, uint64_t Address, raw_ostream &O); + static const char *getRegisterName(unsigned RegNo); +}; +} + +#endif diff --git a/llvm/lib/Target/XVM/MCTargetDesc/XVMMCAsmInfo.h b/llvm/lib/Target/XVM/MCTargetDesc/XVMMCAsmInfo.h new file mode 100644 index 0000000000000000000000000000000000000000..315124b5ba44310cc7ab0d7d0aae0a1709588d7d --- /dev/null +++ b/llvm/lib/Target/XVM/MCTargetDesc/XVMMCAsmInfo.h @@ -0,0 +1,55 @@ +//===-- XVMMCAsmInfo.h - XVM asm properties -------------------*- C++ -*--====// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file contains the declaration of the XVMMCAsmInfo class. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_XVM_MCTARGETDESC_XVMMCASMINFO_H +#define LLVM_LIB_TARGET_XVM_MCTARGETDESC_XVMMCASMINFO_H + +#include "llvm/ADT/Triple.h" +#include "llvm/MC/MCAsmInfo.h" + +namespace llvm { + +class XVMMCAsmInfo : public MCAsmInfo { +public: + explicit XVMMCAsmInfo(const Triple &TT, const MCTargetOptions &Options) { + + PrivateGlobalPrefix = ".L"; + WeakRefDirective = "\t.weak\t"; + CommentString = ";;"; + + UsesELFSectionDirectiveForBSS = true; + HasSingleParameterDotFile = false; + HasDotTypeDotSizeDirective = false; + + SupportsDebugInformation = true; + ExceptionsType = ExceptionHandling::DwarfCFI; + MinInstAlignment = 4; + CommentString = ";;"; + + // the default is 4 and it only affects dwarf elf output + // so if not set correctly, the dwarf data will be + // messed up in random places by 4 bytes. .debug_line + // section will be parsable, but with odd offsets and + // line numbers, etc. + CodePointerSize = 8; + } + + void setDwarfUsesRelocationsAcrossSections(bool enable) { + DwarfUsesRelocationsAcrossSections = enable; + } + bool shouldOmitSectionDirective(StringRef SectionName) const override { + return true; + } +}; +} + +#endif diff --git a/llvm/lib/Target/XVM/MCTargetDesc/XVMMCTargetDesc.cpp b/llvm/lib/Target/XVM/MCTargetDesc/XVMMCTargetDesc.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2415d5f19aeec69378182f86b4eb78717e1cdadf --- /dev/null +++ b/llvm/lib/Target/XVM/MCTargetDesc/XVMMCTargetDesc.cpp @@ -0,0 +1,23 @@ +//===-- XVMMCTargetDesc.cpp - XVM Target Descriptions ---------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file provides XVM specific target descriptions. +// +//===----------------------------------------------------------------------===// +#ifdef XVM_DYLIB_MODE +// Insert the XVM backend code here +#include "llvm/Support/Compiler.h" +extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeXVMTargetMC() { +} + +#else + +#include "../XVMDylibHandler.h" +LLVM_INIT_XVM_COMP(TargetMC) + +#endif diff --git a/llvm/lib/Target/XVM/MCTargetDesc/XVMMCTargetDesc.h b/llvm/lib/Target/XVM/MCTargetDesc/XVMMCTargetDesc.h new file mode 100644 index 0000000000000000000000000000000000000000..cd9b2f2ef30776851440dc0182a18c2c1c4f9ca7 --- /dev/null +++ b/llvm/lib/Target/XVM/MCTargetDesc/XVMMCTargetDesc.h @@ -0,0 +1,48 @@ +//===-- XVMMCTargetDesc.h - XVM Target Descriptions -------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file provides XVM specific target descriptions. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_XVM_MCTARGETDESC_XVMMCTARGETDESC_H +#define LLVM_LIB_TARGET_XVM_MCTARGETDESC_XVMMCTARGETDESC_H + +#include "llvm/Config/config.h" +#include "llvm/MC/MCContext.h" +#include "llvm/Support/DataTypes.h" +#include "llvm/CodeGen/TargetInstrInfo.h" + +#include + +namespace llvm { +class MCContext; +class MCInstrInfo; +class MCRegisterInfo; +class MCSubtargetInfo; +class MCTargetOptions; +class Target; + +} + +// Defines symbolic names for XVM registers. This defines a mapping from +// register name to register number. +// +#define GET_REGINFO_ENUM +#include "XVMGenRegisterInfo.inc" + +// Defines symbolic names for the XVM instructions. +// +#define GET_INSTRINFO_ENUM +#define GET_INSTRINFO_MC_HELPER_DECLS +#include "XVMGenInstrInfo.inc" + +#define GET_SUBTARGETINFO_ENUM +#include "XVMGenSubtargetInfo.inc" + +#endif diff --git a/llvm/lib/Target/XVM/MCTargetDesc/XVMTargetStreamer.cpp b/llvm/lib/Target/XVM/MCTargetDesc/XVMTargetStreamer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..872e3efb4fd913a79ca662b9573a57bc4fb56a56 --- /dev/null +++ b/llvm/lib/Target/XVM/MCTargetDesc/XVMTargetStreamer.cpp @@ -0,0 +1,15 @@ +//=====- XVMTargetStreamer.cpp - XVMTargetStreamer class ------------=====// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file implements the XVMTargetStreamer class. +// +//===----------------------------------------------------------------------===// +#ifdef XVM_DYLIB_MODE +// Insert the XVM backend code here + +#endif diff --git a/llvm/lib/Target/XVM/MCTargetDesc/XVMTargetStreamer.h b/llvm/lib/Target/XVM/MCTargetDesc/XVMTargetStreamer.h new file mode 100644 index 0000000000000000000000000000000000000000..1fdca9958f25c00f32ccf58f498001c50c5ae694 --- /dev/null +++ b/llvm/lib/Target/XVM/MCTargetDesc/XVMTargetStreamer.h @@ -0,0 +1,30 @@ +//=====-- XVMTargetStreamer.h - XVM Target Streamer ------*- C++ -*--=====// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_XVM_MCTARGETDESC_XVMTARGETSTREAMER_H +#define LLVM_LIB_TARGET_XVM_MCTARGETDESC_XVMTARGETSTREAMER_H + +#include "llvm/MC/MCStreamer.h" + +namespace llvm { +class MCSection; + +/// Implments XVM-specific streamer. +class XVMTargetStreamer : public MCTargetStreamer { + +public: + XVMTargetStreamer(MCStreamer &S); + ~XVMTargetStreamer() override; + + void changeSection(const MCSection *CurSection, MCSection *Section, + const MCExpr *SubSection, raw_ostream &OS) override; +}; + +} // end namespace llvm + +#endif diff --git a/llvm/lib/Target/XVM/TargetInfo/CMakeLists.txt b/llvm/lib/Target/XVM/TargetInfo/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..aad77bae6d276a1a2145a840907dd4001f08a4e2 --- /dev/null +++ b/llvm/lib/Target/XVM/TargetInfo/CMakeLists.txt @@ -0,0 +1,15 @@ + +if(LLVM_BUILD_LLVM_DYLIB) +ADD_DEFINITIONS("-DXVM_DYLIB_MODE=1") +endif() + +add_llvm_component_library(LLVMXVMInfo + XVMTargetInfo.cpp + + LINK_COMPONENTS + MC + Support + + ADD_TO_COMPONENT + XVM + ) diff --git a/llvm/lib/Target/XVM/TargetInfo/XVMTargetInfo.cpp b/llvm/lib/Target/XVM/TargetInfo/XVMTargetInfo.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0af0638eeab10ad5c67f09c959651db36f9f65dd --- /dev/null +++ b/llvm/lib/Target/XVM/TargetInfo/XVMTargetInfo.cpp @@ -0,0 +1,22 @@ +//===-- XVMTargetInfo.cpp - XVM Target Implementation ---------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +#ifdef XVM_DYLIB_MODE +// Insert the XVM backend code here +#include "llvm/Support/Compiler.h" +extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeXVMTargetInfo() { +} + +#else + +#include "../XVMDylibHandler.h" +llvm::sys::SmartMutex mutexLoadDylib; +std::map mapTargetNameHandler; + +LLVM_INIT_XVM_COMP(TargetInfo) + +#endif diff --git a/llvm/lib/Target/XVM/TargetInfo/XVMTargetInfo.h b/llvm/lib/Target/XVM/TargetInfo/XVMTargetInfo.h new file mode 100644 index 0000000000000000000000000000000000000000..c1fb33bc46b6040f3edf33e7b4e710e08a7a2cf5 --- /dev/null +++ b/llvm/lib/Target/XVM/TargetInfo/XVMTargetInfo.h @@ -0,0 +1,21 @@ +//===-- XVMTargetInfo.h - XVM Target Implementation -------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_XVM_TARGETINFO_XVMTARGETINFO_H +#define LLVM_LIB_TARGET_XVM_TARGETINFO_XVMTARGETINFO_H + +namespace llvm { + +class Target; + +Target &getTheXVMTarget(); +Target &getTheXVMleTarget(); + +} // namespace llvm + +#endif // LLVM_LIB_TARGET_XVM_TARGETINFO_XVMTARGETINFO_H diff --git a/llvm/lib/Target/XVM/XVM.h b/llvm/lib/Target/XVM/XVM.h new file mode 100644 index 0000000000000000000000000000000000000000..83077088c596cc3a8d3c685f3d796feb6369632d --- /dev/null +++ b/llvm/lib/Target/XVM/XVM.h @@ -0,0 +1,36 @@ +//===-- XVM.h - Top-level interface for XVM representation ------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_XVM_XVM_H +#define LLVM_LIB_TARGET_XVM_XVM_H + +#include "llvm/CodeGen/TargetInstrInfo.h" +#include "MCTargetDesc/XVMMCTargetDesc.h" +#include "llvm/IR/PassManager.h" +#include "llvm/Pass.h" +#include "llvm/PassRegistry.h" +#include "llvm/Target/TargetMachine.h" + +namespace llvm { +class XVMTargetMachine; + +FunctionPass *createXVMISelDag(XVMTargetMachine &TM); +FunctionPass *createXVMCFGSort(); +FunctionPass *createXVMCFGStackify(); +FunctionPass *createXVMCFGStructure(); +FunctionPass *createXVMExpandPseudoPass(); +FunctionPass *createXVMUpdateRefInstrForMIPass(); + +void initializeXVMCFGSortPass(PassRegistry &); +void initializeXVMCFGStackifyPass(PassRegistry&); +void initializeXVMCFGStructurePass(PassRegistry&); +void initializeXVMExpandPseudoPass(PassRegistry&); +void initializeXVMUpdateRefInstrForMIPass(PassRegistry&); +} // namespace llvm + +#endif diff --git a/llvm/lib/Target/XVM/XVM.td b/llvm/lib/Target/XVM/XVM.td new file mode 100644 index 0000000000000000000000000000000000000000..b628c087985c1781c92c7d4da31a71a20bf803c3 --- /dev/null +++ b/llvm/lib/Target/XVM/XVM.td @@ -0,0 +1,48 @@ +//===-- XVM.td - Describe the XVM Target Machine -----------*- tablegen -*-===// + +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +include "llvm/Target/Target.td" + +include "XVMRegisterInfo.td" +include "XVMCallingConv.td" +include "XVMInstrInfo.td" + +class Proc Features> + : Processor; + +def : Proc<"generic", []>; + + +def XVMInstrInfo : InstrInfo; + +def XVMInstPrinter : AsmWriter { + string AsmWriterClassName = "InstPrinter"; + bit isMCAsmWriter = 1; +} + +def Common : SubtargetFeature<"common", "isCommon", + "true", "common 64-bit subtarget">; + +def XVMAsmParser : AsmParser { + bit HasMnemonicFirst = 0; +} + +def XVMAsmParserVariant : AsmParserVariant { + int Variant = 0; + string Name = "XVM"; + string BreakCharacters = "."; + string TokenizingCharacters = "#()[]=:.<>!+*"; +} + +def XVM : Target { + let InstructionSet = XVMInstrInfo; + let AssemblyWriters = [XVMInstPrinter]; + let AssemblyParsers = [XVMAsmParser]; + let AssemblyParserVariants = [XVMAsmParserVariant]; +} diff --git a/llvm/lib/Target/XVM/XVMAsmPrinter.cpp b/llvm/lib/Target/XVM/XVMAsmPrinter.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4632e3e1eace4172cba3948d619a92f1c9cb1888 --- /dev/null +++ b/llvm/lib/Target/XVM/XVMAsmPrinter.cpp @@ -0,0 +1,24 @@ +//===-- XVMAsmPrinter.cpp - XVM LLVM assembly writer ----------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file contains a printer that converts from our internal representation +// of machine-dependent LLVM code to the XVM assembly language. +// +//===----------------------------------------------------------------------===// +#ifdef XVM_DYLIB_MODE +// Insert the XVM backend code here +#include "llvm/Support/Compiler.h" +extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeXVMAsmPrinter() { +} + +#else + +#include "XVMDylibHandler.h" +LLVM_INIT_XVM_COMP(AsmPrinter) + +#endif diff --git a/llvm/lib/Target/XVM/XVMCFGSort.cpp b/llvm/lib/Target/XVM/XVMCFGSort.cpp new file mode 100644 index 0000000000000000000000000000000000000000..69f8ba27a8590056e7f1152028fe6e78ea6e7cf1 --- /dev/null +++ b/llvm/lib/Target/XVM/XVMCFGSort.cpp @@ -0,0 +1,21 @@ +//===-- XVMCFGSort.cpp - CFG Sorting ------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// This file implements a CFG sorting pass. +/// +/// This pass reorders the blocks in a function to put them into topological +/// order, ignoring loop backedges, and without any loop or exception being +/// interrupted by a block not dominated by the its header, with special care +/// to keep the order as similar as possible to the original order. +/// +////===----------------------------------------------------------------------===// +#ifdef XVM_DYLIB_MODE +// Insert the XVM backend code here + +#endif \ No newline at end of file diff --git a/llvm/lib/Target/XVM/XVMCFGStackify.cpp b/llvm/lib/Target/XVM/XVMCFGStackify.cpp new file mode 100644 index 0000000000000000000000000000000000000000..38b63c09a5e1fe3a1ee84bbdb60ab4536b14369a --- /dev/null +++ b/llvm/lib/Target/XVM/XVMCFGStackify.cpp @@ -0,0 +1,26 @@ +//===-- XVMCFGStackify.cpp - CFG Stackification -------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// This file implements a CFG stacking pass. +/// +/// This pass inserts BLOCK, LOOP, and TRY markers to mark the start of scopes, +/// since scope boundaries serve as the labels for XVM's control +/// transfers. +/// +/// This is sufficient to convert arbitrary CFGs into a form that works on +/// XVM, provided that all loops are single-entry. +/// +/// In case we use exceptions, this pass also fixes mismatches in unwind +/// destinations created during transforming CFG into xvm structured format. +/// +//===----------------------------------------------------------------------===// +#ifdef XVM_DYLIB_MODE +// Insert the XVM backend code here + +#endif diff --git a/llvm/lib/Target/XVM/XVMCFGStructure.cpp b/llvm/lib/Target/XVM/XVMCFGStructure.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9427a2f4b6b7f8a4c06f8fc54319d1e556c3f159 --- /dev/null +++ b/llvm/lib/Target/XVM/XVMCFGStructure.cpp @@ -0,0 +1,4 @@ +#ifdef XVM_DYLIB_MODE +// Insert the XVM backend code here + +#endif diff --git a/llvm/lib/Target/XVM/XVMCallingConv.td b/llvm/lib/Target/XVM/XVMCallingConv.td new file mode 100644 index 0000000000000000000000000000000000000000..c4ae32d204718dcbe2feafd3d9329f3e67a0170e --- /dev/null +++ b/llvm/lib/Target/XVM/XVMCallingConv.td @@ -0,0 +1,35 @@ +//===-- XVMCallingConv.td - Calling Conventions XVM --------*- tablegen -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This describes the calling conventions for the XVM architecture. +// +//===----------------------------------------------------------------------===// + +// XVM 64-bit C return-value convention. +def RetCC_XVM64 : CallingConv<[ + CCIfType<[i64], CCAssignToReg<[R0]>> + ]>; + +// XVM 64-bit C Calling convention. +def CC_XVM64 : CallingConv<[ + CCIfInReg>>>>, + + // Return value Register for Structs + CCIfSRet>>, + + // Promote i8/i16/i32 args to i64 + CCIfType<[ i8, i16, i32 ], CCPromoteToType>, + + // All arguments get passed in integer registers if there is space. + CCIfType<[i64], CCAssignToReg<[R0, R1, R2, R3, R4, R5 ]>>, + + // Could be assigned to the stack in 8-byte aligned units, but unsupported + CCAssignToStack<8, 8> +]>; + +def CSR : CalleeSavedRegs<(add R12, R13, R14, R15, R16, R17)>; diff --git a/llvm/lib/Target/XVM/XVMDylibHandler.h b/llvm/lib/Target/XVM/XVMDylibHandler.h new file mode 100644 index 0000000000000000000000000000000000000000..b097450f1e077f0613d07bed8159d117ceeb18de --- /dev/null +++ b/llvm/lib/Target/XVM/XVMDylibHandler.h @@ -0,0 +1,49 @@ + +#ifndef __XVM_DYLIB_HANDLER__H +#define __XVM_DYLIB_HANDLER__H + +#include "llvm/Support/Mutex.h" +#include +#include +#include +using namespace std; + +extern llvm::sys::SmartMutex mutexLoadDylib; +extern std::map mapTargetNameHandler; + +#define LOAD_XVM_DYLIB \ + static void * \ + LoadDylibTarget() { \ + llvm::sys::SmartScopedLock lock(mutexLoadDylib); \ + std::map::iterator itr = mapTargetNameHandler.find("XVM"); \ + void *Handler; \ + const char * targetDyLibName = "LLVMXVMTarget.so"; \ + if (itr == mapTargetNameHandler.end()) { \ + Handler = dlopen(targetDyLibName, RTLD_LAZY | RTLD_NOLOAD); \ + if (!Handler) { \ + Handler = dlopen(targetDyLibName, RTLD_LAZY); \ + } \ + if (Handler) { \ + mapTargetNameHandler[targetDyLibName] = Handler; \ + } \ + } else { \ + Handler = mapTargetNameHandler[targetDyLibName]; \ + } \ + return Handler; \ + } + +#define LLVM_INIT_XVM_COMP(Component) \ + LOAD_XVM_DYLIB \ + extern "C" LLVM_EXTERNAL_VISIBILITY \ + void LLVMInitializeXVM##Component(void) { \ + void *Handler = LoadDylibTarget(); \ + if (!Handler) \ + return; \ + void (*FuncPtr)(void) = (void (*)())(dlsym(Handler, "LLVMInitializeXVM" #Component "CalledInDylib")); \ + if (!FuncPtr) { \ + return; \ + } \ + FuncPtr(); \ + } + +#endif // __XVM_DYLIB_HANDLER__H diff --git a/llvm/lib/Target/XVM/XVMExpandPseudoInsts.cpp b/llvm/lib/Target/XVM/XVMExpandPseudoInsts.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9427a2f4b6b7f8a4c06f8fc54319d1e556c3f159 --- /dev/null +++ b/llvm/lib/Target/XVM/XVMExpandPseudoInsts.cpp @@ -0,0 +1,4 @@ +#ifdef XVM_DYLIB_MODE +// Insert the XVM backend code here + +#endif diff --git a/llvm/lib/Target/XVM/XVMFrameLowering.cpp b/llvm/lib/Target/XVM/XVMFrameLowering.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e85115bef43f24d35d3628583fe24ec66a0afff2 --- /dev/null +++ b/llvm/lib/Target/XVM/XVMFrameLowering.cpp @@ -0,0 +1,15 @@ +//===-- XVMFrameLowering.cpp - XVM Frame Information ----------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file contains the XVM implementation of TargetFrameLowering class. +// +//===----------------------------------------------------------------------===// +#ifdef XVM_DYLIB_MODE +// Insert the XVM backend code here + +#endif diff --git a/llvm/lib/Target/XVM/XVMFrameLowering.h b/llvm/lib/Target/XVM/XVMFrameLowering.h new file mode 100644 index 0000000000000000000000000000000000000000..fe1a249371348cbee4fec2d82f72648525655c63 --- /dev/null +++ b/llvm/lib/Target/XVM/XVMFrameLowering.h @@ -0,0 +1,48 @@ +//===-- XVMFrameLowering.h - Define frame lowering for XVM -----*- C++ -*--===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This class implements XVM-specific bits of TargetFrameLowering class. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_XVM_XVMFRAMELOWERING_H +#define LLVM_LIB_TARGET_XVM_XVMFRAMELOWERING_H + +#include "llvm/CodeGen/TargetFrameLowering.h" + +namespace llvm { +class XVMSubtarget; + +class XVMFrameLowering : public TargetFrameLowering { +public: + explicit XVMFrameLowering(const XVMSubtarget &sti) + : TargetFrameLowering(TargetFrameLowering::StackGrowsDown, Align(8), 0) {} + + void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override; + void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override; + + bool hasFP(const MachineFunction &MF) const override; + void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, + RegScavenger *RS) const override; + + MachineBasicBlock::iterator + eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, + MachineBasicBlock::iterator MI) const override { + return MBB.erase(MI); + } + +private: + bool needsSP(const MachineFunction &MF) const; + bool needsSPForLocalFrame(const MachineFunction &MF) const; + static unsigned getSPReg(const MachineFunction &MF); + static unsigned getOpcSubRef(const MachineFunction &MF); + static unsigned getOpcAddRef(const MachineFunction &MF); + static unsigned getOpcGlobSet(const MachineFunction &MF); +}; +} +#endif diff --git a/llvm/lib/Target/XVM/XVMISelDAGToDAG.cpp b/llvm/lib/Target/XVM/XVMISelDAGToDAG.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ce5114d51d0fcaad2d4d04388e9e48bd2c11fea3 --- /dev/null +++ b/llvm/lib/Target/XVM/XVMISelDAGToDAG.cpp @@ -0,0 +1,16 @@ +//===-- XVMISelDAGToDAG.cpp - A dag to dag inst selector for XVM ----------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file defines a DAG pattern matching instruction selector for XVM, +// converting from a legalized dag to a XVM dag. +// +//===----------------------------------------------------------------------===// +#ifdef XVM_DYLIB_MODE +// Insert the XVM backend code here + +#endif diff --git a/llvm/lib/Target/XVM/XVMISelLowering.cpp b/llvm/lib/Target/XVM/XVMISelLowering.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c6c08fda9a30df31dda57b628a484469b3a79def --- /dev/null +++ b/llvm/lib/Target/XVM/XVMISelLowering.cpp @@ -0,0 +1,17 @@ +//===-- XVMISelLowering.cpp - XVM DAG Lowering Implementation ------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file defines the interfaces that XVM uses to lower LLVM code into a +// selection DAG. +// +//===----------------------------------------------------------------------===// + +#ifdef XVM_DYLIB_MODE +// Insert the XVM backend code here + +#endif diff --git a/llvm/lib/Target/XVM/XVMISelLowering.h b/llvm/lib/Target/XVM/XVMISelLowering.h new file mode 100644 index 0000000000000000000000000000000000000000..e631e358d27877e9db1319e63adc74099ed4ab7d --- /dev/null +++ b/llvm/lib/Target/XVM/XVMISelLowering.h @@ -0,0 +1,154 @@ +//===-- XVMISelLowering.h - XVM DAG Lowering Interface ----------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file defines the interfaces that XVM uses to lower LLVM code into a +// selection DAG. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_XVM_XVMISELLOWERING_H +#define LLVM_LIB_TARGET_XVM_XVMISELLOWERING_H + +#include "XVM.h" +#include "llvm/CodeGen/SelectionDAG.h" +#include "llvm/CodeGen/TargetLowering.h" + + +namespace llvm { +class XVMSubtarget; +namespace XVMISD { +enum NodeType : unsigned { + FIRST_NUMBER = ISD::BUILTIN_OP_END, + RET_FLAG, + CALL, + SELECT_CC, + BR_CC, + Wrapper, + MEMCPY, + BRCOND, + MEMSET, + MEMMOV +}; +} + +class XVMTargetLowering : public TargetLowering { +public: + explicit XVMTargetLowering(const TargetMachine &TM, const XVMSubtarget &STI); + + // Provide custom lowering hooks for some operations. + SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override; + + // This method returns the name of a target specific DAG node. + const char *getTargetNodeName(unsigned Opcode) const override; + + // This method decides whether folding a constant offset + // with the given GlobalAddress is legal. + bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override; + + XVMTargetLowering::ConstraintType + getConstraintType(StringRef Constraint) const override; + + std::pair + getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, + StringRef Constraint, MVT VT) const override; + + MachineBasicBlock * + EmitInstrWithCustomInserter(MachineInstr &MI, + MachineBasicBlock *MBB) const override; + + EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, + EVT VT) const override; + + MVT getScalarShiftAmountTy(const DataLayout &, EVT) const override; + +private: + const XVMSubtarget *Subtarget; + SDValue LowerBRCOND(SDValue Op, SelectionDAG &DAG) const; + SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const; + SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const; + SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const; + SDValue LowerVAARG(SDValue Op, SelectionDAG &DAG) const; + + MachineBasicBlock * EmitInstrWithCustomInserterSelectCC(MachineInstr &MI, + MachineBasicBlock *BB) const; + + // Lower the result values of a call, copying them out of physregs into vregs + SDValue LowerCallResult(SDValue Chain, SDValue InFlag, + CallingConv::ID CallConv, bool IsVarArg, + const SmallVectorImpl &Ins, + const SDLoc &DL, SelectionDAG &DAG, + SmallVectorImpl &InVals) const; + + // Maximum number of arguments to a call + static const unsigned MaxArgs; + + // Lower a call into CALLSEQ_START - XVMISD:CALL - CALLSEQ_END chain + SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI, + SmallVectorImpl &InVals) const override; + + // Lower incoming arguments, copy physregs into vregs + SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, + bool IsVarArg, + const SmallVectorImpl &Ins, + const SDLoc &DL, SelectionDAG &DAG, + SmallVectorImpl &InVals) const override; + + SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg, + const SmallVectorImpl &Outs, + const SmallVectorImpl &OutVals, const SDLoc &DL, + SelectionDAG &DAG) const override; + + void ReplaceNodeResults(SDNode *N, SmallVectorImpl &Results, + SelectionDAG &DAG) const override; + + EVT getOptimalMemOpType(const MemOp &Op, + const AttributeList &FuncAttributes) const override { + return Op.size() >= 8 ? MVT::i64 : MVT::i32; + } + + bool isIntDivCheap(EVT VT, AttributeList Attr) const override { return true; } + + bool shouldConvertConstantLoadToIntImm(const APInt &Imm, + Type *Ty) const override { + return true; + } + + // Prevent reducing load width during SelectionDag phase. + // Otherwise, we may transform the following + // ctx = ctx + reloc_offset + // ... (*(u32 *)ctx) & 0x8000... + // to + // ctx = ctx + reloc_offset + // ... (*(u8 *)(ctx + 1)) & 0x80 ... + // which will be rejected by the verifier. + bool shouldReduceLoadWidth(SDNode *Load, ISD::LoadExtType ExtTy, + EVT NewVT) const override { + return false; + } + + bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, + Type *Ty, unsigned AS, + Instruction *I = nullptr) const override; + + // isTruncateFree - Return true if it's free to truncate a value of + // type Ty1 to type Ty2. e.g. On XVM at alu32 mode, it's free to truncate + // a i64 value in register R1 to i32 by referencing its sub-register W1. + bool isTruncateFree(Type *Ty1, Type *Ty2) const override; + bool isTruncateFree(EVT VT1, EVT VT2) const override; + + // For 32bit ALU result zext to 64bit is free. + bool isZExtFree(Type *Ty1, Type *Ty2) const override; + bool isZExtFree(EVT VT1, EVT VT2) const override; + + unsigned EmitSubregExt(MachineInstr &MI, MachineBasicBlock *BB, unsigned Reg, + bool isSigned) const; + +}; +} + +#endif diff --git a/llvm/lib/Target/XVM/XVMInstrBulkMemory.td b/llvm/lib/Target/XVM/XVMInstrBulkMemory.td new file mode 100644 index 0000000000000000000000000000000000000000..1bf037fc348b6671f962c3d62d4b5949709c638e --- /dev/null +++ b/llvm/lib/Target/XVM/XVMInstrBulkMemory.td @@ -0,0 +1,78 @@ +// XVMInstrBulkMemory.td - bulk memory codegen support --*- tablegen -*- +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// +/// XVM bulk memory codegen constructs. +/// +//===----------------------------------------------------------------------===// + +def SDT_XVMMEMCPY_ri : SDTypeProfile<0, 3, []>; +def SDT_XVMMEMCPY_rr : SDTypeProfile<0, 3, []>; +def SDT_XVMMEMMOV_ri : SDTypeProfile<0, 3, []>; +def SDT_XVMMEMMOV_rr : SDTypeProfile<0, 3, []>; +def SDT_XVMMEMSET_ri : SDTypeProfile<0, 3, []>; +def SDT_XVMMEMSET_rr : SDTypeProfile<0, 3, []>; + +def XVMmemcpy_ri : SDNode<"XVMISD::MEMCPY", SDT_XVMMEMCPY_ri, + [SDNPHasChain, SDNPInGlue, SDNPOutGlue, + SDNPMayStore, SDNPMayLoad]>; +def XVMmemcpy_rr : SDNode<"XVMISD::MEMCPY", SDT_XVMMEMCPY_rr, + [SDNPHasChain, SDNPInGlue, SDNPOutGlue, + SDNPMayStore, SDNPMayLoad]>; + +def XVMmemmov_ri : SDNode<"XVMISD::MEMMOV", SDT_XVMMEMMOV_ri, + [SDNPHasChain, SDNPInGlue, SDNPOutGlue, + SDNPMayStore, SDNPMayLoad]>; +def XVMmemmov_rr : SDNode<"XVMISD::MEMMOV", SDT_XVMMEMMOV_rr, + [SDNPHasChain, SDNPInGlue, SDNPOutGlue, + SDNPMayStore, SDNPMayLoad]>; +def XVMmemset_ri : SDNode<"XVMISD::MEMSET", SDT_XVMMEMSET_ri, + [SDNPHasChain, SDNPInGlue, SDNPOutGlue, + SDNPMayStore, SDNPMayLoad]>; +def XVMmemset_rr : SDNode<"XVMISD::MEMSET", SDT_XVMMEMSET_rr, + [SDNPHasChain, SDNPInGlue, SDNPOutGlue, + SDNPMayStore, SDNPMayLoad]>; + + +let isCall=1, + hasDelaySlot=0, + Uses = [SP], + Defs = [R0, R1, R2, R3, R4, R5] in { + def MEMCPY_ri : Pseudo< + (outs), + (ins XVMGPR:$dst, XVMGPR:$src, i64imm:$len, variable_ops), + "#memcpy dst: $dst, src: $src, len: $len", + [(XVMmemcpy_ri XVMGPR:$dst, XVMGPR:$src, imm:$len)]>; + def MEMCPY_rr : Pseudo< + (outs), + (ins XVMGPR:$dst, XVMGPR:$src, XVMGPR:$len, variable_ops), + "#memcpy dst: $dst, src: $src, len: $len", + [(XVMmemcpy_rr XVMGPR:$dst, XVMGPR:$src, XVMGPR:$len)]>; + def MEMMOV_ri : Pseudo< + (outs), + (ins XVMGPR:$dst, XVMGPR:$src, i64imm:$len, variable_ops), + "#memmov dst: $dst, src: $src, len: $len", + [(XVMmemmov_ri XVMGPR:$dst, XVMGPR:$src, imm:$len)]>; + def MEMMOV_rr : Pseudo< + (outs), + (ins XVMGPR:$dst, XVMGPR:$src, XVMGPR:$len, variable_ops), + "#memmov dst: $dst, src: $src, len: $len", + [(XVMmemmov_rr XVMGPR:$dst, XVMGPR:$src, XVMGPR:$len)]>; + + def MEMSET_ri : Pseudo< + (outs), + (ins XVMGPR:$dst, XVMGPR:$src, i64imm:$len, variable_ops), + "#memset dst: $dst, src: $src, len: $len", + [(XVMmemset_ri XVMGPR:$dst, XVMGPR:$src, imm:$len)]>; + def MEMSET_rr : Pseudo< + (outs), + (ins XVMGPR:$dst, XVMGPR:$src, XVMGPR:$len, variable_ops), + "#memset dst: $dst, src: $src, len: $len", + [(XVMmemset_rr XVMGPR:$dst, XVMGPR:$src, XVMGPR:$len)]>; +} + + diff --git a/llvm/lib/Target/XVM/XVMInstrFormats.td b/llvm/lib/Target/XVM/XVMInstrFormats.td new file mode 100644 index 0000000000000000000000000000000000000000..a28ebdd293df4e8789a6aa09eddcf53e4633731b --- /dev/null +++ b/llvm/lib/Target/XVM/XVMInstrFormats.td @@ -0,0 +1,155 @@ +//===-- XVMInstrFormats.td - XVM Instruction Formats ---*- tablegen -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +class XVMInstr pattern, + InstrItinClass itin = NoItinerary> : Instruction { + field bits<32> Inst; + let Namespace = "XVM"; + let DecoderNamespace = "XVM"; + let Size = 4; + + bits<8> opcode; + let Inst{31-24} = opcode; + + dag OutOperandList = outs; + dag InOperandList = ins; + let AsmString = asmstr; + let Pattern = pattern; +} + +// Pseudo instructions +class Pseudo pattern> + : XVMInstr { + let Inst{31-0} = 0; + let isPseudo = 1; +} + +class ControFlowNoArgsopc, dag outs, dag ins, string asmstr, list pattern, + InstrItinClass itin = NoItinerary> + : XVMInstr { + let opcode = opc; + let Inst{23-0} = 0; +} + +// Addressing modes. +def ADDRri : ComplexPattern; +def FIri : ComplexPattern; + +// Address operands +def MEMri : Operand { + let PrintMethod = "printMemOperand"; + let EncoderMethod = "getMemoryOpValue"; + let DecoderMethod = "decodeMemoryOpValue"; + let MIOperandInfo = (ops XVMGPR, i16imm); +} + +class XVMWidthModifier val> { + bits<2> Value = val; +} + +def XVM_W : XVMWidthModifier<0x0>; +def XVM_H : XVMWidthModifier<0x1>; +def XVM_B : XVMWidthModifier<0x2>; +def XVM_D : XVMWidthModifier<0x3>; + +class LD_ST size, dag outs, dag ins, string asmstr, list pattern> + : XVMInstr; + +class STORE Pattern> + : LD_ST; + +class STOREi64 + : STORE; + +class LOAD Pattern> + : LD_ST; + +class LOADi64 + : LOAD; + +class ALU_rropc, string asmstr, list pattern> + : XVMInstr<(outs XVMGPR:$res), (ins XVMGPR:$src1, XVMGPR:$src2), ""#asmstr#" $res, $src1, $src2", pattern>; + +class ALU_riopc, string asmstr, list pattern> + : XVMInstr<(outs XVMGPR:$res), (ins XVMGPR:$src1, simm14:$src2), ""#asmstr#" $res, $src1, #$src2", pattern>; + +class ALU_ropc, string asmstr, list pattern> + : XVMInstr<(outs XVMGPR:$res), (ins XVMGPR:$src1), ""#asmstr#" $res, $src1", pattern>; + +class ALU_iopc, string asmstr, list pattern> + : XVMInstr<(outs XVMGPR:$res), (ins uimm16:$src1), ""#asmstr#" $res, #$src1", pattern>; + +class ALU_riiopc, string asmstr, list pattern> + : XVMInstr<(outs XVMGPR:$res), (ins XVMGPR:$src3, uimm16:$src1, uimm16:$src2), ""#asmstr#" $res, #$src1, #$src2", pattern>{ + let Constraints = "$res = $src3"; + } + +class TYPE_ALU_JMP Opc, + dag outs, dag ins, string asmstr, list pattern> + : XVMInstr { +} + +class BranchCC_rr + : XVMInstr<(outs), (ins bb_op:$dst, XVMGPR: $op1, XVMGPR: $op2), + "(if "#cccode#" $op1, $op2", []> { + let isBranch = 1; + let isTerminator = 1; + let hasCtrlDep = 1; +} + +class BranchCC_ris + : XVMInstr<(outs), (ins bb_op:$dst, XVMGPR: $op1, simm16: $op2), + "(if "#cccode#" $op1, #$op2", []> { + let isBranch = 1; + let isTerminator = 1; + let hasCtrlDep = 1; +} + +class BranchCC_riu + : XVMInstr<(outs), (ins bb_op:$dst, XVMGPR: $op1, uimm16: $op2), + "(if "#cccode#" $op1, #$op2", []> { + let isBranch = 1; + let isTerminator = 1; + let hasCtrlDep = 1; +} + +class CALL_imm + : TYPE_ALU_JMP { +} +class CALL_REG + : TYPE_ALU_JMP { +} + +class MOV_GLOBAL_IMM64 + : XVMInstr<(outs XVMGPR:$dst), + (ins u64imm:$imm), + ""#OpcodeStr#" $dst, ${imm}", + [(set XVMGPR:$dst, (i64 imm:$imm))]> { +} + +class Ref_rr + : XVMInstr<(outs XVMGPR:$res), (ins XVMGPR:$src1, XVMGPR:$src2), ""#asmstr#" $res, $src1, $src2", []> { +} + +class Ref_ri + : XVMInstr<(outs XVMGPR:$dst), (ins XVMGPR:$src1, simm14:$src2), ""#asmstr#" $dst, $src1, #$src2", []> { +} + +class StrRef_ri + : XVMInstr<(outs), (ins XVMGPR:$dst, XVMGPR:$src1, simm14:$src2), ""#asmstr#" $dst, $src1, #$src2", []> { +} \ No newline at end of file diff --git a/llvm/lib/Target/XVM/XVMInstrInfo.cpp b/llvm/lib/Target/XVM/XVMInstrInfo.cpp new file mode 100644 index 0000000000000000000000000000000000000000..aaeaca5c7e0369d706e6f063d998b013a1bf1721 --- /dev/null +++ b/llvm/lib/Target/XVM/XVMInstrInfo.cpp @@ -0,0 +1,16 @@ +//===-- XVMInstrInfo.cpp - XVM Instruction Information ----------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file contains the XVM implementation of the TargetInstrInfo class. +// +//===----------------------------------------------------------------------===// + +#ifdef XVM_DYLIB_MODE +// Insert the XVM backend code here + +#endif diff --git a/llvm/lib/Target/XVM/XVMInstrInfo.h b/llvm/lib/Target/XVM/XVMInstrInfo.h new file mode 100644 index 0000000000000000000000000000000000000000..6e51f396968763179ed5f4c3ffeb28961da835a7 --- /dev/null +++ b/llvm/lib/Target/XVM/XVMInstrInfo.h @@ -0,0 +1,86 @@ +//===-- XVMInstrInfo.h - XVM Instruction Information ------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file contains the XVM implementation of the TargetInstrInfo class. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_XVM_XVMINSTRINFO_H +#define LLVM_LIB_TARGET_XVM_XVMINSTRINFO_H + +#include "XVMRegisterInfo.h" +#include "llvm/CodeGen/TargetInstrInfo.h" + +#define GET_INSTRINFO_HEADER +#include "XVMGenInstrInfo.inc" + +namespace llvm { + +enum CondCode { + COND_EQ, + COND_NE, + COND_GE, + COND_UGE, + COND_LE, + COND_ULE, + COND_GT, + COND_UGT, + COND_LT, + COND_ULT, + COND_INVALID +}; + +class XVMInstrInfo : public XVMGenInstrInfo { + const XVMRegisterInfo RI; + +public: + XVMInstrInfo(); + + const XVMRegisterInfo &getRegisterInfo() const { return RI; } + + void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, + const DebugLoc &DL, MCRegister DestReg, MCRegister SrcReg, + bool KillSrc) const override; + + bool expandPostRAPseudo(MachineInstr &MI) const override; + + void storeRegToStackSlot(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MBBI, Register SrcReg, + bool isKill, int FrameIndex, + const TargetRegisterClass *RC, + const TargetRegisterInfo *TRI) const override; + + void loadRegFromStackSlot(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MBBI, Register DestReg, + int FrameIndex, const TargetRegisterClass *RC, + const TargetRegisterInfo *TRI) const override; + bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, + MachineBasicBlock *&FBB, + SmallVectorImpl &Cond, + bool AllowModify = false) const override; + + unsigned removeBranch(MachineBasicBlock &MBB, + int *BytesRemoved = nullptr) const override; + unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, + MachineBasicBlock *FBB, ArrayRef Cond, + const DebugLoc &DL, + int *BytesAdded = nullptr) const override; + + bool isCondBranch(const MachineInstr *MI) const; + bool isCondBranchProcessed(const MachineInstr *MI) const; + bool isUnCondBranch(const MachineInstr *MI) const; + void negateCondBranch(MachineInstr *MI) const; + +private: + void expandMEMCPY(MachineBasicBlock::iterator) const; + void expandMEMMOVE(MachineBasicBlock::iterator) const; + void expandMEMSET(MachineBasicBlock::iterator) const; +}; +} + +#endif diff --git a/llvm/lib/Target/XVM/XVMInstrInfo.td b/llvm/lib/Target/XVM/XVMInstrInfo.td new file mode 100644 index 0000000000000000000000000000000000000000..8bb08ae9ac94248ef062d633c8865733feebae72 --- /dev/null +++ b/llvm/lib/Target/XVM/XVMInstrInfo.td @@ -0,0 +1,461 @@ +//===-- XVMInstrInfo.td - Target Description for XVM Target -----------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file describes the XVM instructions in TableGen format. +// +//===----------------------------------------------------------------------===// + +//===---------------------------------------------------------------------===// +// XVM specific DAG Nodes +//===---------------------------------------------------------------------===// + +def SDTXVMBrCC_rr : SDTypeProfile<0, 4, []>; +def SDTXVMBrCC_ri : SDTypeProfile<0, 4, []>; +def SDTXVMSelectCC: SDTypeProfile<1, 5, [SDTCisSameAs<1, 2>, + SDTCisSameAs<0, 4>, + SDTCisSameAs<4, 5>]>; + +def XVMbrccrr : SDNode<"XVMISD::BR_CC", SDTXVMBrCC_rr, [SDNPHasChain]>; +def XVMbrccri : SDNode<"XVMISD::BR_CC", SDTXVMBrCC_ri, [SDNPHasChain]>; +def XVMretflag : SDNode<"XVMISD::RET_FLAG", SDTNone, + [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>; +def XVMselectcc : SDNode<"XVMISD::SELECT_CC", SDTXVMSelectCC, [SDNPInGlue]>; + +//===----------------------------------------------------------------------===// +// XVM specific Operands +//===----------------------------------------------------------------------===// + +def bb_op : Operand; + +def uimm6 : Operand, ImmLeaf= 0 && Imm < 64;}]> { + let MCOperandPredicate = [{ + int64_t Imm; + return MCOp.evaluateAsConstantImm(Imm) && isUInt<6>(Imm); + }]; +} +def uimm16 : Operand, ImmLeaf= 0 && Imm < 65536;}]> { + let MCOperandPredicate = [{ + int64_t Imm; + return MCOp.evaluateAsConstantImm(Imm) && isUInt<16>(Imm); + }]; +} +def simm16 : Operand, ImmLeaf= -32768 && Imm < 32768;}]> { + let MCOperandPredicate = [{ + int64_t Imm; + return MCOp.evaluateAsConstantImm(Imm) && isInt<16>(Imm); + }]; +} +def simm14 : Operand, ImmLeaf= -8192 && Imm < 8192;}]> { + let MCOperandPredicate = [{ + int64_t Imm; + return MCOp.evaluateAsConstantImm(Imm) && isInt<14>(Imm); + }]; +} +def uimm14 : Operand, ImmLeaf= 0 && Imm < 16384;}]> { + let MCOperandPredicate = [{ + int64_t Imm; + return MCOp.evaluateAsConstantImm(Imm) && isUInt<14>(Imm); + }]; +} + + +//===----------------------------------------------------------------------===// +// XVM Instruction +//===----------------------------------------------------------------------===// + +def i64immSExt32 : PatLeaf<(i64 imm), + [{return isInt<32>(N->getSExtValue()); }]>; +def u64imm : Operand; +def calltarget : Operand; +class XVMOpcode val> { + bits<8> Value = val; +} +def XVM_CALL_R : XVMOpcode<0b00000010>; +def XVM_CALL_I : XVMOpcode<0b00000011>; +def XVM_MOV_RR : XVMOpcode<0b00110000>; +def XVM_MOV_RI : XVMOpcode<0b00110001>; + +def SDT_XVMCallSeqStart : SDCallSeqStart<[SDTCisVT<0, iPTR>, + SDTCisVT<1, iPTR>]>; +def SDT_XVMCallSeqEnd : SDCallSeqEnd<[SDTCisVT<0, iPTR>, SDTCisVT<1, iPTR>]>; +def SDT_XVMCall : SDTypeProfile<0, -1, [SDTCisVT<0, iPTR>]>; +def XVMcall : SDNode<"XVMISD::CALL", SDT_XVMCall, + [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, SDNPVariadic]>; +def XVMcallseq_start : SDNode<"ISD::CALLSEQ_START", SDT_XVMCallSeqStart, + [SDNPHasChain, SDNPOutGlue]>; +def XVMcallseq_end : SDNode<"ISD::CALLSEQ_END", SDT_XVMCallSeqEnd, + [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>; + +include "XVMInstrFormats.td" + +//---------------------------------------------------------------- + +let isCall=1, + hasDelaySlot=0, + Uses = [SP], + Defs = [R0, R1, R2, R3, R4, R5] in { + def CALL_IMM : CALL_imm<"call">; + def CALL_REG : CALL_REG<"call">; +} +let Defs = [SP], Uses = [SP], isCodeGenOnly = 1 in { + def ADJCALLSTACKDOWN : Pseudo<(outs), (ins i64imm:$amt1, i64imm:$amt2), + "#ADJCALLSTACKDOWN $amt1 $amt2", + [(XVMcallseq_start timm:$amt1, timm:$amt2)]>; + def ADJCALLSTACKUP : Pseudo<(outs), (ins i64imm:$amt1, i64imm:$amt2), + "#ADJCALLSTACKUP $amt1 $amt2", + [(XVMcallseq_end timm:$amt1, timm:$amt2)]>; +} + +def : Pat<(XVMcall tglobaladdr:$dst), (CALL_IMM tglobaladdr:$dst)>; +def : Pat<(XVMcall texternalsym:$dst), (CALL_IMM texternalsym:$dst)>; +def : Pat<(XVMcall imm:$dst), (CALL_IMM imm:$dst)>; +def : Pat<(XVMcall XVMGPR:$dst), (CALL_REG XVMGPR:$dst)>; + +let usesCustomInserter = 1, isCodeGenOnly = 1 in { +def PseudoSelectCC_rr : Pseudo<(outs XVMGPR:$dst), + (ins XVMGPR:$lhs, XVMGPR:$rhs, i64imm:$imm, XVMGPR:$src, XVMGPR:$src2), + "; Select PSEUDO $dst = $lhs $imm $rhs ? $src : $src2", + [(set i64:$dst, + (XVMselectcc i64:$lhs, i64:$rhs, (i64 imm:$imm), i64:$src, i64:$src2))]>; + +def PseudoSelectCC_ri : Pseudo<(outs XVMGPR:$dst), + (ins XVMGPR:$lhs, i64imm:$rhs, i64imm:$imm, XVMGPR:$src, XVMGPR:$src2), + "# Select PSEUDO $dst = $lhs $imm $rhs ? $src : $src2", + [(set i64:$dst, + (XVMselectcc i64:$lhs, (i64immSExt32:$rhs), (i64 imm:$imm), i64:$src, i64:$src2))]>; +} + +let isReMaterializable = 1, isAsCheapAsAMove = 1 in { + def LD_global_imm64 : MOV_GLOBAL_IMM64<"mov">; + def PEI_PROLOGUE_ri : XVMInstr<(outs XVMGPR:$dst), + (ins XVMGPR:$src1, XVMGPR:$src2, u64imm:$imm), + "", + []>; + def PEI_EPILOGUE_ri : XVMInstr<(outs XVMGPR:$dst), + (ins XVMGPR:$src1, XVMGPR:$src2, u64imm:$imm), + "", + []>; + def SubRef_ri : XVMInstr<(outs XVMGPR:$dst), + (ins XVMGPR:$src, uimm14:$imm), + "subref $dst, $src, #$imm", + []>; + def AddRef_ri : XVMInstr<(outs XVMGPR:$dst), + (ins XVMGPR:$src, uimm14:$imm), + "addref $dst, $src, #$imm", + []>; + def OrRef_ri : XVMInstr<(outs XVMGPR:$dst), + (ins XVMGPR:$src, uimm14:$imm), + "orref $dst, $src, #$imm", + []>; + def XorRef_ri : XVMInstr<(outs XVMGPR:$dst), + (ins XVMGPR:$src, uimm14:$imm), + "xorref $dst, $src, #$imm", + []>; + def AndRef_ri : XVMInstr<(outs XVMGPR:$dst), + (ins XVMGPR:$src, uimm14:$imm), + "andref $dst, $src, #$imm", + []>; +} +def FI_ri + : XVMInstr<(outs XVMGPR:$dst), + (ins MEMri:$addr), + "", + [(set i64:$dst, FIri:$addr)]> { + // This is a tentative instruction, and will be replaced + // with MOV_rr and ADD_ri in PEI phase +} +def SDT_XVMWrapper : SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>, SDTCisPtrTy<0>]>; +def XVMWrapper : SDNode<"XVMISD::Wrapper", SDT_XVMWrapper>; +/* load 64-bit global addr into register: such as function ptr as parameters */ +def : Pat<(XVMWrapper tglobaladdr:$in), (LD_global_imm64 tglobaladdr:$in)>; + +let isReturn = 1, isTerminator = 1, isBarrier = 1 in { + def RETURN : ControFlowNoArgs<0b00000001, (outs), (ins), "ret", [(XVMretflag)]>; +} + +def : InstAlias<"ret", (RETURN)>; + +let isBranch = 1, hasCtrlDep = 1 in { + def LOOP : ControFlowNoArgs<0b00000000, (outs), (ins), "(loop", []>; + def END_LOOP : ControFlowNoArgs<0b00000000, (outs), (ins), ")", []>; + def BLOCK : ControFlowNoArgs<0b00000000, (outs), (ins), "(block", []>; + def END_BLOCK : ControFlowNoArgs<0b00000000, (outs), (ins), ")", []>; + def BREAK : ControFlowNoArgs<0b00000000, (outs), (ins), "break", []>; + def BREAK_IMM : ControFlowNoArgs<0b00001000, (outs), (ins uimm6:$imm), "break #$imm", []>; + def CONTINUE : ControFlowNoArgs<0b00000000, (outs), (ins), "continue", []>; + def THEN : ControFlowNoArgs<0b00000000, (outs), (ins), "(then", []>; + def END_THEN : ControFlowNoArgs<0b00000000, (outs), (ins), ")", []>; + def ELSE : ControFlowNoArgs<0b00000000, (outs), (ins), "(else", []>; + def END_ELSE : ControFlowNoArgs<0b00000000, (outs), (ins), ")", []>; + def END_IF : ControFlowNoArgs<0b00000000, (outs), (ins), ")", []>; +} + +let mayStore = 1 in { + def STW : STOREi64; + def STH : STOREi64; + def STB : STOREi64; + def STD : STOREi64; +} + +let mayLoad = 1 in { + def LDW_z : LOADi64; + def LDW : LOADi64; + def LDH_z : LOADi64; + def LDH : LOADi64; + def LDB_z : LOADi64; + def LDB : LOADi64; + def LDD : LOADi64; +} + +def AddRef_rr : Ref_rr<"addref">; +def SubRef_rr : Ref_rr<"subref">; +def DifRef_rr : Ref_rr<"difref">; +def OrRef_rr : Ref_rr<"orref">; +def XorRef_rr : Ref_rr<"xorref">; +def AndRef_rr : Ref_rr<"andref">; + +def LoadRef_ri : Ref_ri<"ldrref">; + +def StoreRef_ri : StrRef_ri<"strref">; + +let isAsCheapAsAMove = 1 in { + def ADD_rr : ALU_rr<0b00110100, "add", [(set XVMGPR:$res, (add i64:$src1, i64:$src2))]>; + def ADD_ri : ALU_ri<0b00110101, "add", [(set XVMGPR:$res, (add i64:$src1, uimm14:$src2))]>; + def SUB_rr : ALU_rr<0b00110110, "sub", [(set XVMGPR:$res, (sub i64:$src1, i64:$src2))]>; + def SUB_ri : ALU_ri<0b00110111, "sub", [(set XVMGPR:$res, (sub i64:$src1, uimm14:$src2))]>; + def OR_rr : ALU_rr<0b01000000, "or", [(set XVMGPR:$res, (or i64:$src1, i64:$src2))]>; + def OR_ri : ALU_ri<0b01000001, "or", [(set XVMGPR:$res, (or i64:$src1, uimm14:$src2))]>; + def XOR_rr : ALU_rr<0b01000010, "xor", [(set XVMGPR:$res, (xor i64:$src1, i64:$src2))]>; + def XOR_ri : ALU_ri<0b01000011, "xor", [(set XVMGPR:$res, (xor i64:$src1, uimm14:$src2))]>; + def AND_rr : ALU_rr<0b01000100, "and", [(set XVMGPR:$res, (and i64:$src1, i64:$src2))]>; + def AND_ri : ALU_ri<0b01000101, "and", [(set XVMGPR:$res, (and i64:$src1, uimm14:$src2))]>; + def ASR_rr : ALU_rr<0b01000110, "asr", [(set XVMGPR:$res, (sra i64:$src1, i64:$src2))]>; + def ASR_ri : ALU_ri<0b01000111, "asr", [(set XVMGPR:$res, (sra i64:$src1, uimm6:$src2))]>; + def LSR_rr : ALU_rr<0b01001000, "lsr", [(set XVMGPR:$res, (srl i64:$src1, i64:$src2))]>; + def LSR_ri : ALU_ri<0b01001001, "lsr", [(set XVMGPR:$res, (srl i64:$src1, uimm6:$src2))]>; + def LSL_rr : ALU_rr<0b01001010, "lsl", [(set XVMGPR:$res, (shl i64:$src1, i64:$src2))]>; + def LSL_ri : ALU_ri<0b01001011, "lsl", [(set XVMGPR:$res, (shl i64:$src1, uimm6:$src2))]>; +let isMoveReg = 1 in { + def MOV_rr : ALU_r<0b00110000, "mov", []>; + def MOVK_rr : ALU_ri<0b00110010, "movk", []>; +} +let isMoveImm = 1 in { + def MOV_ri : ALU_i<0b00110001, "mov", [(set XVMGPR:$res, simm16:$src1)]>; + def MOVK_ri : ALU_rii<0b00110011, "movk", []>; +} +} + def MUL_rr : ALU_rr<0b00111000, "mul", [(set XVMGPR:$res, (mul i64:$src1, i64:$src2))]>; + def UDIV_rr : ALU_rr<0b00111001, "udiv", [(set XVMGPR:$res, (udiv i64:$src1, i64:$src2))]>; + def SDIV_rr : ALU_rr<0b00111010, "sdiv", [(set XVMGPR:$res, (sdiv i64:$src1, i64:$src2))]>; + def UMOD_rr : ALU_rr<0b00111011, "umod", [(set XVMGPR:$res, (urem i64:$src1, i64:$src2))]>; + def SMOD_rr : ALU_rr<0b00111100, "smod", [(set XVMGPR:$res, (srem i64:$src1, i64:$src2))]>; + + +def NEG_r : ALU_r<0b00110011, "neg", []>; + +def REV16 : XVMInstr<(outs XVMGPR:$dst), + (ins XVMGPR:$src1, i64imm:$imm1, i64imm:$imm2), + "rev16 $dst, $src1", + [(set i64:$dst, + (or (shl i64:$src1, (i64 imm:$imm1)), (srl (and i64:$src1, (i64 imm:$imm2)), (i64 imm:$imm1))))]>; + +def REV32 : XVMInstr<(outs XVMGPR:$dst), + (ins XVMGPR:$src1, + i64imm:$imm1, i64imm:$imm2, i64imm:$imm3, i64imm:$imm4, i64imm:$imm5), + "rev32 $dst, $src1", + [(set i64:$dst, + (or (or (shl i64:$src1, (i64 imm:$imm1)), (and (shl i64:$src1, (i64 imm:$imm2)), (i64 imm:$imm3))), + (or (and (srl (and i64:$src1, (i64 imm:$imm4)), (i64 imm:$imm2)), (i64 imm:$imm5)), (srl (and i64:$src1, (i64 imm:$imm4)), (i64 imm:$imm1)))))]>; + +def REV64 : XVMInstr<(outs XVMGPR:$dst), + (ins XVMGPR:$src1, + i64imm:$imm1, i64imm:$imm2, i64imm:$imm3, i64imm:$imm4, i64imm:$imm5, + i64imm:$imm6, i64imm:$imm7, i64imm:$imm8, i64imm:$imm9, i64imm:$imm10), + "rev64 $dst, $src1", + [(set i64:$dst, + (or (or (or (shl i64:$src1, (i64 imm:$imm2)), (and (shl i64:$src1, (i64 imm:$imm3)), (i64 imm:$imm4))), + (or (and (shl i64:$src1, (i64 imm:$imm5)), (i64 imm:$imm6)), (and (shl i64:$src1, (i64 imm:$imm1)), (i64 imm:$imm7)))), + (or (or (and (srl i64:$src1, (i64 imm:$imm1)), (i64 imm:$imm8)), + (and (srl i64:$src1, (i64 imm:$imm5)), (i64 imm:$imm9))), (or (and (srl i64:$src1, (i64 imm:$imm3)), (i64 imm:$imm10)), (srl i64:$src1, (i64 imm:$imm2))))))]>; + +let AddedComplexity = 1 in +def : Pat < (sub 0, i64:$src2), (NEG_r i64:$src2)>; + +// mov combinations +def GetMovImm : SDNodeXFormgetTargetConstant( (N->getSExtValue() & 0xffff), SDLoc(N), MVT::i64); +}]>; +def GetMovk0Imm : SDNodeXFormgetTargetConstant( (N->getSExtValue() & 0xffff), SDLoc(N), MVT::i64); +}]>; +def GetMovk1Imm : SDNodeXFormgetTargetConstant( ( (N->getSExtValue() >> 16 ) & 0xffff), SDLoc(N), MVT::i64); +}]>; +def GetMovk2Imm : SDNodeXFormgetTargetConstant( ( (N->getSExtValue() >> 32 ) & 0xffff), SDLoc(N), MVT::i64); +}]>; +def GetMovk3Imm : SDNodeXFormgetTargetConstant( ( (N->getSExtValue() >> 48 ) & 0xffff), SDLoc(N), MVT::i64); +}]>; + +def IsLess15Bits : ImmLeaf; +def IsLess16Bits : ImmLeaf 32767 && (long long)Imm <= 65535; +}], GetMovk0Imm>; +def IsOver16Bits : ImmLeaf 65535 && (long long)Imm <= 4294967295; +}], GetMovk1Imm>; +def IsOver32Bits : ImmLeaf 4294967295 && (long long)Imm <= 281474976710655; +}], GetMovk2Imm>; +def IsOver48Bits : ImmLeaf 281474976710655 || (long long)Imm <= -32769; +}], GetMovk3Imm>; + +def : Pat< + (i64 IsLess16Bits:$src1), + (MOVK_ri (MOV_ri 0), IsLess16Bits:$src1, 0) +>; +def : Pat< + (i64 IsOver16Bits:$src1), + (MOVK_ri (MOVK_ri (MOV_ri 0), IsLess16Bits:$src1, 0), IsOver16Bits:$src1, 1) +>; +def : Pat< + (i64 IsOver32Bits:$src1), + (MOVK_ri (MOVK_ri (MOVK_ri (MOV_ri 0), IsLess16Bits:$src1, 0), IsOver16Bits:$src1, 1), IsOver32Bits:$src1, 2) +>; +def : Pat< + (i64 IsOver48Bits:$src1), + (MOVK_ri (MOVK_ri (MOVK_ri (MOVK_ri (MOV_ri 0), IsLess16Bits:$src1, 0), IsOver16Bits:$src1, 1), IsOver32Bits:$src1, 2), IsOver48Bits:$src1, 3) +>; + + +let isBranch = 1, isTerminator = 1, hasCtrlDep = 1 in { + def BR: XVMInstr<(outs), (ins bb_op:$dst), "br \t$dst", [(br bb:$dst)]>; + def LOOP_BR: XVMInstr<(outs), (ins bb_op:$dst), "br \t$dst", [(br bb:$dst)]>; +} + +//TODO: all signed and unsigned comparisons are the same for the moment +def BUEQ_rr : BranchCC_rr<"ueq">; +def BSNEQ_rr : BranchCC_rr<"une">; +def BSGE_rr : BranchCC_rr<"sge">; +def BUGE_rr : BranchCC_rr<"uge">; +def BSLE_rr : BranchCC_rr<"sle">; +def BULE_rr : BranchCC_rr<"ule">; +def BSGT_rr : BranchCC_rr<"sgt">; +def BUGT_rr : BranchCC_rr<"ugt">; +def BSLT_rr : BranchCC_rr<"slt">; +def BULT_rr : BranchCC_rr<"ult">; + +def BSEQ_ri : BranchCC_ris<"seq">; +def BUEQ_ri : BranchCC_riu<"ueq">; +def BSNEQ_ri : BranchCC_ris<"sne">; +def BUNEQ_ri: BranchCC_riu<"une">; +def BSGE_ri : BranchCC_ris<"sge">; +def BUGE_ri : BranchCC_riu<"uge">; +def BSLE_ri : BranchCC_ris<"sle">; +def BULE_ri : BranchCC_riu<"ule">; +def BSGT_ri : BranchCC_ris<"sgt">; +def BUGT_ri : BranchCC_riu<"ugt">; +def BSLT_ri : BranchCC_ris<"slt">; +def BULT_ri : BranchCC_riu<"ult">; + +def LOOP_BUEQ_rr : BranchCC_rr<"ueq">; +def LOOP_BSNEQ_rr : BranchCC_rr<"une">; +def LOOP_BSGE_rr : BranchCC_rr<"sge">; +def LOOP_BUGE_rr : BranchCC_rr<"uge">; +def LOOP_BSLE_rr : BranchCC_rr<"sle">; +def LOOP_BULE_rr : BranchCC_rr<"ule">; +def LOOP_BSGT_rr : BranchCC_rr<"sgt">; +def LOOP_BUGT_rr : BranchCC_rr<"ugt">; +def LOOP_BSLT_rr : BranchCC_rr<"slt">; +def LOOP_BULT_rr : BranchCC_rr<"ult">; + +def LOOP_BSEQ_ri : BranchCC_ris<"seq">; +def LOOP_BUEQ_ri : BranchCC_riu<"ueq">; +def LOOP_BSNEQ_ri : BranchCC_ris<"sne">; +def LOOP_BUNEQ_ri: BranchCC_riu<"une">; +def LOOP_BSGE_ri : BranchCC_ris<"sge">; +def LOOP_BUGE_ri : BranchCC_riu<"uge">; +def LOOP_BSLE_ri : BranchCC_ris<"sle">; +def LOOP_BULE_ri : BranchCC_riu<"ule">; +def LOOP_BSGT_ri : BranchCC_ris<"sgt">; +def LOOP_BUGT_ri : BranchCC_riu<"ugt">; +def LOOP_BSLT_ri : BranchCC_ris<"slt">; +def LOOP_BULT_ri : BranchCC_riu<"ult">; + +def : Pat<(XVMbrccrr i64:$op1, i64:$op2, SETNE, bb:$dst), + (BSNEQ_rr bb:$dst, XVMGPR:$op1, XVMGPR:$op2)>; +def : Pat<(XVMbrccrr i64:$op1, i64:$op2, SETEQ, bb:$dst), + (BUEQ_rr bb:$dst, XVMGPR:$op1, XVMGPR:$op2)>; +def : Pat<(XVMbrccrr i64:$op1, i64:$op2, SETGE, bb:$dst), + (BSGE_rr bb:$dst, XVMGPR:$op1, XVMGPR:$op2)>; +def : Pat<(XVMbrccrr i64:$op1, i64:$op2, SETUGE, bb:$dst), + (BUGE_rr bb:$dst, XVMGPR:$op1, XVMGPR:$op2)>; +def : Pat<(XVMbrccrr i64:$op1, i64:$op2, SETLE, bb:$dst), + (BSLE_rr bb:$dst, XVMGPR:$op1, XVMGPR:$op2)>; +def : Pat<(XVMbrccrr i64:$op1, i64:$op2, SETULE, bb:$dst), + (BULE_rr bb:$dst, XVMGPR:$op1, XVMGPR:$op2)>; +def : Pat<(XVMbrccrr i64:$op1, i64:$op2, SETGT, bb:$dst), + (BSGT_rr bb:$dst, XVMGPR:$op1, XVMGPR:$op2)>; +def : Pat<(XVMbrccrr i64:$op1, i64:$op2, SETUGT, bb:$dst), + (BUGT_rr bb:$dst, XVMGPR:$op1, XVMGPR:$op2)>; +def : Pat<(XVMbrccrr i64:$op1, i64:$op2, SETLT, bb:$dst), + (BSLT_rr bb:$dst, XVMGPR:$op1, XVMGPR:$op2)>; +def : Pat<(XVMbrccrr i64:$op1, i64:$op2, SETULT, bb:$dst), + (BULT_rr bb:$dst, XVMGPR:$op1, XVMGPR:$op2)>; + +def DoesNotFitIn15Bits : ImmLeaf= 0 ); +}]>; +class BigImmediateBRCC + : Pat<(XVMbrccri i64:$op1, DoesNotFitIn15Bits:$op2, condcode, bb:$dst), + (outnode bb:$dst, XVMGPR:$op1, i64:$op2)>; + +def SignedDoesNotFitIn15Bits : ImmLeaf= -16383 ); +}]>; +class SignedBigImmediateBRCC + : Pat<(XVMbrccri i64:$op1, SignedDoesNotFitIn15Bits:$op2, condcode, bb:$dst), + (outnode bb:$dst, XVMGPR:$op1, i64:$op2)>; + +def : SignedBigImmediateBRCC; +def : SignedBigImmediateBRCC; +def : SignedBigImmediateBRCC; +def : BigImmediateBRCC; +def : SignedBigImmediateBRCC; +def : BigImmediateBRCC; +def : SignedBigImmediateBRCC; +def : BigImmediateBRCC; +def : SignedBigImmediateBRCC; +def : BigImmediateBRCC; + +def : Pat<(XVMbrccri i64:$op1, imm:$op2, SETNE, bb:$dst), + (BSNEQ_ri bb:$dst, XVMGPR:$op1, simm16:$op2)>; +def : Pat<(XVMbrccri i64:$op1, imm:$op2, SETEQ, bb:$dst), + (BSEQ_ri bb:$dst, XVMGPR:$op1, simm16:$op2)>; +def : Pat<(XVMbrccri i64:$op1, imm:$op2, SETGE, bb:$dst), + (BSGE_ri bb:$dst, XVMGPR:$op1, simm16:$op2)>; +def : Pat<(XVMbrccri i64:$op1, imm:$op2, SETUGE, bb:$dst), + (BUGE_ri bb:$dst, XVMGPR:$op1, uimm16:$op2)>; +def : Pat<(XVMbrccri i64:$op1, imm:$op2, SETLE, bb:$dst), + (BSLE_ri bb:$dst, XVMGPR:$op1, simm16:$op2)>; +def : Pat<(XVMbrccri i64:$op1, imm:$op2, SETULE, bb:$dst), + (BULE_ri bb:$dst, XVMGPR:$op1, uimm16:$op2)>; +def : Pat<(XVMbrccri i64:$op1, imm:$op2, SETGT, bb:$dst), + (BSGT_ri bb:$dst, XVMGPR:$op1, simm16:$op2)>; +def : Pat<(XVMbrccri i64:$op1, imm:$op2, SETUGT, bb:$dst), + (BUGT_ri bb:$dst, XVMGPR:$op1, uimm16:$op2)>; +def : Pat<(XVMbrccri i64:$op1, imm:$op2, SETLT, bb:$dst), + (BSLT_ri bb:$dst, XVMGPR:$op1, simm16:$op2)>; +def : Pat<(XVMbrccri i64:$op1, imm:$op2, SETULT, bb:$dst), + (BULT_ri bb:$dst, XVMGPR:$op1, uimm16:$op2)>; + +include "XVMInstrBulkMemory.td" \ No newline at end of file diff --git a/llvm/lib/Target/XVM/XVMMCInstLower.cpp b/llvm/lib/Target/XVM/XVMMCInstLower.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6414a7de94eaa7d7c5b8be68a693c82f5c42a6ea --- /dev/null +++ b/llvm/lib/Target/XVM/XVMMCInstLower.cpp @@ -0,0 +1,16 @@ +//=-- XVMMCInstLower.cpp - Convert XVM MachineInstr to an MCInst ------------=// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file contains code to lower XVM MachineInstrs to their corresponding +// MCInst records. +// +//===----------------------------------------------------------------------===// +#ifdef XVM_DYLIB_MODE +// Insert the XVM backend code here + +#endif diff --git a/llvm/lib/Target/XVM/XVMMCInstLower.h b/llvm/lib/Target/XVM/XVMMCInstLower.h new file mode 100644 index 0000000000000000000000000000000000000000..aa2a165b0cc6a66cf3455ef44e6c383811799be4 --- /dev/null +++ b/llvm/lib/Target/XVM/XVMMCInstLower.h @@ -0,0 +1,41 @@ +//===-- XVMMCInstLower.h - Lower MachineInstr to MCInst ---------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_XVM_XVMMCINSTLOWER_H +#define LLVM_LIB_TARGET_XVM_XVMMCINSTLOWER_H + +#include "llvm/Support/Compiler.h" + +namespace llvm { +class AsmPrinter; +class MCContext; +class MCInst; +class MCOperand; +class MCSymbol; +class MachineInstr; +class MachineOperand; + +// XVMMCInstLower - This class is used to lower an MachineInstr into an MCInst. +class LLVM_LIBRARY_VISIBILITY XVMMCInstLower { + MCContext &Ctx; + + AsmPrinter &Printer; + +public: + XVMMCInstLower(MCContext &ctx, AsmPrinter &printer) + : Ctx(ctx), Printer(printer) {} + void Lower(const MachineInstr *MI, MCInst &OutMI) const; + + MCOperand LowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym) const; + + MCSymbol *GetGlobalAddressSymbol(const MachineOperand &MO) const; + MCSymbol *GetExternalSymbolSymbol(const MachineOperand &MO) const; +}; +} + +#endif diff --git a/llvm/lib/Target/XVM/XVMMachineFunctionInfo.h b/llvm/lib/Target/XVM/XVMMachineFunctionInfo.h new file mode 100644 index 0000000000000000000000000000000000000000..ac3ff3ac210417af027fe9372fc418671850fd69 --- /dev/null +++ b/llvm/lib/Target/XVM/XVMMachineFunctionInfo.h @@ -0,0 +1,20 @@ +#ifndef LLVM_LIB_TARGET_XVM_XVMMACHINEFUNCTIONINFO_H +#define LLVM_LIB_TARGET_XVM_XVMMACHINEFUNCTIONINFO_H + +#include "llvm/CodeGen/MachineFunction.h" + +namespace llvm { + +class XVMMachineFunctionInfo : public MachineFunctionInfo { +public: + XVMMachineFunctionInfo(const MachineFunction &MF) {} + void SetVarArgsFrameIndex(int _index) { VarArgsFrameIndex = _index; } + int GetVarArgsFrameIndex() { return VarArgsFrameIndex; } +private: + int VarArgsFrameIndex; +}; + + +} + +#endif \ No newline at end of file diff --git a/llvm/lib/Target/XVM/XVMRegisterInfo.cpp b/llvm/lib/Target/XVM/XVMRegisterInfo.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2be5295ec007ef7e50f14873a0da6e4bec7c64c6 --- /dev/null +++ b/llvm/lib/Target/XVM/XVMRegisterInfo.cpp @@ -0,0 +1,15 @@ +//===-- XVMRegisterInfo.cpp - XVM Register Information ----------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file contains the XVM implementation of the TargetRegisterInfo class. +// +//===----------------------------------------------------------------------===// +#ifdef XVM_DYLIB_MODE +// Insert the XVM backend code here + +#endif diff --git a/llvm/lib/Target/XVM/XVMRegisterInfo.h b/llvm/lib/Target/XVM/XVMRegisterInfo.h new file mode 100644 index 0000000000000000000000000000000000000000..2a5221d08a11d34b7d64e5b96b069d2665c62b35 --- /dev/null +++ b/llvm/lib/Target/XVM/XVMRegisterInfo.h @@ -0,0 +1,45 @@ +//===-- XVMRegisterInfo.h - XVM Register Information Impl -------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file contains the XVM implementation of the TargetRegisterInfo class. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_XVM_XVMREGISTERINFO_H +#define LLVM_LIB_TARGET_XVM_XVMREGISTERINFO_H + +#include "llvm/CodeGen/TargetRegisterInfo.h" + +#define GET_REGINFO_HEADER +#include "XVMGenRegisterInfo.inc" + +namespace llvm { + +struct XVMRegisterInfo : public XVMGenRegisterInfo { + + XVMRegisterInfo(); + + const MCPhysReg *getCalleeSavedRegs(const MachineFunction *MF) const override; + + BitVector getReservedRegs(const MachineFunction &MF) const override; + + void eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj, + unsigned FIOperandNum, + RegScavenger *RS = nullptr) const override; + + Register getFrameRegister(const MachineFunction &MF) const override; + + const TargetRegisterClass * + getPointerRegClass(const MachineFunction &MF, unsigned Kind = 0) const override; + + const uint32_t *getCallPreservedMask(const MachineFunction &MF, + CallingConv::ID) const override; +}; +} + +#endif diff --git a/llvm/lib/Target/XVM/XVMRegisterInfo.td b/llvm/lib/Target/XVM/XVMRegisterInfo.td new file mode 100644 index 0000000000000000000000000000000000000000..5b7dfa12a22a7f16dafa217a84191ca597378d72 --- /dev/null +++ b/llvm/lib/Target/XVM/XVMRegisterInfo.td @@ -0,0 +1,33 @@ +//===-- XVMRegisterInfo.td - XVM Register defs -------------*- tablegen -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +//===----------------------------------------------------------------------===// +// Declarations that describe the XVM register file +//===----------------------------------------------------------------------===// + + +// Registers are identified with 4-bit ID numbers. +// Ri - 64-bit integer registers +class Ri Enc, string n> : Register { + let HWEncoding = Enc; + let Namespace = "XVM"; +} + +foreach I = 0-17 in { + // 64-bit Integer registers + def R#I : Ri, DwarfRegNum<[I]>; +} + +def SP : Ri<18, "sp">, DwarfRegNum<[31]>; + +def XVMGPR : RegisterClass<"XVM", [i64], 64, (add + R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R15, R16, R17, + R0 // Return value +)>; + +def XVMRR : RegisterClass<"XVM", [i64], 64, (add SP)>; \ No newline at end of file diff --git a/llvm/lib/Target/XVM/XVMSelectionDAGInfo.cpp b/llvm/lib/Target/XVM/XVMSelectionDAGInfo.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a681b7bea5b19c46eaf07765318248a5feae26e1 --- /dev/null +++ b/llvm/lib/Target/XVM/XVMSelectionDAGInfo.cpp @@ -0,0 +1,15 @@ +//===-- XVMSelectionDAGInfo.cpp - XVM SelectionDAG Info -------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file implements the XVMSelectionDAGInfo class. +// +//===----------------------------------------------------------------------===// +#ifdef XVM_DYLIB_MODE +// Insert the XVM backend code here + +#endif diff --git a/llvm/lib/Target/XVM/XVMSelectionDAGInfo.h b/llvm/lib/Target/XVM/XVMSelectionDAGInfo.h new file mode 100644 index 0000000000000000000000000000000000000000..7cc229c58d9ad35bfff9b7e812eb76cb691f7d9d --- /dev/null +++ b/llvm/lib/Target/XVM/XVMSelectionDAGInfo.h @@ -0,0 +1,44 @@ +//===-- XVMSelectionDAGInfo.h - XVM SelectionDAG Info -----------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file defines the XVM subclass for SelectionDAGTargetInfo. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_XVM_XVMSELECTIONDAGINFO_H +#define LLVM_LIB_TARGET_XVM_XVMSELECTIONDAGINFO_H + +#include "llvm/CodeGen/SelectionDAGTargetInfo.h" + +namespace llvm { + +class XVMSelectionDAGInfo : public SelectionDAGTargetInfo { +public: + SDValue EmitTargetCodeForMemcpy(SelectionDAG &DAG, const SDLoc &dl, + SDValue Chain, SDValue Dst, SDValue Src, + SDValue Size, Align Alignment, + bool isVolatile, bool AlwaysInline, + MachinePointerInfo DstPtrInfo, + MachinePointerInfo SrcPtrInfo) const override; + + SDValue EmitTargetCodeForMemmove(SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, + SDValue Op1, SDValue Op2, SDValue Op3, + Align Alignment, bool isVolatile, + MachinePointerInfo DstPtrInfo, + MachinePointerInfo SrcPtrInfo) const override; + + SDValue EmitTargetCodeForMemset(SelectionDAG &DAG, const SDLoc &DL, + SDValue Chain, SDValue Op1, SDValue Op2, + SDValue Op3, Align Alignment, bool IsVolatile, + bool AlwaysInline, + MachinePointerInfo DstPtrInfo) const override; +}; + +} + +#endif diff --git a/llvm/lib/Target/XVM/XVMSortRegion.cpp b/llvm/lib/Target/XVM/XVMSortRegion.cpp new file mode 100644 index 0000000000000000000000000000000000000000..dc79f12b0bc003091707bc4de050f8378c4a63c7 --- /dev/null +++ b/llvm/lib/Target/XVM/XVMSortRegion.cpp @@ -0,0 +1,4 @@ +#ifdef XVM_DYLIB_MODE +// Insert the XVM backend code here + +#endif \ No newline at end of file diff --git a/llvm/lib/Target/XVM/XVMSortRegion.h b/llvm/lib/Target/XVM/XVMSortRegion.h new file mode 100644 index 0000000000000000000000000000000000000000..41929766eb3abc24211838f1b24c9be69d83185f --- /dev/null +++ b/llvm/lib/Target/XVM/XVMSortRegion.h @@ -0,0 +1,82 @@ +//===-- XVMSortRegion.h - XVM Sort SortRegion ----*- C++-*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// \brief This file implements regions used in CFGSort and CFGStackify. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_XVM_XVMSORTREGION_H +#define LLVM_LIB_TARGET_XVM_XVMSORTREGION_H + +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/iterator_range.h" + +namespace llvm { + +class MachineBasicBlock; +class MachineLoop; +class MachineLoopInfo; + +namespace XVM { + +// Wrapper for loops and exceptions +class SortRegion { +public: + virtual ~SortRegion() = default; + virtual MachineBasicBlock *getHeader() const = 0; + virtual bool contains(const MachineBasicBlock *MBB) const = 0; + virtual unsigned getNumBlocks() const = 0; + using block_iterator = typename ArrayRef::const_iterator; + virtual iterator_range blocks() const = 0; + virtual bool isLoop() const = 0; +}; + +template class ConcreteSortRegion : public SortRegion { + const T *Unit; + +public: + ConcreteSortRegion(const T *Unit) : Unit(Unit) {} + MachineBasicBlock *getHeader() const override { return Unit->getHeader(); } + bool contains(const MachineBasicBlock *MBB) const override { + return Unit->contains(MBB); + } + unsigned getNumBlocks() const override { return Unit->getNumBlocks(); } + iterator_range blocks() const override { + return Unit->blocks(); + } + bool isLoop() const override { return false; } +}; + +// This class has information of nested SortRegions; this is analogous to what +// LoopInfo is for loops. +class SortRegionInfo { + friend class ConcreteSortRegion; + + const MachineLoopInfo &MLI; + DenseMap> LoopMap; + +public: + SortRegionInfo(const MachineLoopInfo &MLI) : MLI(MLI) {} + + // Returns a smallest loop or exception that contains MBB + const SortRegion *getRegionFor(const MachineBasicBlock *MBB); + + // Return the "bottom" block among all blocks dominated by the region + // (MachineLoop or XVMException) header. This works when the entity is + // discontiguous. + MachineBasicBlock *getBottom(const SortRegion *R); + MachineBasicBlock *getBottom(const MachineLoop *ML); +}; + +} // end namespace XVM + +} // end namespace llvm + +#endif diff --git a/llvm/lib/Target/XVM/XVMSubtarget.cpp b/llvm/lib/Target/XVM/XVMSubtarget.cpp new file mode 100644 index 0000000000000000000000000000000000000000..63b5b636d7a3bbbd366d450831d08793938d736b --- /dev/null +++ b/llvm/lib/Target/XVM/XVMSubtarget.cpp @@ -0,0 +1,15 @@ +//===-- XVMSubtarget.cpp - XVM Subtarget Information ----------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file implements the XVM specific subclass of TargetSubtargetInfo. +// +//===----------------------------------------------------------------------===// +#ifdef XVM_DYLIB_MODE +// Insert the XVM backend code here + +#endif diff --git a/llvm/lib/Target/XVM/XVMSubtarget.h b/llvm/lib/Target/XVM/XVMSubtarget.h new file mode 100644 index 0000000000000000000000000000000000000000..643b03528b101ea2364aed5f3390f45083b552b2 --- /dev/null +++ b/llvm/lib/Target/XVM/XVMSubtarget.h @@ -0,0 +1,69 @@ +//===-- XVMSubtarget.h - Define Subtarget for the XVM -----------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file declares the XVM specific subclass of TargetSubtargetInfo. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_XVM_XVMSUBTARGET_H +#define LLVM_LIB_TARGET_XVM_XVMSUBTARGET_H + +#include "XVMFrameLowering.h" +#include "XVMISelLowering.h" +#include "XVMInstrInfo.h" +#include "XVMSelectionDAGInfo.h" +#include "llvm/CodeGen/SelectionDAGTargetInfo.h" +#include "llvm/CodeGen/TargetSubtargetInfo.h" +#include "llvm/IR/DataLayout.h" +#include "llvm/Target/TargetMachine.h" + +#define GET_SUBTARGETINFO_HEADER +#include "XVMGenSubtargetInfo.inc" + +namespace llvm { + +class XVMSubtarget : public XVMGenSubtargetInfo { + virtual void anchor(); + XVMInstrInfo InstrInfo; + XVMFrameLowering FrameLowering; + XVMTargetLowering TLInfo; + XVMSelectionDAGInfo TSInfo; + +protected: + bool isCommon; + +public: + // This constructor initializes the data members to match that + // of the specified triple. + XVMSubtarget(const Triple &TT, const std::string &CPU, const std::string &FS, + const TargetMachine &TM); + + XVMSubtarget &initializeSubtargetDependencies(StringRef CPU, StringRef FS); + + // ParseSubtargetFeatures - Parses features string setting specified + // subtarget options. Definition of function is auto generated by tblgen. + void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS); + + const XVMInstrInfo *getInstrInfo() const override { return &InstrInfo; } + const XVMFrameLowering *getFrameLowering() const override { + return &FrameLowering; + } + const XVMTargetLowering *getTargetLowering() const override { + return &TLInfo; + } + const XVMSelectionDAGInfo *getSelectionDAGInfo() const override { + return &TSInfo; + } + const XVMRegisterInfo *getRegisterInfo() const override { + return &InstrInfo.getRegisterInfo(); + } + +}; +} // End llvm namespace + +#endif diff --git a/llvm/lib/Target/XVM/XVMTargetMachine.cpp b/llvm/lib/Target/XVM/XVMTargetMachine.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0320e7a770ba8b3e8d08c38897c1989a2053e938 --- /dev/null +++ b/llvm/lib/Target/XVM/XVMTargetMachine.cpp @@ -0,0 +1,24 @@ +//===-- XVMTargetMachine.cpp - Define TargetMachine for XVM ---------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// Implements the info about XVM target spec. +// +//===----------------------------------------------------------------------===// + +#ifdef XVM_DYLIB_MODE +// Insert the XVM backend code here +#include "llvm/Support/Compiler.h" +extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeXVMTarget() { +} + +#else + +#include "XVMDylibHandler.h" +LLVM_INIT_XVM_COMP(Target) + +#endif diff --git a/llvm/lib/Target/XVM/XVMTargetMachine.h b/llvm/lib/Target/XVM/XVMTargetMachine.h new file mode 100644 index 0000000000000000000000000000000000000000..3b25b0f1e89a9ce9c636b7af02bc0391b197f1bc --- /dev/null +++ b/llvm/lib/Target/XVM/XVMTargetMachine.h @@ -0,0 +1,45 @@ +//===-- XVMTargetMachine.h - Define TargetMachine for XVM --- C++ ---===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file declares the XVM specific subclass of TargetMachine. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_XVM_XVMTARGETMACHINE_H +#define LLVM_LIB_TARGET_XVM_XVMTARGETMACHINE_H + +#include "XVMSubtarget.h" +#include "llvm/Target/TargetMachine.h" + +namespace llvm { +class XVMTargetMachine : public LLVMTargetMachine { + std::unique_ptr TLOF; + XVMSubtarget Subtarget; + +public: + XVMTargetMachine(const Target &T, const Triple &TT, StringRef CPU, + StringRef FS, const TargetOptions &Options, + Optional RM, Optional CM, + CodeGenOpt::Level OL, bool JIT); + + const XVMSubtarget *getSubtargetImpl() const { return &Subtarget; } + const XVMSubtarget *getSubtargetImpl(const Function &) const override { + return &Subtarget; + } + + TargetPassConfig *createPassConfig(PassManagerBase &PM) override; + + TargetTransformInfo getTargetTransformInfo(const Function &F) const override; + + TargetLoweringObjectFile *getObjFileLowering() const override { + return TLOF.get(); + } +}; +} + +#endif diff --git a/llvm/lib/Target/XVM/XVMTargetTransformInfo.h b/llvm/lib/Target/XVM/XVMTargetTransformInfo.h new file mode 100644 index 0000000000000000000000000000000000000000..2194866b6ab0ffb5fb834abf484aef2ddb24ae0d --- /dev/null +++ b/llvm/lib/Target/XVM/XVMTargetTransformInfo.h @@ -0,0 +1,87 @@ +//===------ XVMTargetTransformInfo.h - XVM specific TTI ---------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file uses the target's specific information to +// provide more precise answers to certain TTI queries, while letting the +// target independent and default TTI implementations handle the rest. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_XVM_XVMTARGETTRANSFORMINFO_H +#define LLVM_LIB_TARGET_XVM_XVMTARGETTRANSFORMINFO_H + +#include "XVMTargetMachine.h" +#include "llvm/Analysis/TargetTransformInfo.h" +#include "llvm/CodeGen/BasicTTIImpl.h" +#include "llvm/Transforms/Utils/ScalarEvolutionExpander.h" + +namespace llvm { +class XVMTTIImpl : public BasicTTIImplBase { + typedef BasicTTIImplBase BaseT; + typedef TargetTransformInfo TTI; + friend BaseT; + + const XVMSubtarget *ST; + const XVMTargetLowering *TLI; + + const XVMSubtarget *getST() const { return ST; } + const XVMTargetLowering *getTLI() const { return TLI; } + +public: + explicit XVMTTIImpl(const XVMTargetMachine *TM, const Function &F) + : BaseT(TM, F.getParent()->getDataLayout()), ST(TM->getSubtargetImpl(F)), + TLI(ST->getTargetLowering()) {} + + int getIntImmCost(const APInt &Imm, Type *Ty, TTI::TargetCostKind CostKind) { + if (Imm.getBitWidth() <= 64 && isInt<32>(Imm.getSExtValue())) + return TTI::TCC_Free; + + return TTI::TCC_Basic; + } + + InstructionCost getCmpSelInstrCost(unsigned Opcode, Type *ValTy, Type *CondTy, + CmpInst::Predicate VecPred, + TTI::TargetCostKind CostKind, + const llvm::Instruction *I = nullptr) { + if (Opcode == Instruction::Select) + return SCEVCheapExpansionBudget.getValue(); + + return BaseT::getCmpSelInstrCost(Opcode, ValTy, CondTy, VecPred, CostKind, + I); + } + + InstructionCost getArithmeticInstrCost( + unsigned Opcode, Type *Ty, TTI::TargetCostKind CostKind, + TTI::OperandValueKind Opd1Info = TTI::OK_AnyValue, + TTI::OperandValueKind Opd2Info = TTI::OK_AnyValue, + TTI::OperandValueProperties Opd1PropInfo = TTI::OP_None, + TTI::OperandValueProperties Opd2PropInfo = TTI::OP_None, + ArrayRef Args = ArrayRef(), + const Instruction *CxtI = nullptr) { + int ISD = TLI->InstructionOpcodeToISD(Opcode); + if (ISD == ISD::ADD && CostKind == TTI::TCK_RecipThroughput) + return SCEVCheapExpansionBudget.getValue() + 1; + + return BaseT::getArithmeticInstrCost(Opcode, Ty, CostKind, Opd1Info, + Opd2Info, Opd1PropInfo, + Opd2PropInfo); + } + + TTI::MemCmpExpansionOptions enableMemCmpExpansion(bool OptSize, + bool IsZeroCmp) const { + TTI::MemCmpExpansionOptions Options; + Options.LoadSizes = {8, 4, 2, 1}; + Options.MaxNumLoads = TLI->getMaxExpandSizeMemcmp(OptSize); + return Options; + } + +}; + +} // end namespace llvm + +#endif // LLVM_LIB_TARGET_XVM_XVMTARGETTRANSFORMINFO_H diff --git a/llvm/lib/Target/XVM/XVMUpdateRefInstrForMI.cpp b/llvm/lib/Target/XVM/XVMUpdateRefInstrForMI.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9427a2f4b6b7f8a4c06f8fc54319d1e556c3f159 --- /dev/null +++ b/llvm/lib/Target/XVM/XVMUpdateRefInstrForMI.cpp @@ -0,0 +1,4 @@ +#ifdef XVM_DYLIB_MODE +// Insert the XVM backend code here + +#endif diff --git a/llvm/lib/Target/XVM/XVM_def.h b/llvm/lib/Target/XVM/XVM_def.h new file mode 100644 index 0000000000000000000000000000000000000000..ac0910a01792a094a427d68b7c7063970aa3938e --- /dev/null +++ b/llvm/lib/Target/XVM/XVM_def.h @@ -0,0 +1,68 @@ +#ifndef LLVM_LIB_TARGET_XVM_XVM_DEF_H +#define LLVM_LIB_TARGET_XVM_XVM_DEF_H + +#include +#include "llvm/Support/raw_ostream.h" +using namespace llvm; + +/* Flags for MCInst */ +#define FUNC_CALL_FLAG_MC_INST_IMM 0x00000080 +#define FUNC_CALL_FLAG_MC_INST_REG 0x00000081 +#define FUNC_ID_FLAG_MC_INST_REG 0x00000082 +#define GLOBAL_DATAREF_FLAG_MC_INST 0x00000083 + + +namespace llvm { + +/** XVM section permissions + index: | 7 6 5 4 3 2 1 0 +meaning: | reserved X W R +*/ +#define XVM_SECTION_PERM_UNKNOWN 0b00000000 +#define XVM_SECTION_PERM_RO 0b00000001 +#define XVM_SECTION_PERM_WO 0b00000010 +#define XVM_SECTION_PERM_XO 0b00000100 +#define XVM_SECTION_PERM_RW 0b00000011 +#define XVM_SECTION_PERM_RX 0b00000101 +#define XVM_SECTION_PERM_WX 0b00000110 +#define XVM_SECTION_PERM_RWX 0b00000111 + +#define XVM_SECTION_DATA_TYPE_UNKNOWN 0b00000000 +#define XVM_SECTION_DATA_TYPE_UNDEF 0b00000001 +#define XVM_SECTION_DATA_TYPE_NUMERIC 0b00000010 +#define XVM_SECTION_DATA_TYPE_POINTER 0b00000100 +#define XVM_SECTION_DATA_TYPE_STRING 0b00001000 +#define XVM_SECTION_DATA_TYPE_ARRAY 0b00010000 +#define XVM_SECTION_DATA_TYPE_STRUCT 0b00100000 +#define XVM_SECTION_DATA_TYPE_BSS 0b01000000 + +typedef struct XVMGVPatchInfo { + std::string SymName; + int AddEnd; +} XVMGVPathInfo; + +typedef struct XVMSectionInfo { + unsigned short MergedSecIndex;/* the merged section index */ + uint64_t SubSecOffset; /* the offset of the subsection in the merged section*/ + + unsigned short SecIndex; /* start from 0, 1, ...*/ + std::string SecComment; /* the comment to be printed */ + std::string SymName; + + std::string SecName; /* such as '$bss', '$data', '$rodata'*/ + unsigned char Permission; /* such as rw, ro,*/ + unsigned int SecSize; /* such as 32, 64, 111,*/ + std::string SecBuf; /* such as 0 for some integer, or "hello world!\x00" for some string*/ + // SmallVector SecBuf; + unsigned char BufType; /* such as int, char, string ...*/ + short PtrSecIndex; /* the section index pointer to: -1-> not ptr */ + SmallVector PatchListInfo; +} XVMSectionInfo; + +} + +extern unsigned int GetPtrRegisterLevelBasedOnName(const char * _name); +extern uint64_t GetSubSecOffsetForGlobal(const char * _name); +extern int GetFuncIndex(const char * _name); + +#endif /* LLVM_LIB_TARGET_XVM_XVM_DEF_H */ diff --git a/llvm/tools/llvm-shlib/CMakeLists.txt b/llvm/tools/llvm-shlib/CMakeLists.txt index 9043b2014ffe6c1ef6f3b9b64864bcd2fc539d69..f481963784894574b2733ee9830949d8eb989738 100644 --- a/llvm/tools/llvm-shlib/CMakeLists.txt +++ b/llvm/tools/llvm-shlib/CMakeLists.txt @@ -14,6 +14,11 @@ if(LLVM_BUILD_LLVM_DYLIB) if(MSVC) message(FATAL_ERROR "Generating libLLVM is not supported on MSVC") endif() + # OHOS_LOCAL begin + if (LLVM_LINK_LLVM_DYLIB) + set(INSTALL_WITH_TOOLCHAIN INSTALL_WITH_TOOLCHAIN) + endif() + # OHOS_LOCAL end llvm_map_components_to_libnames(LIB_NAMES ${LLVM_DYLIB_COMPONENTS}) @@ -22,15 +27,31 @@ if(LLVM_BUILD_LLVM_DYLIB) # - it pollutes the global options space. list(REMOVE_ITEM LIB_NAMES "LLVMTableGen") + # OHOS_LOCAL begin + foreach(target ${LLVM_TARGETS_TO_BUILD}) + get_property(target_link_components TARGET ${target} PROPERTY LLVM_LINK_COMPONENTS) + set(objects "") + foreach(component ${target_link_components}) + list(REMOVE_ITEM LIB_NAMES "LLVM${component}") + list(APPEND objects "$") + endforeach() + add_llvm_library("LLVM${target}Target" + MODULE + DISABLE_LLVM_LINK_LLVM_DYLIB + ${INSTALL_WITH_TOOLCHAIN} + OBJLIBS ${objects}) + + endforeach() + # OHOS_LOCAL end + if(LLVM_DYLIB_EXPORTED_SYMBOL_FILE) set(LLVM_EXPORTED_SYMBOL_FILE ${LLVM_DYLIB_EXPORTED_SYMBOL_FILE}) add_custom_target(libLLVMExports DEPENDS ${LLVM_EXPORTED_SYMBOL_FILE}) endif() - if (LLVM_LINK_LLVM_DYLIB) - set(INSTALL_WITH_TOOLCHAIN INSTALL_WITH_TOOLCHAIN) - endif() add_llvm_library(LLVM SHARED DISABLE_LLVM_LINK_LLVM_DYLIB SONAME ${INSTALL_WITH_TOOLCHAIN} ${SOURCES}) + # OHOS_LOCAL + target_compile_definitions(LLVM PRIVATE "LLVM_BUILD_BACKEND_MODULE") list(REMOVE_DUPLICATES LIB_NAMES) if(("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux") OR (MINGW) OR (HAIKU) @@ -64,6 +85,11 @@ if(LLVM_BUILD_LLVM_DYLIB) endif() target_link_libraries(LLVM PRIVATE ${LIB_NAMES}) + # OHOS_LOCAL begin + foreach(target ${LLVM_TARGETS_TO_BUILD}) + add_dependencies(LLVM LLVM${target}Target) + endforeach() + # OHOS_LOCAL end if (APPLE) set_property(TARGET LLVM APPEND_STRING PROPERTY diff --git a/llvm/tools/llvm-shlib/libllvm.cpp b/llvm/tools/llvm-shlib/libllvm.cpp index 51abeb79ad96e6febc729538cc23289adcd8744d..6b8792b4e74490cfa1e731b450a166791d88216d 100644 --- a/llvm/tools/llvm-shlib/libllvm.cpp +++ b/llvm/tools/llvm-shlib/libllvm.cpp @@ -6,7 +6,54 @@ // //===----------------------------------------------------------------------===// // -// This file is empty and serves only the purpose of making CMake happy because -// you can't define a target with no sources. // //===----------------------------------------------------------------------===// +// OHOS_LOCAL begin +#ifdef LLVM_BUILD_BACKEND_MODULE + +#include +#include + +static void * LoadTargetModule(const char *Target) { + char SharedObjectName[100]; + void *Handle; + + snprintf(SharedObjectName, 100, "LLVM%sTarget.so", Target); + Handle = dlopen(SharedObjectName, RTLD_LAZY | RTLD_NOLOAD); + if (!Handle) { + Handle = dlopen(SharedObjectName, RTLD_LAZY); + } + + return Handle; +} + +extern "C" { + +#define LLVM_INIT_FUNC(TargetName, Component) \ + void LLVMInitialize##TargetName##Component(void) { \ + void *Handle = LoadTargetModule(#TargetName); \ + if (!Handle) \ + return; \ + void (*InitFunc)(void) = (void (*)())(dlsym(Handle, "LLVMInitialize"#TargetName #Component)); \ + if (!InitFunc) { \ + return; \ + } \ + InitFunc(); \ + } + + +#define LLVM_TARGET(TargetName) \ + LLVM_INIT_FUNC(TargetName, Target) \ + LLVM_INIT_FUNC(TargetName, TargetInfo) \ + LLVM_INIT_FUNC(TargetName, TargetMC) \ + LLVM_INIT_FUNC(TargetName, TargetMCA) \ + LLVM_INIT_FUNC(TargetName, AsmParser) \ + LLVM_INIT_FUNC(TargetName, AsmPrinter) \ + LLVM_INIT_FUNC(TargetName, Disassembler) +#include "llvm/Config/Targets.def" +#undef LLVM_TARGET + +} + +#endif +// OHOS_LOCAL end