Index: lib/Basic/Targets.cpp =================================================================== --- lib/Basic/Targets.cpp +++ lib/Basic/Targets.cpp @@ -377,6 +377,11 @@ if (os == llvm::Triple::Linux) return new LinuxTargetInfo(Triple, Opts); return new RISCV32TargetInfo(Triple, Opts); + case llvm::Triple::riscv32e: + // TODO: add cases for FreeBSD, NetBSD, RTEMS once tested. + if (os == llvm::Triple::Linux) + return new LinuxTargetInfo(Triple, Opts); + return new RISCV32ETargetInfo(Triple, Opts); case llvm::Triple::riscv64: // TODO: add cases for FreeBSD, NetBSD, RTEMS once tested. if (os == llvm::Triple::Linux) Index: lib/Basic/Targets/RISCV.h =================================================================== --- lib/Basic/Targets/RISCV.h +++ lib/Basic/Targets/RISCV.h @@ -83,7 +83,26 @@ bool setABI(const std::string &Name) override { // TODO: support ilp32f and ilp32d ABIs. - if (Name == "ilp32") { + if (Name == "ilp32" || Name == "ilp32e") { + ABI = Name; + return true; + } + return false; + } +}; +class LLVM_LIBRARY_VISIBILITY RISCV32ETargetInfo : public RISCVTargetInfo { +public: + RISCV32ETargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : RISCVTargetInfo(Triple, Opts) { + IntPtrType = SignedInt; + PtrDiffType = SignedInt; + SizeType = UnsignedInt; + resetDataLayout("e-m:e-p:32:32-i64:64-n32-S128"); + } + + bool setABI(const std::string &Name) override { + // TODO: support ilp32e + if (Name == "ilp32e") { ABI = Name; return true; } Index: lib/Basic/Targets/RISCV.cpp =================================================================== --- lib/Basic/Targets/RISCV.cpp +++ lib/Basic/Targets/RISCV.cpp @@ -72,10 +72,12 @@ /// Return true if has this feature, need to sync with handleTargetFeatures. bool RISCVTargetInfo::hasFeature(StringRef Feature) const { bool Is64Bit = getTriple().getArch() == llvm::Triple::riscv64; + bool IsRV32E = getTriple().getArch() == llvm::Triple::riscv32e; return llvm::StringSwitch(Feature) .Case("riscv", true) .Case("riscv32", !Is64Bit) .Case("riscv64", Is64Bit) + .Case("riscv32e", IsRV32E) .Case("m", HasM) .Case("a", HasA) .Case("f", HasF) Index: lib/CodeGen/TargetInfo.cpp =================================================================== --- lib/CodeGen/TargetInfo.cpp +++ lib/CodeGen/TargetInfo.cpp @@ -8865,11 +8865,17 @@ class RISCVABIInfo : public DefaultABIInfo { private: unsigned XLen; // Size of the integer ('x') registers in bits. - static const int NumArgGPRs = 8; + static int NumArgGPRs; public: RISCVABIInfo(CodeGen::CodeGenTypes &CGT, unsigned XLen) - : DefaultABIInfo(CGT), XLen(XLen) {} + : DefaultABIInfo(CGT), XLen(XLen) { + if (CGT.getTarget().getTriple().getArch() == llvm::Triple::riscv32e) { + NumArgGPRs = 6; + } else { + NumArgGPRs = 8; + } + } // DefaultABIInfo's classifyReturnType and classifyArgumentType are // non-virtual, but computeInfo is virtual, so we overload it. @@ -8884,6 +8890,7 @@ ABIArgInfo extendType(QualType Ty) const; }; +int RISCVABIInfo::NumArgGPRs = 8; } // end anonymous namespace void RISCVABIInfo::computeInfo(CGFunctionInfo &FI) const { @@ -9170,6 +9177,8 @@ case llvm::Triple::riscv32: return SetCGInfo(new RISCVTargetCodeGenInfo(Types, 32)); + case llvm::Triple::riscv32e: + return SetCGInfo(new RISCVTargetCodeGenInfo(Types, 32)); case llvm::Triple::riscv64: return SetCGInfo(new RISCVTargetCodeGenInfo(Types, 64)); Index: lib/Driver/ToolChains/Arch/RISCV.cpp =================================================================== --- lib/Driver/ToolChains/Arch/RISCV.cpp +++ lib/Driver/ToolChains/Arch/RISCV.cpp @@ -240,13 +240,11 @@ StringRef Error; // Currently LLVM does not support 'e'. // Extension 'e' is not allowed in rv64. - if (HasRV64) + if (HasRV64) { Error = "standard user-level extension 'e' requires 'rv32'"; - else - Error = "unsupported standard user-level extension 'e'"; - D.Diag(diag::err_drv_invalid_riscv_arch_name) - << MArch << Error; - return; + return; + } else + Features.push_back("+Embed"); } case 'i': break; @@ -374,5 +372,7 @@ if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) return A->getValue(); + if (Triple.getArch() == llvm::Triple::riscv32e) + return "ilp32e"; return Triple.getArch() == llvm::Triple::riscv32 ? "ilp32" : "lp64"; } Index: lib/Driver/ToolChains/Clang.cpp =================================================================== --- lib/Driver/ToolChains/Clang.cpp +++ lib/Driver/ToolChains/Clang.cpp @@ -333,6 +333,7 @@ ppc::getPPCTargetFeatures(D, Triple, Args, Features); break; case llvm::Triple::riscv32: + case llvm::Triple::riscv32e: case llvm::Triple::riscv64: riscv::getRISCVTargetFeatures(D, Args, Features); break; @@ -520,6 +521,7 @@ // WebAssembly never wants frame pointers. return false; case llvm::Triple::riscv32: + case llvm::Triple::riscv32e: case llvm::Triple::riscv64: return !areOptimizationsEnabled(Args); default: @@ -1276,6 +1278,7 @@ case llvm::Triple::hexagon: case llvm::Triple::ppc64le: case llvm::Triple::riscv32: + case llvm::Triple::riscv32e: case llvm::Triple::riscv64: case llvm::Triple::systemz: case llvm::Triple::xcore: @@ -1396,6 +1399,7 @@ break; case llvm::Triple::riscv32: + case llvm::Triple::riscv32e: case llvm::Triple::riscv64: AddRISCVTargetArgs(Args, CmdArgs); break; @@ -1699,6 +1703,8 @@ ABIName = A->getValue(); else if (Triple.getArch() == llvm::Triple::riscv32) ABIName = "ilp32"; + else if (Triple.getArch() == llvm::Triple::riscv32e) + ABIName = "ilp32e"; else if (Triple.getArch() == llvm::Triple::riscv64) ABIName = "lp64"; else Index: lib/Driver/ToolChains/Gnu.cpp =================================================================== --- lib/Driver/ToolChains/Gnu.cpp +++ lib/Driver/ToolChains/Gnu.cpp @@ -252,6 +252,8 @@ return "elf64lppc"; case llvm::Triple::riscv32: return "elf32lriscv"; + case llvm::Triple::riscv32e: + return "elf32lriscv"; case llvm::Triple::riscv64: return "elf64lriscv"; case llvm::Triple::sparc: @@ -607,6 +609,7 @@ break; } case llvm::Triple::riscv32: + case llvm::Triple::riscv32e: case llvm::Triple::riscv64: { StringRef ABIName = riscv::getRISCVABI(Args, getToolChain().getTriple()); CmdArgs.push_back("-mabi"); @@ -842,7 +845,8 @@ } static bool isRISCV(llvm::Triple::ArchType Arch) { - return Arch == llvm::Triple::riscv32 || Arch == llvm::Triple::riscv64; + return Arch == llvm::Triple::riscv32 || Arch == llvm::Triple::riscv64 || + Arch == llvm::Triple::riscv32e; } static Multilib makeMultilib(StringRef commonSuffix) { @@ -1396,6 +1400,8 @@ FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS()); Multilib Ilp32 = makeMultilib("lib32/ilp32").flag("+m32").flag("+mabi=ilp32"); + Multilib Ilp32e = + makeMultilib("lib32/ilp32e").flag("+m32").flag("+mabi=ilp32e"); Multilib Ilp32f = makeMultilib("lib32/ilp32f").flag("+m32").flag("+mabi=ilp32f"); Multilib Ilp32d = @@ -1405,16 +1411,19 @@ Multilib Lp64d = makeMultilib("lib64/lp64d").flag("+m64").flag("+mabi=lp64d"); MultilibSet RISCVMultilibs = MultilibSet() - .Either({Ilp32, Ilp32f, Ilp32d, Lp64, Lp64f, Lp64d}) + .Either({Ilp32, Ilp32e, Ilp32f, Ilp32d, Lp64, Lp64f, Lp64d}) .FilterOut(NonExistent); Multilib::flags_list Flags; bool IsRV64 = TargetTriple.getArch() == llvm::Triple::riscv64; + bool IsRV32E = TargetTriple.getArch() == llvm::Triple::riscv32e; StringRef ABIName = tools::riscv::getRISCVABI(Args, TargetTriple); addMultilibFlag(!IsRV64, "m32", Flags); + addMultilibFlag(IsRV32E, "m32", Flags); addMultilibFlag(IsRV64, "m64", Flags); addMultilibFlag(ABIName == "ilp32", "mabi=ilp32", Flags); + addMultilibFlag(ABIName == "ilp32e", "mabi=ilp32e", Flags); addMultilibFlag(ABIName == "ilp32f", "mabi=ilp32f", Flags); addMultilibFlag(ABIName == "ilp32d", "mabi=ilp32d", Flags); addMultilibFlag(ABIName == "lp64", "mabi=lp64", Flags); @@ -2401,6 +2410,7 @@ case llvm::Triple::ppc64: case llvm::Triple::ppc64le: case llvm::Triple::riscv32: + case llvm::Triple::riscv32e: case llvm::Triple::riscv64: case llvm::Triple::systemz: case llvm::Triple::mips: @@ -2549,7 +2559,8 @@ !getTriple().hasEnvironment()) || getTriple().getOS() == llvm::Triple::Solaris || getTriple().getArch() == llvm::Triple::riscv32 || - getTriple().getArch() == llvm::Triple::riscv64; + getTriple().getArch() == llvm::Triple::riscv64 || + getTriple().getArch() == llvm::Triple::riscv32e; if (DriverArgs.hasFlag(options::OPT_fuse_init_array, options::OPT_fno_use_init_array, UseInitArrayDefault)) Index: lib/Driver/ToolChains/Linux.cpp =================================================================== --- lib/Driver/ToolChains/Linux.cpp +++ lib/Driver/ToolChains/Linux.cpp @@ -191,7 +191,8 @@ Triple.getEnvironment() == llvm::Triple::GNUX32) return "libx32"; - if (Triple.getArch() == llvm::Triple::riscv32) + if (Triple.getArch() == llvm::Triple::riscv32 || + Triple.getArch() == llvm::Triple::riscv32e) return "lib32"; return Triple.isArch32Bit() ? "lib" : "lib64"; @@ -254,8 +255,9 @@ const bool IsAndroid = Triple.isAndroid(); const bool IsMips = Triple.isMIPS(); const bool IsHexagon = Arch == llvm::Triple::hexagon; - const bool IsRISCV = - Arch == llvm::Triple::riscv32 || Arch == llvm::Triple::riscv64; + const bool IsRISCV = Arch == llvm::Triple::riscv32 || + Arch == llvm::Triple::riscv64 || + Triple.getArch() == llvm::Triple::riscv32e; if (IsMips && !SysRoot.empty()) ExtraOpts.push_back("--sysroot=" + SysRoot); @@ -574,6 +576,8 @@ Loader = (tools::ppc::hasPPCAbiArg(Args, "elfv1")) ? "ld64.so.1" : "ld64.so.2"; break; + // not sure whether riscv32e use riscv32-ld, + case llvm::Triple::riscv32e: case llvm::Triple::riscv32: { StringRef ABIName = tools::riscv::getRISCVABI(Args, Triple); LibDir = "lib";