From fab8f945246e12849de2cb0c35ede4c04096ccf8 Mon Sep 17 00:00:00 2001 From: zeshanpeng Date: Mon, 29 Apr 2024 13:42:02 -0400 Subject: [PATCH] [XVM] Generate the dynamic library of the new XVM target Description: A new LLVM backend named XVM is to be added into LLVM. This includes the basic XVM framework and the approach to build the XVM dynamic library to make the XVM target as plugable. The backend implementation of the XVM target is not included here. The corresponding issue is here: https://gitee.com/openharmony/third_party_llvm-project/issues/I9MSPC Signed-off-by: zeshanpeng --- clang/include/clang/Basic/Attr.td | 12 + clang/lib/Basic/CMakeLists.txt | 2 + clang/lib/Basic/Targets.cpp | 6 + clang/lib/Basic/Targets/XVM.cpp | 46 ++ clang/lib/Basic/Targets/XVM.h | 89 ++++ clang/lib/CodeGen/TargetInfo.cpp | 107 ++++ clang/lib/Driver/CMakeLists.txt | 2 + clang/lib/Driver/Driver.cpp | 7 + clang/lib/Driver/ToolChains/CommonArgs.cpp | 7 + clang/lib/Driver/ToolChains/Gnu.cpp | 2 + clang/lib/Driver/ToolChains/XVMToolchain.cpp | 201 ++++++++ clang/lib/Driver/ToolChains/XVMToolchain.h | 74 +++ clang/lib/Sema/SemaDeclAttr.cpp | 23 + clang/test/CodeGen/XVM/xvm-export-name.c | 8 + ...a-attribute-supported-attributes-list.test | 1 + lld/ELF/Driver.cpp | 2 + lld/ELF/InputFiles.cpp | 4 + llvm/CMakeLists.txt | 2 + llvm/include/llvm/ADT/Triple.h | 2 + llvm/include/llvm/BinaryFormat/ELF.h | 9 + .../llvm/BinaryFormat/ELFRelocs/XVM.def | 11 + llvm/include/llvm/Object/ELFObjectFile.h | 9 + llvm/lib/Object/ELF.cpp | 7 + llvm/lib/Support/Triple.cpp | 19 + llvm/lib/Target/XVM/CMakeLists.txt | 58 +++ .../Target/XVM/MCTargetDesc/CMakeLists.txt | 18 + .../XVM/MCTargetDesc/XVMInstPrinter.cpp | 15 + .../Target/XVM/MCTargetDesc/XVMInstPrinter.h | 46 ++ .../Target/XVM/MCTargetDesc/XVMMCAsmInfo.h | 55 +++ .../XVM/MCTargetDesc/XVMMCTargetDesc.cpp | 23 + .../Target/XVM/MCTargetDesc/XVMMCTargetDesc.h | 48 ++ .../XVM/MCTargetDesc/XVMTargetStreamer.cpp | 15 + .../XVM/MCTargetDesc/XVMTargetStreamer.h | 30 ++ llvm/lib/Target/XVM/TargetInfo/CMakeLists.txt | 15 + .../Target/XVM/TargetInfo/XVMTargetInfo.cpp | 22 + .../lib/Target/XVM/TargetInfo/XVMTargetInfo.h | 21 + llvm/lib/Target/XVM/XVM.h | 36 ++ llvm/lib/Target/XVM/XVM.td | 48 ++ llvm/lib/Target/XVM/XVMAsmPrinter.cpp | 24 + llvm/lib/Target/XVM/XVMCFGSort.cpp | 21 + llvm/lib/Target/XVM/XVMCFGStackify.cpp | 26 + llvm/lib/Target/XVM/XVMCFGStructure.cpp | 4 + llvm/lib/Target/XVM/XVMCallingConv.td | 35 ++ llvm/lib/Target/XVM/XVMDylibHandler.h | 49 ++ llvm/lib/Target/XVM/XVMExpandPseudoInsts.cpp | 4 + llvm/lib/Target/XVM/XVMFrameLowering.cpp | 15 + llvm/lib/Target/XVM/XVMFrameLowering.h | 48 ++ llvm/lib/Target/XVM/XVMISelDAGToDAG.cpp | 16 + llvm/lib/Target/XVM/XVMISelLowering.cpp | 17 + llvm/lib/Target/XVM/XVMISelLowering.h | 154 ++++++ llvm/lib/Target/XVM/XVMInstrBulkMemory.td | 78 +++ llvm/lib/Target/XVM/XVMInstrFormats.td | 155 ++++++ llvm/lib/Target/XVM/XVMInstrInfo.cpp | 16 + llvm/lib/Target/XVM/XVMInstrInfo.h | 86 ++++ llvm/lib/Target/XVM/XVMInstrInfo.td | 461 ++++++++++++++++++ llvm/lib/Target/XVM/XVMMCInstLower.cpp | 16 + llvm/lib/Target/XVM/XVMMCInstLower.h | 41 ++ llvm/lib/Target/XVM/XVMMachineFunctionInfo.h | 20 + llvm/lib/Target/XVM/XVMRegisterInfo.cpp | 15 + llvm/lib/Target/XVM/XVMRegisterInfo.h | 45 ++ llvm/lib/Target/XVM/XVMRegisterInfo.td | 33 ++ llvm/lib/Target/XVM/XVMSelectionDAGInfo.cpp | 15 + llvm/lib/Target/XVM/XVMSelectionDAGInfo.h | 44 ++ llvm/lib/Target/XVM/XVMSortRegion.cpp | 4 + llvm/lib/Target/XVM/XVMSortRegion.h | 82 ++++ llvm/lib/Target/XVM/XVMSubtarget.cpp | 15 + llvm/lib/Target/XVM/XVMSubtarget.h | 69 +++ llvm/lib/Target/XVM/XVMTargetMachine.cpp | 24 + llvm/lib/Target/XVM/XVMTargetMachine.h | 45 ++ llvm/lib/Target/XVM/XVMTargetTransformInfo.h | 87 ++++ .../lib/Target/XVM/XVMUpdateRefInstrForMI.cpp | 4 + llvm/lib/Target/XVM/XVM_def.h | 68 +++ llvm/tools/llvm-shlib/CMakeLists.txt | 32 +- llvm/tools/llvm-shlib/libllvm.cpp | 51 +- 74 files changed, 3016 insertions(+), 5 deletions(-) create mode 100644 clang/lib/Basic/Targets/XVM.cpp create mode 100644 clang/lib/Basic/Targets/XVM.h create mode 100644 clang/lib/Driver/ToolChains/XVMToolchain.cpp create mode 100644 clang/lib/Driver/ToolChains/XVMToolchain.h create mode 100644 clang/test/CodeGen/XVM/xvm-export-name.c create mode 100644 llvm/include/llvm/BinaryFormat/ELFRelocs/XVM.def create mode 100644 llvm/lib/Target/XVM/CMakeLists.txt create mode 100644 llvm/lib/Target/XVM/MCTargetDesc/CMakeLists.txt create mode 100644 llvm/lib/Target/XVM/MCTargetDesc/XVMInstPrinter.cpp create mode 100644 llvm/lib/Target/XVM/MCTargetDesc/XVMInstPrinter.h create mode 100644 llvm/lib/Target/XVM/MCTargetDesc/XVMMCAsmInfo.h create mode 100644 llvm/lib/Target/XVM/MCTargetDesc/XVMMCTargetDesc.cpp create mode 100644 llvm/lib/Target/XVM/MCTargetDesc/XVMMCTargetDesc.h create mode 100644 llvm/lib/Target/XVM/MCTargetDesc/XVMTargetStreamer.cpp create mode 100644 llvm/lib/Target/XVM/MCTargetDesc/XVMTargetStreamer.h create mode 100644 llvm/lib/Target/XVM/TargetInfo/CMakeLists.txt create mode 100644 llvm/lib/Target/XVM/TargetInfo/XVMTargetInfo.cpp create mode 100644 llvm/lib/Target/XVM/TargetInfo/XVMTargetInfo.h create mode 100644 llvm/lib/Target/XVM/XVM.h create mode 100644 llvm/lib/Target/XVM/XVM.td create mode 100644 llvm/lib/Target/XVM/XVMAsmPrinter.cpp create mode 100644 llvm/lib/Target/XVM/XVMCFGSort.cpp create mode 100644 llvm/lib/Target/XVM/XVMCFGStackify.cpp create mode 100644 llvm/lib/Target/XVM/XVMCFGStructure.cpp create mode 100644 llvm/lib/Target/XVM/XVMCallingConv.td create mode 100644 llvm/lib/Target/XVM/XVMDylibHandler.h create mode 100644 llvm/lib/Target/XVM/XVMExpandPseudoInsts.cpp create mode 100644 llvm/lib/Target/XVM/XVMFrameLowering.cpp create mode 100644 llvm/lib/Target/XVM/XVMFrameLowering.h create mode 100644 llvm/lib/Target/XVM/XVMISelDAGToDAG.cpp create mode 100644 llvm/lib/Target/XVM/XVMISelLowering.cpp create mode 100644 llvm/lib/Target/XVM/XVMISelLowering.h create mode 100644 llvm/lib/Target/XVM/XVMInstrBulkMemory.td create mode 100644 llvm/lib/Target/XVM/XVMInstrFormats.td create mode 100644 llvm/lib/Target/XVM/XVMInstrInfo.cpp create mode 100644 llvm/lib/Target/XVM/XVMInstrInfo.h create mode 100644 llvm/lib/Target/XVM/XVMInstrInfo.td create mode 100644 llvm/lib/Target/XVM/XVMMCInstLower.cpp create mode 100644 llvm/lib/Target/XVM/XVMMCInstLower.h create mode 100644 llvm/lib/Target/XVM/XVMMachineFunctionInfo.h create mode 100644 llvm/lib/Target/XVM/XVMRegisterInfo.cpp create mode 100644 llvm/lib/Target/XVM/XVMRegisterInfo.h create mode 100644 llvm/lib/Target/XVM/XVMRegisterInfo.td create mode 100644 llvm/lib/Target/XVM/XVMSelectionDAGInfo.cpp create mode 100644 llvm/lib/Target/XVM/XVMSelectionDAGInfo.h create mode 100644 llvm/lib/Target/XVM/XVMSortRegion.cpp create mode 100644 llvm/lib/Target/XVM/XVMSortRegion.h create mode 100644 llvm/lib/Target/XVM/XVMSubtarget.cpp create mode 100644 llvm/lib/Target/XVM/XVMSubtarget.h create mode 100644 llvm/lib/Target/XVM/XVMTargetMachine.cpp create mode 100644 llvm/lib/Target/XVM/XVMTargetMachine.h create mode 100644 llvm/lib/Target/XVM/XVMTargetTransformInfo.h create mode 100644 llvm/lib/Target/XVM/XVMUpdateRefInstrForMI.cpp create mode 100644 llvm/lib/Target/XVM/XVM_def.h diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index 7416f4757f8c..4b1c89039d90 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 3e052c0cf995..ff83f9963535 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 d2eac5cae7b6..4a136b1c3e39 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 000000000000..6e61b363303d --- /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 000000000000..d5ef06081cf5 --- /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 3e667abc6f1c..2de773e38519 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 7be7f959e896..00da647e4c66 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 cbd2ff494de9..4717ae56d3a7 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 d20aa1390f0b..6e7fccf89871 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 f8dfb189eaf6..e320fee08547 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 000000000000..bae9da13d095 --- /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 000000000000..68059a7eb6e9 --- /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 ed6d1cc923cc..00120cc54c4b 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 000000000000..916510f0c51a --- /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 6192296477c5..1a5775f4e14b 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 abcc8a984a65..185757ad8c29 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 473809b05e9c..ba317d1e4bb0 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 2bbdfcae6ae8..34c1f19a9f95 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 72657016efcf..a021f862c4db 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 556fe9c6a1a0..234c946b2014 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 000000000000..1c32c326dfe8 --- /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 ed2f70b0da25..f50e34e1d6a5 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 0d5aa91c1348..3139ca3c6dcb 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 d163bcff0d3f..8acfe4c47ce7 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 000000000000..0f5ef89440fd --- /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 000000000000..04738c3f0a8c --- /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 000000000000..cf1caaffbc81 --- /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 000000000000..33e8860810f0 --- /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 000000000000..315124b5ba44 --- /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 000000000000..2415d5f19aee --- /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 000000000000..cd9b2f2ef307 --- /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 000000000000..872e3efb4fd9 --- /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 000000000000..1fdca9958f25 --- /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 000000000000..aad77bae6d27 --- /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 000000000000..0af0638eeab1 --- /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 000000000000..c1fb33bc46b6 --- /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 000000000000..83077088c596 --- /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 000000000000..b628c087985c --- /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 000000000000..4632e3e1eace --- /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 000000000000..69f8ba27a859 --- /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 000000000000..38b63c09a5e1 --- /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 000000000000..9427a2f4b6b7 --- /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 000000000000..c4ae32d20471 --- /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 000000000000..b097450f1e07 --- /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 000000000000..9427a2f4b6b7 --- /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 000000000000..e85115bef43f --- /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 000000000000..fe1a24937134 --- /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 000000000000..ce5114d51d0f --- /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 000000000000..c6c08fda9a30 --- /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 000000000000..e631e358d278 --- /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 000000000000..1bf037fc348b --- /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 000000000000..a28ebdd293df --- /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 000000000000..aaeaca5c7e03 --- /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 000000000000..6e51f3969687 --- /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 000000000000..8bb08ae9ac94 --- /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 000000000000..6414a7de94ea --- /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 000000000000..aa2a165b0cc6 --- /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 000000000000..ac3ff3ac2104 --- /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 000000000000..2be5295ec007 --- /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 000000000000..2a5221d08a11 --- /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 000000000000..5b7dfa12a22a --- /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 000000000000..a681b7bea5b1 --- /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 000000000000..7cc229c58d9a --- /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 000000000000..dc79f12b0bc0 --- /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 000000000000..41929766eb3a --- /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 000000000000..63b5b636d7a3 --- /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 000000000000..643b03528b10 --- /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 000000000000..0320e7a770ba --- /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 000000000000..3b25b0f1e89a --- /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 000000000000..2194866b6ab0 --- /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 000000000000..9427a2f4b6b7 --- /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 000000000000..ac0910a01792 --- /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 9043b2014ffe..f48196378489 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 51abeb79ad96..6b8792b4e744 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 -- Gitee