From 57ef51a040ed1efa68640c60dc52209a6202a04b Mon Sep 17 00:00:00 2001 From: Owen Anderson Date: Wed, 20 Aug 2025 17:38:24 +0800 Subject: [PATCH] [CHERIoT] Wire up enough driver support to be able to successfully infer -mabi=cheriot from the cheriotrtos OS field in the triple. --- clang/lib/Driver/ToolChains/Arch/RISCV.cpp | 56 ++++++---------------- llvm/lib/TargetParser/RISCVISAInfo.cpp | 2 + 2 files changed, 17 insertions(+), 41 deletions(-) diff --git a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp index 19c1445a8e72c..89fed43cde286 100644 --- a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp +++ b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp @@ -63,6 +63,8 @@ static bool isCheriPurecapABIName(StringRef ABI) { .Case("l64pc128", true) .Case("l64pc128f", true) .Case("l64pc128d", true) + .Case("cheriot", true) + .Case("cheriot-baremetal", true) .Default(false); } @@ -205,8 +207,12 @@ void riscv::getRISCVTargetFeatures(const Driver &D, const llvm::Triple &Triple, options::OPT_m_riscv_Features_Group); if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) { - bool IsPureCapability = isCheriPurecapABIName(A->getValue()); - if (IsPureCapability) { + StringRef ABI = A->getValue(); + bool IsPureCapability = isCheriPurecapABIName(ABI); + if (ABI == "cheriot" || ABI == "cheriot-baremetal") { + // +xcheriot implies both +xcheri and +xcheripurecap + Features.push_back("+xcheriot"); + } else if (IsPureCapability) { auto ISAInfo = llvm::RISCVISAInfo::parseFeatures( Triple.isArch32Bit() ? 32 : 64, std::vector(Features.begin(), Features.end())); @@ -224,42 +230,6 @@ void riscv::getRISCVTargetFeatures(const Driver &D, const llvm::Triple &Triple, } } - if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) { - bool IsPureCapability = isCheriPurecapABIName(A->getValue()); - if (IsPureCapability) { - if (llvm::find(Features, "+xcheri") == Features.end()) { - D.Diag(diag::err_riscv_invalid_abi) << A->getValue() - << "pure capability ABI requires xcheri extension to be specified"; - return; - } - Features.push_back("+xcheripurecap"); - } - } - - if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) { - bool IsPureCapability = isCheriPurecapABIName(A->getValue()); - if (IsPureCapability) { - if (llvm::find(Features, "+xcheri") == Features.end()) { - D.Diag(diag::err_riscv_invalid_abi) << A->getValue() - << "pure capability ABI requires xcheri extension to be specified"; - return; - } - Features.push_back("+xcheripurecap"); - } - } - - if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) { - bool IsPureCapability = isCheriPurecapABIName(A->getValue()); - if (IsPureCapability) { - if (llvm::find(Features, "+xcheri") == Features.end()) { - D.Diag(diag::err_riscv_invalid_abi) << A->getValue() - << "pure capability ABI requires xcheri extension to be specified"; - return; - } - Features.push_back("+xcheripurecap"); - } - } - // If -mstrict-align, -mno-strict-align, -mscalar-strict-align, or // -mno-scalar-strict-align is passed, use it. Otherwise, the // unaligned-scalar-mem is enabled if the CPU supports it or the target is @@ -356,6 +326,8 @@ StringRef riscv::getRISCVABI(const ArgList &Args, const llvm::Triple &Triple) { // - On `riscv{XLEN}-unknown-elf` we use the integer calling convention only. // - On all other OSs we use the double floating point calling convention. if (Triple.isRISCV32()) { + if (Triple.getOS() == llvm::Triple::CheriotRTOS) + return "cheriot"; if (Triple.getOS() == llvm::Triple::UnknownOS) return "ilp32"; else @@ -457,8 +429,9 @@ std::string riscv::getRISCVArch(const llvm::opt::ArgList &Args, // We deviate from GCC's defaults here: // - 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.getSubArch() == llvm::Triple::RISCV32SubArch_cheriot_v1) - return "rv32emc_xcheri"; + if (Triple.getSubArch() == llvm::Triple::RISCV32SubArch_cheriot_v1 || + Triple.getOS() == llvm::Triple::CheriotRTOS) + return "rv32emc_xcheriot"; if (Triple.isRISCV32()) { if (Triple.getOS() == llvm::Triple::UnknownOS) return "rv32imac"; @@ -488,7 +461,8 @@ std::string riscv::getRISCVTargetCPU(const llvm::opt::ArgList &Args, if (!CPU.empty()) return CPU; - if (Triple.getSubArch() == llvm::Triple::RISCV32SubArch_cheriot_v1) + if (Triple.getOS() == llvm::Triple::CheriotRTOS || + Triple.getSubArch() == llvm::Triple::RISCV32SubArch_cheriot_v1) return "cheriot"; return Triple.isRISCV64() ? "generic-rv64" : "generic-rv32"; diff --git a/llvm/lib/TargetParser/RISCVISAInfo.cpp b/llvm/lib/TargetParser/RISCVISAInfo.cpp index 17b8c2ac77307..5d012888740a9 100644 --- a/llvm/lib/TargetParser/RISCVISAInfo.cpp +++ b/llvm/lib/TargetParser/RISCVISAInfo.cpp @@ -957,6 +957,8 @@ RISCVISAInfo::postProcessAndChecking(std::unique_ptr &&ISAInfo) { StringRef RISCVISAInfo::computeDefaultABI() const { if (XLen == 32) { + if (Exts.count("xcheriot")) + return "cheriot"; if (Exts.count("e")) return "ilp32e"; if (Exts.count("d"))