-
Notifications
You must be signed in to change notification settings - Fork 12.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[RISC-V] Add support for MIPS P8700 CPU #117865
base: main
Are you sure you want to change the base?
Conversation
@llvm/pr-subscribers-clang @llvm/pr-subscribers-llvm-globalisel Author: Djordje Todorovic (djtodoro) ChangesThe P8700 is a high-performance processor from MIPS designed to meet the demands of modern workloads, offering exceptional scalability and efficiency. It builds on MIPS's established architectural strengths while introducing enhancements that set it apart. For more details, you can check out the official product page here: https://mips.com/products/hardware/p8700/. RFC: TODO Patch is 143.83 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/117865.diff 48 Files Affected:
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index e5f2fec88706d8..822ead08392734 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -4937,6 +4937,11 @@ def msave_restore : Flag<["-"], "msave-restore">, Group<m_riscv_Features_Group>,
def mno_save_restore : Flag<["-"], "mno-save-restore">, Group<m_riscv_Features_Group>,
HelpText<"Disable using library calls for save and restore">;
} // let Flags = [TargetSpecific]
+def mload_store_pairs : Flag<["-"], "mload-store-pairs">, Group<m_riscv_Features_Group>;
+def mno_load_store_pairs : Flag<["-"], "mno-load-store-pairs">, Group<m_riscv_Features_Group>;
+def mccmov : Flag<["-"], "mccmov">, Group<m_riscv_Features_Group>;
+def mno_ccmov : Flag<["-"], "mno-ccmov">, Group<m_riscv_Features_Group>;
+def mremove_back_to_back_branches : Flag<["-"], "mremove_back_to_back_branches">, Group<m_riscv_Features_Group>;
let Flags = [TargetSpecific] in {
def menable_experimental_extensions : Flag<["-"], "menable-experimental-extensions">, Group<m_Group>,
HelpText<"Enable use of experimental RISC-V extensions.">;
diff --git a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
index 6935904a24edbf..7a2408477e2d7b 100644
--- a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
+++ b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
@@ -336,12 +336,14 @@ std::string riscv::getRISCVArch(const llvm::opt::ArgList &Args,
// - On `riscv{XLEN}-unknown-elf` we default to `rv{XLEN}imac`
// - On all other OSs we use `rv{XLEN}imafdc` (equivalent to `rv{XLEN}gc`)
if (Triple.isRISCV32()) {
- if (Triple.getOS() == llvm::Triple::UnknownOS)
+ if (Triple.getOS() == llvm::Triple::UnknownOS &&
+ Triple.getVendor() != llvm::Triple::MipsTechnologies)
return "rv32imac";
else
return "rv32imafdc";
} else {
- if (Triple.getOS() == llvm::Triple::UnknownOS)
+ if (Triple.getOS() == llvm::Triple::UnknownOS &&
+ Triple.getVendor() != llvm::Triple::MipsTechnologies)
return "rv64imac";
else if (Triple.isAndroid())
return "rv64imafdcv_zba_zbb_zbs";
@@ -364,5 +366,9 @@ std::string riscv::getRISCVTargetCPU(const llvm::opt::ArgList &Args,
if (!CPU.empty())
return CPU;
+ if (Triple.getVendor() == llvm::Triple::MipsTechnologies &&
+ Triple.isRISCV64())
+ return "p8700";
+
return Triple.isRISCV64() ? "generic-rv64" : "generic-rv32";
}
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index d3eec9fea0d498..a2887fe49d940d 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -2164,6 +2164,25 @@ void Clang::AddRISCVTargetArgs(const ArgList &Args,
CmdArgs.push_back(A->getValue());
}
+ if (Arg *A = Args.getLastArg(options::OPT_mload_store_pairs,
+ options::OPT_mno_load_store_pairs)) {
+ if (A->getOption().matches(options::OPT_mload_store_pairs)) {
+ CmdArgs.push_back("-mllvm");
+ CmdArgs.push_back("-riscv-load-store-pairs=1");
+ }
+ }
+
+ if (Arg *A = Args.getLastArg(options::OPT_mccmov,
+ options::OPT_mno_ccmov)) {
+ if (A->getOption().matches(options::OPT_mno_ccmov)) {
+ CmdArgs.push_back("-mllvm");
+ CmdArgs.push_back("-riscv-ccmov=0");
+ }
+ }
+ if (Args.getLastArg(options::OPT_mremove_back_to_back_branches)) {
+ CmdArgs.push_back("-mllvm");
+ CmdArgs.push_back("-riscv-remove-back-to-back-branches=1");
+ }
// Handle -mrvv-vector-bits=<bits>
if (Arg *A = Args.getLastArg(options::OPT_mrvv_vector_bits_EQ)) {
StringRef Val = A->getValue();
diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp
index 8397f1121ec2ce..b404b7ab07894b 100644
--- a/clang/lib/Driver/ToolChains/Gnu.cpp
+++ b/clang/lib/Driver/ToolChains/Gnu.cpp
@@ -252,9 +252,18 @@ static const char *getLDMOption(const llvm::Triple &T, const ArgList &Args) {
case llvm::Triple::ppc64le:
return "elf64lppc";
case llvm::Triple::riscv32:
- return "elf32lriscv";
case llvm::Triple::riscv64:
- return "elf64lriscv";
+ {
+ bool IsBigEndian = false;
+ if (Arg *A = Args.getLastArg(options::OPT_mlittle_endian,
+ options::OPT_mbig_endian))
+ IsBigEndian = A->getOption().matches(options::OPT_mbig_endian);
+
+ if (T.getArch() == llvm::Triple::riscv32)
+ return IsBigEndian ? "elf32briscv" : "elf32lriscv";
+ else
+ return IsBigEndian ? "elf64briscv" : "elf64lriscv";
+ }
case llvm::Triple::sparc:
case llvm::Triple::sparcel:
return "elf32_sparc";
@@ -402,6 +411,14 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back(Arch == llvm::Triple::aarch64_be ? "-EB" : "-EL");
}
+ if (Triple.isRISCV() &&
+ Triple.getVendor() == llvm::Triple::MipsTechnologies) {
+ bool IsBigEndian = false;
+ if (Arg *A = Args.getLastArg(options::OPT_mlittle_endian,
+ options::OPT_mbig_endian))
+ IsBigEndian = A->getOption().matches(options::OPT_mbig_endian);
+ CmdArgs.push_back(IsBigEndian ? "-EB" : "-EL");
+ }
// Most Android ARM64 targets should enable the linker fix for erratum
// 843419. Only non-Cortex-A53 devices are allowed to skip this flag.
if (Arch == llvm::Triple::aarch64 && (isAndroid || isOHOSFamily)) {
@@ -765,7 +782,8 @@ void tools::gnutools::Assembler::ConstructJob(Compilation &C,
}
case llvm::Triple::riscv32:
case llvm::Triple::riscv64: {
- StringRef ABIName = riscv::getRISCVABI(Args, getToolChain().getTriple());
+ const llvm::Triple &Triple = getToolChain().getTriple();
+ StringRef ABIName = riscv::getRISCVABI(Args, Triple);
CmdArgs.push_back("-mabi");
CmdArgs.push_back(ABIName.data());
std::string MArchName =
@@ -774,6 +792,14 @@ void tools::gnutools::Assembler::ConstructJob(Compilation &C,
CmdArgs.push_back(Args.MakeArgString(MArchName));
if (!Args.hasFlag(options::OPT_mrelax, options::OPT_mno_relax, true))
Args.addOptOutFlag(CmdArgs, options::OPT_mrelax, options::OPT_mno_relax);
+
+ if (Triple.getVendor() == llvm::Triple::MipsTechnologies) {
+ bool IsBigEndian = false;
+ if (Arg *A = Args.getLastArg(options::OPT_mlittle_endian,
+ options::OPT_mbig_endian))
+ IsBigEndian = A->getOption().matches(options::OPT_mbig_endian);
+ CmdArgs.push_back(IsBigEndian ? "-EB" : "-EL");
+ }
break;
}
case llvm::Triple::sparc:
@@ -1873,9 +1899,18 @@ static void findRISCVBareMetalMultilibs(const Driver &D,
.flag(Twine("-march=", Element.march).str())
.flag(Twine("-mabi=", Element.mabi).str()));
}
+ SmallVector<MultilibBuilder, 2> Endian;
+ if (TargetTriple.getVendor() == llvm::Triple::MipsTechnologies) {
+ Endian.push_back(
+ MultilibBuilder("/riscv").flag("-EL").flag("-EB", /*Disallow=*/true));
+ Endian.push_back(
+ MultilibBuilder("/riscveb").flag("-EB").flag("-EL", /*Disallow=*/true));
+ }
MultilibSet RISCVMultilibs =
MultilibSetBuilder()
.Either(Ms)
+ .Either(Endian)
+ .Either(ArrayRef<MultilibBuilder>(Ms))
.makeMultilibSet()
.FilterOut(NonExistent)
.setFilePathsCallback([](const Multilib &M) {
@@ -1899,6 +1934,19 @@ static void findRISCVBareMetalMultilibs(const Driver &D,
}
}
+ bool IsBigEndian = false;
+ if (Arg *A = Args.getLastArg(options::OPT_mlittle_endian,
+ options::OPT_mbig_endian))
+ IsBigEndian = A->getOption().matches(options::OPT_mbig_endian);
+
+ if (IsBigEndian) {
+ D.Diag(diag::err_drv_unsupported_opt_for_target)
+ << "-EB" << TargetTriple.str();
+ }
+
+ addMultilibFlag(IsBigEndian, "-EB", Flags);
+ addMultilibFlag(!IsBigEndian, "-EL", Flags);
+
if (selectRISCVMultilib(D, RISCVMultilibs, MArch, Flags,
Result.SelectedMultilibs))
Result.Multilibs = RISCVMultilibs;
@@ -1923,8 +1971,18 @@ static void findRISCVMultilibs(const Driver &D,
MultilibBuilder("lib64/lp64f").flag("-m64").flag("-mabi=lp64f");
MultilibBuilder Lp64d =
MultilibBuilder("lib64/lp64d").flag("-m64").flag("-mabi=lp64d");
+
+ SmallVector<MultilibBuilder, 2> Endian;
+ if (TargetTriple.getVendor() == llvm::Triple::MipsTechnologies) {
+ Endian.push_back(
+ MultilibBuilder("/riscv").flag("-EL").flag("-EB", /*Disallow=*/true));
+ Endian.push_back(
+ MultilibBuilder("/riscveb").flag("-EB").flag("-EL", /*Disallow=*/true));
+ }
+
MultilibSet RISCVMultilibs =
MultilibSetBuilder()
+ .Either(Endian)
.Either({Ilp32, Ilp32f, Ilp32d, Lp64, Lp64f, Lp64d})
.makeMultilibSet()
.FilterOut(NonExistent);
@@ -1932,6 +1990,15 @@ static void findRISCVMultilibs(const Driver &D,
Multilib::flags_list Flags;
bool IsRV64 = TargetTriple.getArch() == llvm::Triple::riscv64;
StringRef ABIName = tools::riscv::getRISCVABI(Args, TargetTriple);
+ bool IsBigEndian = false;
+ if (Arg *A = Args.getLastArg(options::OPT_mlittle_endian,
+ options::OPT_mbig_endian))
+ IsBigEndian = A->getOption().matches(options::OPT_mbig_endian);
+
+ if (IsBigEndian) {
+ D.Diag(diag::err_drv_unsupported_opt_for_target)
+ << "-EB" << TargetTriple.str();
+ }
addMultilibFlag(!IsRV64, "-m32", Flags);
addMultilibFlag(IsRV64, "-m64", Flags);
@@ -1941,6 +2008,8 @@ static void findRISCVMultilibs(const Driver &D,
addMultilibFlag(ABIName == "lp64", "-mabi=lp64", Flags);
addMultilibFlag(ABIName == "lp64f", "-mabi=lp64f", Flags);
addMultilibFlag(ABIName == "lp64d", "-mabi=lp64d", Flags);
+ addMultilibFlag(IsBigEndian, "-EB", Flags);
+ addMultilibFlag(!IsBigEndian, "-EL", Flags);
if (RISCVMultilibs.select(D, Flags, Result.SelectedMultilibs))
Result.Multilibs = RISCVMultilibs;
@@ -2566,7 +2635,8 @@ void Generic_GCC::GCCInstallationDetector::AddDefaultGCCPrefixes(
"riscv32-unknown-elf"};
static const char *const RISCV64LibDirs[] = {"/lib64", "/lib"};
static const char *const RISCV64Triples[] = {"riscv64-unknown-linux-gnu",
- "riscv64-unknown-elf"};
+ "riscv64-unknown-elf",
+ "riscv64-mti-elf"};
static const char *const SPARCv8LibDirs[] = {"/lib32", "/lib"};
static const char *const SPARCv8Triples[] = {"sparc-linux-gnu",
@@ -3137,6 +3207,45 @@ bool Generic_GCC::IsIntegratedAssemblerDefault() const {
case llvm::Triple::nvptx64:
case llvm::Triple::xcore:
return false;
+ case llvm::Triple::aarch64:
+ case llvm::Triple::aarch64_be:
+ case llvm::Triple::amdgcn:
+ case llvm::Triple::arm:
+ case llvm::Triple::armeb:
+ case llvm::Triple::avr:
+ case llvm::Triple::bpfel:
+ case llvm::Triple::bpfeb:
+ case llvm::Triple::csky:
+ case llvm::Triple::hexagon:
+ case llvm::Triple::lanai:
+ case llvm::Triple::loongarch32:
+ case llvm::Triple::loongarch64:
+ case llvm::Triple::m68k:
+ case llvm::Triple::mips:
+ case llvm::Triple::mipsel:
+ case llvm::Triple::mips64:
+ case llvm::Triple::mips64el:
+ case llvm::Triple::msp430:
+ case llvm::Triple::ppc:
+ case llvm::Triple::ppcle:
+ case llvm::Triple::ppc64:
+ case llvm::Triple::ppc64le:
+ case llvm::Triple::r600:
+ case llvm::Triple::sparc:
+ case llvm::Triple::sparcel:
+ case llvm::Triple::sparcv9:
+ case llvm::Triple::systemz:
+ case llvm::Triple::thumb:
+ case llvm::Triple::thumbeb:
+ case llvm::Triple::ve:
+ case llvm::Triple::x86:
+ case llvm::Triple::x86_64:
+ return true;
+ case llvm::Triple::riscv32:
+ case llvm::Triple::riscv64:
+ if (getTriple().getVendor() != llvm::Triple::MipsTechnologies)
+ return true;
+ return false;
default:
return true;
}
diff --git a/clang/lib/Driver/ToolChains/Linux.cpp b/clang/lib/Driver/ToolChains/Linux.cpp
index d1cb625613415b..3759b01b436e5c 100644
--- a/clang/lib/Driver/ToolChains/Linux.cpp
+++ b/clang/lib/Driver/ToolChains/Linux.cpp
@@ -274,11 +274,13 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
const bool IsHexagon = Arch == llvm::Triple::hexagon;
const bool IsRISCV = Triple.isRISCV();
const bool IsCSKY = Triple.isCSKY();
+ const bool IsMipsSysRoot = IsMips ||
+ (IsRISCV && Triple.getVendor() == llvm::Triple::MipsTechnologies);
if (IsCSKY && !SelectedMultilibs.empty())
SysRoot = SysRoot + SelectedMultilibs.back().osSuffix();
- if ((IsMips || IsCSKY) && !SysRoot.empty())
+ if ((IsMipsSysRoot || IsCSKY) && !SysRoot.empty())
ExtraOpts.push_back("--sysroot=" + SysRoot);
// Do not use 'gnu' hash style for Mips targets because .gnu.hash
@@ -412,7 +414,11 @@ std::string Linux::computeSysRoot() const {
return std::string();
}
- if (!GCCInstallation.isValid() || !getTriple().isMIPS())
+ const bool IsMipsSysRoot = getTriple().isMIPS() ||
+ (getTriple().isRISCV() &&
+ getTriple().getVendor() == llvm::Triple::MipsTechnologies);
+
+ if (!GCCInstallation.isValid() || !IsMipsSysRoot)
return std::string();
// Standalone MIPS toolchains use different names for sysroot folder
@@ -422,8 +428,19 @@ std::string Linux::computeSysRoot() const {
const StringRef InstallDir = GCCInstallation.getInstallPath();
const StringRef TripleStr = GCCInstallation.getTriple().str();
const Multilib &Multilib = GCCInstallation.getMultilib();
+ std::string Path;
+ if (getTriple().isRISCV()) {
+ Path =
+ (InstallDir + "/../../../../sysroot" + Multilib.osSuffix() + "/../..")
+ .str();
+
+ if (getVFS().exists(Path))
+ return Path;
+
+ return std::string();
+ }
- std::string Path =
+ Path =
(InstallDir + "/../../../../" + TripleStr + "/libc" + Multilib.osSuffix())
.str();
diff --git a/clang/lib/Driver/ToolChains/RISCVToolchain.cpp b/clang/lib/Driver/ToolChains/RISCVToolchain.cpp
index 624099d21ae124..6d0e0935135dd9 100644
--- a/clang/lib/Driver/ToolChains/RISCVToolchain.cpp
+++ b/clang/lib/Driver/ToolChains/RISCVToolchain.cpp
@@ -77,7 +77,7 @@ Tool *RISCVToolChain::buildLinker() const {
}
ToolChain::RuntimeLibType RISCVToolChain::GetDefaultRuntimeLibType() const {
- return GCCInstallation.isValid() ?
+ return GCCInstallation.isValid() ?
ToolChain::RLT_Libgcc : ToolChain::RLT_CompilerRT;
}
@@ -173,6 +173,14 @@ void RISCV::Linker::ConstructJob(Compilation &C, const JobAction &JA,
}
CmdArgs.push_back("-X");
+ if (ToolChain.getTriple().getVendor() == llvm::Triple::MipsTechnologies) {
+ bool IsBigEndian = false;
+ if (Arg *A = Args.getLastArg(options::OPT_mlittle_endian,
+ options::OPT_mbig_endian))
+ IsBigEndian = A->getOption().matches(options::OPT_mbig_endian);
+ CmdArgs.push_back(IsBigEndian ? "-EB" : "-EL");
+ }
+
std::string Linker = getToolChain().GetLinkerPath();
bool WantCRTs =
@@ -229,4 +237,10 @@ void RISCV::Linker::ConstructJob(Compilation &C, const JobAction &JA,
JA, *this, ResponseFileSupport::AtFileCurCP(), Args.MakeArgString(Linker),
CmdArgs, Inputs, Output));
}
+
+bool RISCVToolChain::IsIntegratedAssemblerDefault() const {
+ if (getTriple().getVendor() != llvm::Triple::MipsTechnologies)
+ return true;
+ return false;
+}
// RISCV tools end.
diff --git a/clang/lib/Driver/ToolChains/RISCVToolchain.h b/clang/lib/Driver/ToolChains/RISCVToolchain.h
index fa0aa265d842bb..c189772cc0d0ca 100644
--- a/clang/lib/Driver/ToolChains/RISCVToolchain.h
+++ b/clang/lib/Driver/ToolChains/RISCVToolchain.h
@@ -22,6 +22,7 @@ class LLVM_LIBRARY_VISIBILITY RISCVToolChain : public Generic_ELF {
const llvm::opt::ArgList &Args);
static bool hasGCCToolchain(const Driver &D, const llvm::opt::ArgList &Args);
+ bool IsIntegratedAssemblerDefault() const override;
void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args,
Action::OffloadKind) const override;
diff --git a/clang/test/Misc/target-invalid-cpu-note/riscv.c b/clang/test/Misc/target-invalid-cpu-note/riscv.c
index 8c5df5884cd791..fc8536d99cb804 100644
--- a/clang/test/Misc/target-invalid-cpu-note/riscv.c
+++ b/clang/test/Misc/target-invalid-cpu-note/riscv.c
@@ -25,6 +25,7 @@
// RISCV64: error: unknown target CPU 'not-a-cpu'
// RISCV64-NEXT: note: valid target CPU values are:
// RISCV64-SAME: {{^}} generic-rv64
+// RISCV64-SAME: {{^}}, mips-p8700
// RISCV64-SAME: {{^}}, rocket-rv64
// RISCV64-SAME: {{^}}, sifive-p450
// RISCV64-SAME: {{^}}, sifive-p470
@@ -72,6 +73,7 @@
// TUNE-RISCV64: error: unknown target CPU 'not-a-cpu'
// TUNE-RISCV64-NEXT: note: valid target CPU values are:
// TUNE-RISCV64-SAME: {{^}} generic-rv64
+// TUNE-RISCV64-SAME: {{^}}, mips-p8700
// TUNE-RISCV64-SAME: {{^}}, rocket-rv64
// TUNE-RISCV64-SAME: {{^}}, sifive-p450
// TUNE-RISCV64-SAME: {{^}}, sifive-p470
diff --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst
index 1317221448ea5b..7fc1f1d49faf4e 100644
--- a/llvm/docs/RISCVUsage.rst
+++ b/llvm/docs/RISCVUsage.rst
@@ -423,6 +423,12 @@ The current vendor extensions supported are:
``Xwchc``
LLVM implements `the custom compressed opcodes present in some QingKe cores` by WCH / Nanjing Qinheng Microelectronics. The vendor refers to these opcodes by the name "XW".
+``xmipscmove``
+ LLVM implements conditional move for the `p8700 processor <https://mips.com/products/hardware/p8700/>` by MIPS.
+
+``xmipslsp``
+ LLVM implements load/store pair instructions for the `p8700 processor <https://mips.com/products/hardware/p8700/>` by MIPS.
+
Experimental C Intrinsics
=========================
diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index b843bb5ae43100..4edeb07a0fc980 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -855,6 +855,16 @@ struct RISCVOperand final : public MCParsedAsmOperand {
VK == RISCVMCExpr::VK_RISCV_None;
}
+ bool isUImm7Lsb000() const {
+ if (!isImm())
+ return false;
+ int64_t Imm;
+ RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
+ bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
+ return IsConstantImm && isShiftedUInt<4, 3>(Imm) &&
+ VK == RISCVMCExpr::VK_RISCV_None;
+ }
+
bool isUImm8Lsb00() const {
if (!isImm())
return false;
diff --git a/llvm/lib/Target/RISCV/CMakeLists.txt b/llvm/lib/Target/RISCV/CMakeLists.txt
index fd049d1a57860e..2f63d7f1e4c39f 100644
--- a/llvm/lib/Target/RISCV/CMakeLists.txt
+++ b/llvm/lib/Target/RISCV/CMakeLists.txt
@@ -47,6 +47,7 @@ add_llvm_target(RISCVCodeGen
RISCVISelLowering.cpp
RISCVLandingPadSetup.cpp
RISCVMachineFunctionInfo.cpp
+ RISCVLoadStoreOptimizer.cpp
RISCVMergeBaseOffset.cpp
RISCVOptWInstrs.cpp
RISCVPostRAExpandPseudoInsts.cpp
@@ -54,6 +55,7 @@ add_llvm_target(RISCVCodeGen
RISCVMoveMerger.cpp
RISCVPushPopOptimizer.cpp
RISCVRegisterInfo.cpp
+ RISCVRemoveBackToBackBranches.cpp
RISCVSubtarget.cpp
RISCVTargetMachine.cpp
RISCVTargetObjectFile.cpp
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
index 19103e219cb800..746a73b1936810 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
@@ -300,6 +300,7 @@ enum OperandType : unsigned {
OPERAND_UIMM6_LSB0,
OPERAND_UIMM7,
OPERAND_UIMM7_LSB00,
+ OPERAND_UIMM7_LSB000,
OPERAND_UIMM8_LSB00,
OPERAND_UIMM8,
OPERAND_UIMM8_LSB000,
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.cpp
index 7b927522d39549..30ad5c84e996b6 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.cpp
@@ -45,3 +45,11 @@ const MCExpr *RISCVMCAsmInfo::getExprForFDESymbol(const MCSymbol *Sym,
assert(Encoding & dwarf::DW_EH_PE_sdata4 && "Unexpected encoding");
return RISCVMCExpr::create(ME, RISCVMCExpr::VK_RISCV_32_PCREL, Ctx);
}
+
+void RISCVMCAsmInfo::setUseIntegratedAssembler(bool Value) {
+ UseIntegratedAssembler = V...
[truncated]
|
@llvm/pr-subscribers-mc Author: Djordje Todorovic (djtodoro) ChangesThe P8700 is a high-performance processor from MIPS designed to meet the demands of modern workloads, offering exceptional scalability and efficiency. It builds on MIPS's established architectural strengths while introducing enhancements that set it apart. For more details, you can check out the official product page here: https://mips.com/products/hardware/p8700/. RFC: TODO Patch is 143.83 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/117865.diff 48 Files Affected:
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index e5f2fec88706d8..822ead08392734 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -4937,6 +4937,11 @@ def msave_restore : Flag<["-"], "msave-restore">, Group<m_riscv_Features_Group>,
def mno_save_restore : Flag<["-"], "mno-save-restore">, Group<m_riscv_Features_Group>,
HelpText<"Disable using library calls for save and restore">;
} // let Flags = [TargetSpecific]
+def mload_store_pairs : Flag<["-"], "mload-store-pairs">, Group<m_riscv_Features_Group>;
+def mno_load_store_pairs : Flag<["-"], "mno-load-store-pairs">, Group<m_riscv_Features_Group>;
+def mccmov : Flag<["-"], "mccmov">, Group<m_riscv_Features_Group>;
+def mno_ccmov : Flag<["-"], "mno-ccmov">, Group<m_riscv_Features_Group>;
+def mremove_back_to_back_branches : Flag<["-"], "mremove_back_to_back_branches">, Group<m_riscv_Features_Group>;
let Flags = [TargetSpecific] in {
def menable_experimental_extensions : Flag<["-"], "menable-experimental-extensions">, Group<m_Group>,
HelpText<"Enable use of experimental RISC-V extensions.">;
diff --git a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
index 6935904a24edbf..7a2408477e2d7b 100644
--- a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
+++ b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
@@ -336,12 +336,14 @@ std::string riscv::getRISCVArch(const llvm::opt::ArgList &Args,
// - On `riscv{XLEN}-unknown-elf` we default to `rv{XLEN}imac`
// - On all other OSs we use `rv{XLEN}imafdc` (equivalent to `rv{XLEN}gc`)
if (Triple.isRISCV32()) {
- if (Triple.getOS() == llvm::Triple::UnknownOS)
+ if (Triple.getOS() == llvm::Triple::UnknownOS &&
+ Triple.getVendor() != llvm::Triple::MipsTechnologies)
return "rv32imac";
else
return "rv32imafdc";
} else {
- if (Triple.getOS() == llvm::Triple::UnknownOS)
+ if (Triple.getOS() == llvm::Triple::UnknownOS &&
+ Triple.getVendor() != llvm::Triple::MipsTechnologies)
return "rv64imac";
else if (Triple.isAndroid())
return "rv64imafdcv_zba_zbb_zbs";
@@ -364,5 +366,9 @@ std::string riscv::getRISCVTargetCPU(const llvm::opt::ArgList &Args,
if (!CPU.empty())
return CPU;
+ if (Triple.getVendor() == llvm::Triple::MipsTechnologies &&
+ Triple.isRISCV64())
+ return "p8700";
+
return Triple.isRISCV64() ? "generic-rv64" : "generic-rv32";
}
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index d3eec9fea0d498..a2887fe49d940d 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -2164,6 +2164,25 @@ void Clang::AddRISCVTargetArgs(const ArgList &Args,
CmdArgs.push_back(A->getValue());
}
+ if (Arg *A = Args.getLastArg(options::OPT_mload_store_pairs,
+ options::OPT_mno_load_store_pairs)) {
+ if (A->getOption().matches(options::OPT_mload_store_pairs)) {
+ CmdArgs.push_back("-mllvm");
+ CmdArgs.push_back("-riscv-load-store-pairs=1");
+ }
+ }
+
+ if (Arg *A = Args.getLastArg(options::OPT_mccmov,
+ options::OPT_mno_ccmov)) {
+ if (A->getOption().matches(options::OPT_mno_ccmov)) {
+ CmdArgs.push_back("-mllvm");
+ CmdArgs.push_back("-riscv-ccmov=0");
+ }
+ }
+ if (Args.getLastArg(options::OPT_mremove_back_to_back_branches)) {
+ CmdArgs.push_back("-mllvm");
+ CmdArgs.push_back("-riscv-remove-back-to-back-branches=1");
+ }
// Handle -mrvv-vector-bits=<bits>
if (Arg *A = Args.getLastArg(options::OPT_mrvv_vector_bits_EQ)) {
StringRef Val = A->getValue();
diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp
index 8397f1121ec2ce..b404b7ab07894b 100644
--- a/clang/lib/Driver/ToolChains/Gnu.cpp
+++ b/clang/lib/Driver/ToolChains/Gnu.cpp
@@ -252,9 +252,18 @@ static const char *getLDMOption(const llvm::Triple &T, const ArgList &Args) {
case llvm::Triple::ppc64le:
return "elf64lppc";
case llvm::Triple::riscv32:
- return "elf32lriscv";
case llvm::Triple::riscv64:
- return "elf64lriscv";
+ {
+ bool IsBigEndian = false;
+ if (Arg *A = Args.getLastArg(options::OPT_mlittle_endian,
+ options::OPT_mbig_endian))
+ IsBigEndian = A->getOption().matches(options::OPT_mbig_endian);
+
+ if (T.getArch() == llvm::Triple::riscv32)
+ return IsBigEndian ? "elf32briscv" : "elf32lriscv";
+ else
+ return IsBigEndian ? "elf64briscv" : "elf64lriscv";
+ }
case llvm::Triple::sparc:
case llvm::Triple::sparcel:
return "elf32_sparc";
@@ -402,6 +411,14 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back(Arch == llvm::Triple::aarch64_be ? "-EB" : "-EL");
}
+ if (Triple.isRISCV() &&
+ Triple.getVendor() == llvm::Triple::MipsTechnologies) {
+ bool IsBigEndian = false;
+ if (Arg *A = Args.getLastArg(options::OPT_mlittle_endian,
+ options::OPT_mbig_endian))
+ IsBigEndian = A->getOption().matches(options::OPT_mbig_endian);
+ CmdArgs.push_back(IsBigEndian ? "-EB" : "-EL");
+ }
// Most Android ARM64 targets should enable the linker fix for erratum
// 843419. Only non-Cortex-A53 devices are allowed to skip this flag.
if (Arch == llvm::Triple::aarch64 && (isAndroid || isOHOSFamily)) {
@@ -765,7 +782,8 @@ void tools::gnutools::Assembler::ConstructJob(Compilation &C,
}
case llvm::Triple::riscv32:
case llvm::Triple::riscv64: {
- StringRef ABIName = riscv::getRISCVABI(Args, getToolChain().getTriple());
+ const llvm::Triple &Triple = getToolChain().getTriple();
+ StringRef ABIName = riscv::getRISCVABI(Args, Triple);
CmdArgs.push_back("-mabi");
CmdArgs.push_back(ABIName.data());
std::string MArchName =
@@ -774,6 +792,14 @@ void tools::gnutools::Assembler::ConstructJob(Compilation &C,
CmdArgs.push_back(Args.MakeArgString(MArchName));
if (!Args.hasFlag(options::OPT_mrelax, options::OPT_mno_relax, true))
Args.addOptOutFlag(CmdArgs, options::OPT_mrelax, options::OPT_mno_relax);
+
+ if (Triple.getVendor() == llvm::Triple::MipsTechnologies) {
+ bool IsBigEndian = false;
+ if (Arg *A = Args.getLastArg(options::OPT_mlittle_endian,
+ options::OPT_mbig_endian))
+ IsBigEndian = A->getOption().matches(options::OPT_mbig_endian);
+ CmdArgs.push_back(IsBigEndian ? "-EB" : "-EL");
+ }
break;
}
case llvm::Triple::sparc:
@@ -1873,9 +1899,18 @@ static void findRISCVBareMetalMultilibs(const Driver &D,
.flag(Twine("-march=", Element.march).str())
.flag(Twine("-mabi=", Element.mabi).str()));
}
+ SmallVector<MultilibBuilder, 2> Endian;
+ if (TargetTriple.getVendor() == llvm::Triple::MipsTechnologies) {
+ Endian.push_back(
+ MultilibBuilder("/riscv").flag("-EL").flag("-EB", /*Disallow=*/true));
+ Endian.push_back(
+ MultilibBuilder("/riscveb").flag("-EB").flag("-EL", /*Disallow=*/true));
+ }
MultilibSet RISCVMultilibs =
MultilibSetBuilder()
.Either(Ms)
+ .Either(Endian)
+ .Either(ArrayRef<MultilibBuilder>(Ms))
.makeMultilibSet()
.FilterOut(NonExistent)
.setFilePathsCallback([](const Multilib &M) {
@@ -1899,6 +1934,19 @@ static void findRISCVBareMetalMultilibs(const Driver &D,
}
}
+ bool IsBigEndian = false;
+ if (Arg *A = Args.getLastArg(options::OPT_mlittle_endian,
+ options::OPT_mbig_endian))
+ IsBigEndian = A->getOption().matches(options::OPT_mbig_endian);
+
+ if (IsBigEndian) {
+ D.Diag(diag::err_drv_unsupported_opt_for_target)
+ << "-EB" << TargetTriple.str();
+ }
+
+ addMultilibFlag(IsBigEndian, "-EB", Flags);
+ addMultilibFlag(!IsBigEndian, "-EL", Flags);
+
if (selectRISCVMultilib(D, RISCVMultilibs, MArch, Flags,
Result.SelectedMultilibs))
Result.Multilibs = RISCVMultilibs;
@@ -1923,8 +1971,18 @@ static void findRISCVMultilibs(const Driver &D,
MultilibBuilder("lib64/lp64f").flag("-m64").flag("-mabi=lp64f");
MultilibBuilder Lp64d =
MultilibBuilder("lib64/lp64d").flag("-m64").flag("-mabi=lp64d");
+
+ SmallVector<MultilibBuilder, 2> Endian;
+ if (TargetTriple.getVendor() == llvm::Triple::MipsTechnologies) {
+ Endian.push_back(
+ MultilibBuilder("/riscv").flag("-EL").flag("-EB", /*Disallow=*/true));
+ Endian.push_back(
+ MultilibBuilder("/riscveb").flag("-EB").flag("-EL", /*Disallow=*/true));
+ }
+
MultilibSet RISCVMultilibs =
MultilibSetBuilder()
+ .Either(Endian)
.Either({Ilp32, Ilp32f, Ilp32d, Lp64, Lp64f, Lp64d})
.makeMultilibSet()
.FilterOut(NonExistent);
@@ -1932,6 +1990,15 @@ static void findRISCVMultilibs(const Driver &D,
Multilib::flags_list Flags;
bool IsRV64 = TargetTriple.getArch() == llvm::Triple::riscv64;
StringRef ABIName = tools::riscv::getRISCVABI(Args, TargetTriple);
+ bool IsBigEndian = false;
+ if (Arg *A = Args.getLastArg(options::OPT_mlittle_endian,
+ options::OPT_mbig_endian))
+ IsBigEndian = A->getOption().matches(options::OPT_mbig_endian);
+
+ if (IsBigEndian) {
+ D.Diag(diag::err_drv_unsupported_opt_for_target)
+ << "-EB" << TargetTriple.str();
+ }
addMultilibFlag(!IsRV64, "-m32", Flags);
addMultilibFlag(IsRV64, "-m64", Flags);
@@ -1941,6 +2008,8 @@ static void findRISCVMultilibs(const Driver &D,
addMultilibFlag(ABIName == "lp64", "-mabi=lp64", Flags);
addMultilibFlag(ABIName == "lp64f", "-mabi=lp64f", Flags);
addMultilibFlag(ABIName == "lp64d", "-mabi=lp64d", Flags);
+ addMultilibFlag(IsBigEndian, "-EB", Flags);
+ addMultilibFlag(!IsBigEndian, "-EL", Flags);
if (RISCVMultilibs.select(D, Flags, Result.SelectedMultilibs))
Result.Multilibs = RISCVMultilibs;
@@ -2566,7 +2635,8 @@ void Generic_GCC::GCCInstallationDetector::AddDefaultGCCPrefixes(
"riscv32-unknown-elf"};
static const char *const RISCV64LibDirs[] = {"/lib64", "/lib"};
static const char *const RISCV64Triples[] = {"riscv64-unknown-linux-gnu",
- "riscv64-unknown-elf"};
+ "riscv64-unknown-elf",
+ "riscv64-mti-elf"};
static const char *const SPARCv8LibDirs[] = {"/lib32", "/lib"};
static const char *const SPARCv8Triples[] = {"sparc-linux-gnu",
@@ -3137,6 +3207,45 @@ bool Generic_GCC::IsIntegratedAssemblerDefault() const {
case llvm::Triple::nvptx64:
case llvm::Triple::xcore:
return false;
+ case llvm::Triple::aarch64:
+ case llvm::Triple::aarch64_be:
+ case llvm::Triple::amdgcn:
+ case llvm::Triple::arm:
+ case llvm::Triple::armeb:
+ case llvm::Triple::avr:
+ case llvm::Triple::bpfel:
+ case llvm::Triple::bpfeb:
+ case llvm::Triple::csky:
+ case llvm::Triple::hexagon:
+ case llvm::Triple::lanai:
+ case llvm::Triple::loongarch32:
+ case llvm::Triple::loongarch64:
+ case llvm::Triple::m68k:
+ case llvm::Triple::mips:
+ case llvm::Triple::mipsel:
+ case llvm::Triple::mips64:
+ case llvm::Triple::mips64el:
+ case llvm::Triple::msp430:
+ case llvm::Triple::ppc:
+ case llvm::Triple::ppcle:
+ case llvm::Triple::ppc64:
+ case llvm::Triple::ppc64le:
+ case llvm::Triple::r600:
+ case llvm::Triple::sparc:
+ case llvm::Triple::sparcel:
+ case llvm::Triple::sparcv9:
+ case llvm::Triple::systemz:
+ case llvm::Triple::thumb:
+ case llvm::Triple::thumbeb:
+ case llvm::Triple::ve:
+ case llvm::Triple::x86:
+ case llvm::Triple::x86_64:
+ return true;
+ case llvm::Triple::riscv32:
+ case llvm::Triple::riscv64:
+ if (getTriple().getVendor() != llvm::Triple::MipsTechnologies)
+ return true;
+ return false;
default:
return true;
}
diff --git a/clang/lib/Driver/ToolChains/Linux.cpp b/clang/lib/Driver/ToolChains/Linux.cpp
index d1cb625613415b..3759b01b436e5c 100644
--- a/clang/lib/Driver/ToolChains/Linux.cpp
+++ b/clang/lib/Driver/ToolChains/Linux.cpp
@@ -274,11 +274,13 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
const bool IsHexagon = Arch == llvm::Triple::hexagon;
const bool IsRISCV = Triple.isRISCV();
const bool IsCSKY = Triple.isCSKY();
+ const bool IsMipsSysRoot = IsMips ||
+ (IsRISCV && Triple.getVendor() == llvm::Triple::MipsTechnologies);
if (IsCSKY && !SelectedMultilibs.empty())
SysRoot = SysRoot + SelectedMultilibs.back().osSuffix();
- if ((IsMips || IsCSKY) && !SysRoot.empty())
+ if ((IsMipsSysRoot || IsCSKY) && !SysRoot.empty())
ExtraOpts.push_back("--sysroot=" + SysRoot);
// Do not use 'gnu' hash style for Mips targets because .gnu.hash
@@ -412,7 +414,11 @@ std::string Linux::computeSysRoot() const {
return std::string();
}
- if (!GCCInstallation.isValid() || !getTriple().isMIPS())
+ const bool IsMipsSysRoot = getTriple().isMIPS() ||
+ (getTriple().isRISCV() &&
+ getTriple().getVendor() == llvm::Triple::MipsTechnologies);
+
+ if (!GCCInstallation.isValid() || !IsMipsSysRoot)
return std::string();
// Standalone MIPS toolchains use different names for sysroot folder
@@ -422,8 +428,19 @@ std::string Linux::computeSysRoot() const {
const StringRef InstallDir = GCCInstallation.getInstallPath();
const StringRef TripleStr = GCCInstallation.getTriple().str();
const Multilib &Multilib = GCCInstallation.getMultilib();
+ std::string Path;
+ if (getTriple().isRISCV()) {
+ Path =
+ (InstallDir + "/../../../../sysroot" + Multilib.osSuffix() + "/../..")
+ .str();
+
+ if (getVFS().exists(Path))
+ return Path;
+
+ return std::string();
+ }
- std::string Path =
+ Path =
(InstallDir + "/../../../../" + TripleStr + "/libc" + Multilib.osSuffix())
.str();
diff --git a/clang/lib/Driver/ToolChains/RISCVToolchain.cpp b/clang/lib/Driver/ToolChains/RISCVToolchain.cpp
index 624099d21ae124..6d0e0935135dd9 100644
--- a/clang/lib/Driver/ToolChains/RISCVToolchain.cpp
+++ b/clang/lib/Driver/ToolChains/RISCVToolchain.cpp
@@ -77,7 +77,7 @@ Tool *RISCVToolChain::buildLinker() const {
}
ToolChain::RuntimeLibType RISCVToolChain::GetDefaultRuntimeLibType() const {
- return GCCInstallation.isValid() ?
+ return GCCInstallation.isValid() ?
ToolChain::RLT_Libgcc : ToolChain::RLT_CompilerRT;
}
@@ -173,6 +173,14 @@ void RISCV::Linker::ConstructJob(Compilation &C, const JobAction &JA,
}
CmdArgs.push_back("-X");
+ if (ToolChain.getTriple().getVendor() == llvm::Triple::MipsTechnologies) {
+ bool IsBigEndian = false;
+ if (Arg *A = Args.getLastArg(options::OPT_mlittle_endian,
+ options::OPT_mbig_endian))
+ IsBigEndian = A->getOption().matches(options::OPT_mbig_endian);
+ CmdArgs.push_back(IsBigEndian ? "-EB" : "-EL");
+ }
+
std::string Linker = getToolChain().GetLinkerPath();
bool WantCRTs =
@@ -229,4 +237,10 @@ void RISCV::Linker::ConstructJob(Compilation &C, const JobAction &JA,
JA, *this, ResponseFileSupport::AtFileCurCP(), Args.MakeArgString(Linker),
CmdArgs, Inputs, Output));
}
+
+bool RISCVToolChain::IsIntegratedAssemblerDefault() const {
+ if (getTriple().getVendor() != llvm::Triple::MipsTechnologies)
+ return true;
+ return false;
+}
// RISCV tools end.
diff --git a/clang/lib/Driver/ToolChains/RISCVToolchain.h b/clang/lib/Driver/ToolChains/RISCVToolchain.h
index fa0aa265d842bb..c189772cc0d0ca 100644
--- a/clang/lib/Driver/ToolChains/RISCVToolchain.h
+++ b/clang/lib/Driver/ToolChains/RISCVToolchain.h
@@ -22,6 +22,7 @@ class LLVM_LIBRARY_VISIBILITY RISCVToolChain : public Generic_ELF {
const llvm::opt::ArgList &Args);
static bool hasGCCToolchain(const Driver &D, const llvm::opt::ArgList &Args);
+ bool IsIntegratedAssemblerDefault() const override;
void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args,
Action::OffloadKind) const override;
diff --git a/clang/test/Misc/target-invalid-cpu-note/riscv.c b/clang/test/Misc/target-invalid-cpu-note/riscv.c
index 8c5df5884cd791..fc8536d99cb804 100644
--- a/clang/test/Misc/target-invalid-cpu-note/riscv.c
+++ b/clang/test/Misc/target-invalid-cpu-note/riscv.c
@@ -25,6 +25,7 @@
// RISCV64: error: unknown target CPU 'not-a-cpu'
// RISCV64-NEXT: note: valid target CPU values are:
// RISCV64-SAME: {{^}} generic-rv64
+// RISCV64-SAME: {{^}}, mips-p8700
// RISCV64-SAME: {{^}}, rocket-rv64
// RISCV64-SAME: {{^}}, sifive-p450
// RISCV64-SAME: {{^}}, sifive-p470
@@ -72,6 +73,7 @@
// TUNE-RISCV64: error: unknown target CPU 'not-a-cpu'
// TUNE-RISCV64-NEXT: note: valid target CPU values are:
// TUNE-RISCV64-SAME: {{^}} generic-rv64
+// TUNE-RISCV64-SAME: {{^}}, mips-p8700
// TUNE-RISCV64-SAME: {{^}}, rocket-rv64
// TUNE-RISCV64-SAME: {{^}}, sifive-p450
// TUNE-RISCV64-SAME: {{^}}, sifive-p470
diff --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst
index 1317221448ea5b..7fc1f1d49faf4e 100644
--- a/llvm/docs/RISCVUsage.rst
+++ b/llvm/docs/RISCVUsage.rst
@@ -423,6 +423,12 @@ The current vendor extensions supported are:
``Xwchc``
LLVM implements `the custom compressed opcodes present in some QingKe cores` by WCH / Nanjing Qinheng Microelectronics. The vendor refers to these opcodes by the name "XW".
+``xmipscmove``
+ LLVM implements conditional move for the `p8700 processor <https://mips.com/products/hardware/p8700/>` by MIPS.
+
+``xmipslsp``
+ LLVM implements load/store pair instructions for the `p8700 processor <https://mips.com/products/hardware/p8700/>` by MIPS.
+
Experimental C Intrinsics
=========================
diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index b843bb5ae43100..4edeb07a0fc980 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -855,6 +855,16 @@ struct RISCVOperand final : public MCParsedAsmOperand {
VK == RISCVMCExpr::VK_RISCV_None;
}
+ bool isUImm7Lsb000() const {
+ if (!isImm())
+ return false;
+ int64_t Imm;
+ RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
+ bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
+ return IsConstantImm && isShiftedUInt<4, 3>(Imm) &&
+ VK == RISCVMCExpr::VK_RISCV_None;
+ }
+
bool isUImm8Lsb00() const {
if (!isImm())
return false;
diff --git a/llvm/lib/Target/RISCV/CMakeLists.txt b/llvm/lib/Target/RISCV/CMakeLists.txt
index fd049d1a57860e..2f63d7f1e4c39f 100644
--- a/llvm/lib/Target/RISCV/CMakeLists.txt
+++ b/llvm/lib/Target/RISCV/CMakeLists.txt
@@ -47,6 +47,7 @@ add_llvm_target(RISCVCodeGen
RISCVISelLowering.cpp
RISCVLandingPadSetup.cpp
RISCVMachineFunctionInfo.cpp
+ RISCVLoadStoreOptimizer.cpp
RISCVMergeBaseOffset.cpp
RISCVOptWInstrs.cpp
RISCVPostRAExpandPseudoInsts.cpp
@@ -54,6 +55,7 @@ add_llvm_target(RISCVCodeGen
RISCVMoveMerger.cpp
RISCVPushPopOptimizer.cpp
RISCVRegisterInfo.cpp
+ RISCVRemoveBackToBackBranches.cpp
RISCVSubtarget.cpp
RISCVTargetMachine.cpp
RISCVTargetObjectFile.cpp
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
index 19103e219cb800..746a73b1936810 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
@@ -300,6 +300,7 @@ enum OperandType : unsigned {
OPERAND_UIMM6_LSB0,
OPERAND_UIMM7,
OPERAND_UIMM7_LSB00,
+ OPERAND_UIMM7_LSB000,
OPERAND_UIMM8_LSB00,
OPERAND_UIMM8,
OPERAND_UIMM8_LSB000,
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.cpp
index 7b927522d39549..30ad5c84e996b6 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.cpp
@@ -45,3 +45,11 @@ const MCExpr *RISCVMCAsmInfo::getExprForFDESymbol(const MCSymbol *Sym,
assert(Encoding & dwarf::DW_EH_PE_sdata4 && "Unexpected encoding");
return RISCVMCExpr::create(ME, RISCVMCExpr::VK_RISCV_32_PCREL, Ctx);
}
+
+void RISCVMCAsmInfo::setUseIntegratedAssembler(bool Value) {
+ UseIntegratedAssembler = V...
[truncated]
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
Extensions belong in their own PRs, ditto CPU/scheduler, driver and any additional passes. Each PR is one commit and this is not one commit's worth of changes. |
@jrtc27 Yes! I agree. That is why I marked it as |
Add support for MIPS's p8700 CPU. co-authored by Nemanja Rakovic <[email protected]>
Introduce MIPS extensions by adding: 1) ccmov (+xmipscmov) 2) load/store pairs (+xmipslsp) The -mload-store-pairs imply l[w|d]p and s[w|d]p usage. The `ccmov` feature is ON by default, so we introduce an option for disabling the feature - `-mno-ccmov`. co-authored by Dragan Mladjenovic <[email protected]> co-authored by Jovan Dmitrović <[email protected]>
MipsTechnologies vendor is set up to use the p8700 processor by default. co-authored by Jovan Dmitrović <[email protected]>
Default to not using integrated as and adjust assembler output to be compatible with v0.97 gas. Rudimentary big-endian support. co-authored by Dragan Mladjenovic <[email protected]>
We see benefits in terms of performance. CoreMark benchmarking demonstrates a 2.5% performance improvement.
According to the MIPS specification, there shouldn't be two conditional branches in the same 8-byte aligned region of code.
7dea5e9
to
4f39531
Compare
// According to the MIPS specification, there shouldn't be two conditional | ||
// branches in the same 8-byte aligned region of code. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you describe this Pass in a bit more depth? The RISC-V specification doesn't have this restriction as far as I understand - is this a performance optimisation for your core, or is it required for your core to work correctly?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, I’ll describe it in more detail. To clarify, this is not a general RISC-V specification but rather a MIPS-specific requirement necessary for our core to function correctly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it's a requirement to function correctly then your core is not a RISC-V core...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will try to explain in detail why it was needed :)
Please split a3ed355 into multiple commits (and eventually PRs). One for CPU definition and one for scheduler model. |
The P8700 is a high-performance processor from MIPS designed to meet the demands of modern workloads, offering exceptional scalability and efficiency. It builds on MIPS's established architectural strengths while introducing enhancements that set it apart. For more details, you can check out the official product page here: https://mips.com/products/hardware/p8700/.
RFC: https://discourse.llvm.org/t/rfc-risc-v-add-support-for-mips-p8700-cpu/83365