Skip to content

Commit 56adb1f

Browse files
djtodorodjtodoro
authored andcommitted
[clang] Add driver support for riscv64-mti toolchains
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]>
1 parent 1430238 commit 56adb1f

File tree

14 files changed

+233
-80
lines changed

14 files changed

+233
-80
lines changed

clang/lib/Driver/ToolChains/Arch/RISCV.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -336,12 +336,14 @@ std::string riscv::getRISCVArch(const llvm::opt::ArgList &Args,
336336
// - On `riscv{XLEN}-unknown-elf` we default to `rv{XLEN}imac`
337337
// - On all other OSs we use `rv{XLEN}imafdc` (equivalent to `rv{XLEN}gc`)
338338
if (Triple.isRISCV32()) {
339-
if (Triple.getOS() == llvm::Triple::UnknownOS)
339+
if (Triple.getOS() == llvm::Triple::UnknownOS &&
340+
Triple.getVendor() != llvm::Triple::MipsTechnologies)
340341
return "rv32imac";
341342
else
342343
return "rv32imafdc";
343344
} else {
344-
if (Triple.getOS() == llvm::Triple::UnknownOS)
345+
if (Triple.getOS() == llvm::Triple::UnknownOS &&
346+
Triple.getVendor() != llvm::Triple::MipsTechnologies)
345347
return "rv64imac";
346348
else if (Triple.isAndroid())
347349
return "rv64imafdcv_zba_zbb_zbs";

clang/lib/Driver/ToolChains/Gnu.cpp

Lines changed: 113 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -252,9 +252,18 @@ static const char *getLDMOption(const llvm::Triple &T, const ArgList &Args) {
252252
case llvm::Triple::ppc64le:
253253
return "elf64lppc";
254254
case llvm::Triple::riscv32:
255-
return "elf32lriscv";
256255
case llvm::Triple::riscv64:
257-
return "elf64lriscv";
256+
{
257+
bool IsBigEndian = false;
258+
if (Arg *A = Args.getLastArg(options::OPT_mlittle_endian,
259+
options::OPT_mbig_endian))
260+
IsBigEndian = A->getOption().matches(options::OPT_mbig_endian);
261+
262+
if (T.getArch() == llvm::Triple::riscv32)
263+
return IsBigEndian ? "elf32briscv" : "elf32lriscv";
264+
else
265+
return IsBigEndian ? "elf64briscv" : "elf64lriscv";
266+
}
258267
case llvm::Triple::sparc:
259268
case llvm::Triple::sparcel:
260269
return "elf32_sparc";
@@ -402,6 +411,14 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA,
402411
CmdArgs.push_back(Arch == llvm::Triple::aarch64_be ? "-EB" : "-EL");
403412
}
404413

414+
if (Triple.isRISCV() &&
415+
Triple.getVendor() == llvm::Triple::MipsTechnologies) {
416+
bool IsBigEndian = false;
417+
if (Arg *A = Args.getLastArg(options::OPT_mlittle_endian,
418+
options::OPT_mbig_endian))
419+
IsBigEndian = A->getOption().matches(options::OPT_mbig_endian);
420+
CmdArgs.push_back(IsBigEndian ? "-EB" : "-EL");
421+
}
405422
// Most Android ARM64 targets should enable the linker fix for erratum
406423
// 843419. Only non-Cortex-A53 devices are allowed to skip this flag.
407424
if (Arch == llvm::Triple::aarch64 && (isAndroid || isOHOSFamily)) {
@@ -765,7 +782,8 @@ void tools::gnutools::Assembler::ConstructJob(Compilation &C,
765782
}
766783
case llvm::Triple::riscv32:
767784
case llvm::Triple::riscv64: {
768-
StringRef ABIName = riscv::getRISCVABI(Args, getToolChain().getTriple());
785+
const llvm::Triple &Triple = getToolChain().getTriple();
786+
StringRef ABIName = riscv::getRISCVABI(Args, Triple);
769787
CmdArgs.push_back("-mabi");
770788
CmdArgs.push_back(ABIName.data());
771789
std::string MArchName =
@@ -774,6 +792,14 @@ void tools::gnutools::Assembler::ConstructJob(Compilation &C,
774792
CmdArgs.push_back(Args.MakeArgString(MArchName));
775793
if (!Args.hasFlag(options::OPT_mrelax, options::OPT_mno_relax, true))
776794
Args.addOptOutFlag(CmdArgs, options::OPT_mrelax, options::OPT_mno_relax);
795+
796+
if (Triple.getVendor() == llvm::Triple::MipsTechnologies) {
797+
bool IsBigEndian = false;
798+
if (Arg *A = Args.getLastArg(options::OPT_mlittle_endian,
799+
options::OPT_mbig_endian))
800+
IsBigEndian = A->getOption().matches(options::OPT_mbig_endian);
801+
CmdArgs.push_back(IsBigEndian ? "-EB" : "-EL");
802+
}
777803
break;
778804
}
779805
case llvm::Triple::sparc:
@@ -1873,9 +1899,18 @@ static void findRISCVBareMetalMultilibs(const Driver &D,
18731899
.flag(Twine("-march=", Element.march).str())
18741900
.flag(Twine("-mabi=", Element.mabi).str()));
18751901
}
1902+
SmallVector<MultilibBuilder, 2> Endian;
1903+
if (TargetTriple.getVendor() == llvm::Triple::MipsTechnologies) {
1904+
Endian.push_back(
1905+
MultilibBuilder("/riscv").flag("-EL").flag("-EB", /*Disallow=*/true));
1906+
Endian.push_back(
1907+
MultilibBuilder("/riscveb").flag("-EB").flag("-EL", /*Disallow=*/true));
1908+
}
18761909
MultilibSet RISCVMultilibs =
18771910
MultilibSetBuilder()
18781911
.Either(Ms)
1912+
.Either(Endian)
1913+
.Either(ArrayRef<MultilibBuilder>(Ms))
18791914
.makeMultilibSet()
18801915
.FilterOut(NonExistent)
18811916
.setFilePathsCallback([](const Multilib &M) {
@@ -1899,6 +1934,19 @@ static void findRISCVBareMetalMultilibs(const Driver &D,
18991934
}
19001935
}
19011936

1937+
bool IsBigEndian = false;
1938+
if (Arg *A = Args.getLastArg(options::OPT_mlittle_endian,
1939+
options::OPT_mbig_endian))
1940+
IsBigEndian = A->getOption().matches(options::OPT_mbig_endian);
1941+
1942+
if (IsBigEndian) {
1943+
D.Diag(diag::err_drv_unsupported_opt_for_target)
1944+
<< "-EB" << TargetTriple.str();
1945+
}
1946+
1947+
addMultilibFlag(IsBigEndian, "-EB", Flags);
1948+
addMultilibFlag(!IsBigEndian, "-EL", Flags);
1949+
19021950
if (selectRISCVMultilib(D, RISCVMultilibs, MArch, Flags,
19031951
Result.SelectedMultilibs))
19041952
Result.Multilibs = RISCVMultilibs;
@@ -1923,15 +1971,34 @@ static void findRISCVMultilibs(const Driver &D,
19231971
MultilibBuilder("lib64/lp64f").flag("-m64").flag("-mabi=lp64f");
19241972
MultilibBuilder Lp64d =
19251973
MultilibBuilder("lib64/lp64d").flag("-m64").flag("-mabi=lp64d");
1974+
1975+
SmallVector<MultilibBuilder, 2> Endian;
1976+
if (TargetTriple.getVendor() == llvm::Triple::MipsTechnologies) {
1977+
Endian.push_back(
1978+
MultilibBuilder("/riscv").flag("-EL").flag("-EB", /*Disallow=*/true));
1979+
Endian.push_back(
1980+
MultilibBuilder("/riscveb").flag("-EB").flag("-EL", /*Disallow=*/true));
1981+
}
1982+
19261983
MultilibSet RISCVMultilibs =
19271984
MultilibSetBuilder()
1985+
.Either(Endian)
19281986
.Either({Ilp32, Ilp32f, Ilp32d, Lp64, Lp64f, Lp64d})
19291987
.makeMultilibSet()
19301988
.FilterOut(NonExistent);
19311989

19321990
Multilib::flags_list Flags;
19331991
bool IsRV64 = TargetTriple.getArch() == llvm::Triple::riscv64;
19341992
StringRef ABIName = tools::riscv::getRISCVABI(Args, TargetTriple);
1993+
bool IsBigEndian = false;
1994+
if (Arg *A = Args.getLastArg(options::OPT_mlittle_endian,
1995+
options::OPT_mbig_endian))
1996+
IsBigEndian = A->getOption().matches(options::OPT_mbig_endian);
1997+
1998+
if (IsBigEndian) {
1999+
D.Diag(diag::err_drv_unsupported_opt_for_target)
2000+
<< "-EB" << TargetTriple.str();
2001+
}
19352002

19362003
addMultilibFlag(!IsRV64, "-m32", Flags);
19372004
addMultilibFlag(IsRV64, "-m64", Flags);
@@ -1941,6 +2008,8 @@ static void findRISCVMultilibs(const Driver &D,
19412008
addMultilibFlag(ABIName == "lp64", "-mabi=lp64", Flags);
19422009
addMultilibFlag(ABIName == "lp64f", "-mabi=lp64f", Flags);
19432010
addMultilibFlag(ABIName == "lp64d", "-mabi=lp64d", Flags);
2011+
addMultilibFlag(IsBigEndian, "-EB", Flags);
2012+
addMultilibFlag(!IsBigEndian, "-EL", Flags);
19442013

19452014
if (RISCVMultilibs.select(D, Flags, Result.SelectedMultilibs))
19462015
Result.Multilibs = RISCVMultilibs;
@@ -2566,7 +2635,8 @@ void Generic_GCC::GCCInstallationDetector::AddDefaultGCCPrefixes(
25662635
"riscv32-unknown-elf"};
25672636
static const char *const RISCV64LibDirs[] = {"/lib64", "/lib"};
25682637
static const char *const RISCV64Triples[] = {"riscv64-unknown-linux-gnu",
2569-
"riscv64-unknown-elf"};
2638+
"riscv64-unknown-elf",
2639+
"riscv64-mti-elf"};
25702640

25712641
static const char *const SPARCv8LibDirs[] = {"/lib32", "/lib"};
25722642
static const char *const SPARCv8Triples[] = {"sparc-linux-gnu",
@@ -3137,6 +3207,45 @@ bool Generic_GCC::IsIntegratedAssemblerDefault() const {
31373207
case llvm::Triple::nvptx64:
31383208
case llvm::Triple::xcore:
31393209
return false;
3210+
case llvm::Triple::aarch64:
3211+
case llvm::Triple::aarch64_be:
3212+
case llvm::Triple::amdgcn:
3213+
case llvm::Triple::arm:
3214+
case llvm::Triple::armeb:
3215+
case llvm::Triple::avr:
3216+
case llvm::Triple::bpfel:
3217+
case llvm::Triple::bpfeb:
3218+
case llvm::Triple::csky:
3219+
case llvm::Triple::hexagon:
3220+
case llvm::Triple::lanai:
3221+
case llvm::Triple::loongarch32:
3222+
case llvm::Triple::loongarch64:
3223+
case llvm::Triple::m68k:
3224+
case llvm::Triple::mips:
3225+
case llvm::Triple::mipsel:
3226+
case llvm::Triple::mips64:
3227+
case llvm::Triple::mips64el:
3228+
case llvm::Triple::msp430:
3229+
case llvm::Triple::ppc:
3230+
case llvm::Triple::ppcle:
3231+
case llvm::Triple::ppc64:
3232+
case llvm::Triple::ppc64le:
3233+
case llvm::Triple::r600:
3234+
case llvm::Triple::sparc:
3235+
case llvm::Triple::sparcel:
3236+
case llvm::Triple::sparcv9:
3237+
case llvm::Triple::systemz:
3238+
case llvm::Triple::thumb:
3239+
case llvm::Triple::thumbeb:
3240+
case llvm::Triple::ve:
3241+
case llvm::Triple::x86:
3242+
case llvm::Triple::x86_64:
3243+
return true;
3244+
case llvm::Triple::riscv32:
3245+
case llvm::Triple::riscv64:
3246+
if (getTriple().getVendor() != llvm::Triple::MipsTechnologies)
3247+
return true;
3248+
return false;
31403249
default:
31413250
return true;
31423251
}

clang/lib/Driver/ToolChains/Linux.cpp

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -274,11 +274,13 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
274274
const bool IsHexagon = Arch == llvm::Triple::hexagon;
275275
const bool IsRISCV = Triple.isRISCV();
276276
const bool IsCSKY = Triple.isCSKY();
277+
const bool IsMipsSysRoot = IsMips ||
278+
(IsRISCV && Triple.getVendor() == llvm::Triple::MipsTechnologies);
277279

278280
if (IsCSKY && !SelectedMultilibs.empty())
279281
SysRoot = SysRoot + SelectedMultilibs.back().osSuffix();
280282

281-
if ((IsMips || IsCSKY) && !SysRoot.empty())
283+
if ((IsMipsSysRoot || IsCSKY) && !SysRoot.empty())
282284
ExtraOpts.push_back("--sysroot=" + SysRoot);
283285

284286
// Do not use 'gnu' hash style for Mips targets because .gnu.hash
@@ -412,7 +414,11 @@ std::string Linux::computeSysRoot() const {
412414
return std::string();
413415
}
414416

415-
if (!GCCInstallation.isValid() || !getTriple().isMIPS())
417+
const bool IsMipsSysRoot = getTriple().isMIPS() ||
418+
(getTriple().isRISCV() &&
419+
getTriple().getVendor() == llvm::Triple::MipsTechnologies);
420+
421+
if (!GCCInstallation.isValid() || !IsMipsSysRoot)
416422
return std::string();
417423

418424
// Standalone MIPS toolchains use different names for sysroot folder
@@ -422,8 +428,19 @@ std::string Linux::computeSysRoot() const {
422428
const StringRef InstallDir = GCCInstallation.getInstallPath();
423429
const StringRef TripleStr = GCCInstallation.getTriple().str();
424430
const Multilib &Multilib = GCCInstallation.getMultilib();
431+
std::string Path;
432+
if (getTriple().isRISCV()) {
433+
Path =
434+
(InstallDir + "/../../../../sysroot" + Multilib.osSuffix() + "/../..")
435+
.str();
436+
437+
if (getVFS().exists(Path))
438+
return Path;
439+
440+
return std::string();
441+
}
425442

426-
std::string Path =
443+
Path =
427444
(InstallDir + "/../../../../" + TripleStr + "/libc" + Multilib.osSuffix())
428445
.str();
429446

clang/lib/Driver/ToolChains/RISCVToolchain.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ Tool *RISCVToolChain::buildLinker() const {
7777
}
7878

7979
ToolChain::RuntimeLibType RISCVToolChain::GetDefaultRuntimeLibType() const {
80-
return GCCInstallation.isValid() ?
80+
return GCCInstallation.isValid() ?
8181
ToolChain::RLT_Libgcc : ToolChain::RLT_CompilerRT;
8282
}
8383

@@ -173,6 +173,14 @@ void RISCV::Linker::ConstructJob(Compilation &C, const JobAction &JA,
173173
}
174174
CmdArgs.push_back("-X");
175175

176+
if (ToolChain.getTriple().getVendor() == llvm::Triple::MipsTechnologies) {
177+
bool IsBigEndian = false;
178+
if (Arg *A = Args.getLastArg(options::OPT_mlittle_endian,
179+
options::OPT_mbig_endian))
180+
IsBigEndian = A->getOption().matches(options::OPT_mbig_endian);
181+
CmdArgs.push_back(IsBigEndian ? "-EB" : "-EL");
182+
}
183+
176184
std::string Linker = getToolChain().GetLinkerPath();
177185

178186
bool WantCRTs =
@@ -229,4 +237,10 @@ void RISCV::Linker::ConstructJob(Compilation &C, const JobAction &JA,
229237
JA, *this, ResponseFileSupport::AtFileCurCP(), Args.MakeArgString(Linker),
230238
CmdArgs, Inputs, Output));
231239
}
240+
241+
bool RISCVToolChain::IsIntegratedAssemblerDefault() const {
242+
if (getTriple().getVendor() != llvm::Triple::MipsTechnologies)
243+
return true;
244+
return false;
245+
}
232246
// RISCV tools end.

clang/lib/Driver/ToolChains/RISCVToolchain.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ class LLVM_LIBRARY_VISIBILITY RISCVToolChain : public Generic_ELF {
2222
const llvm::opt::ArgList &Args);
2323

2424
static bool hasGCCToolchain(const Driver &D, const llvm::opt::ArgList &Args);
25+
bool IsIntegratedAssemblerDefault() const override;
2526
void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
2627
llvm::opt::ArgStringList &CC1Args,
2728
Action::OffloadKind) const override;

llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,11 @@ const MCExpr *RISCVMCAsmInfo::getExprForFDESymbol(const MCSymbol *Sym,
4545
assert(Encoding & dwarf::DW_EH_PE_sdata4 && "Unexpected encoding");
4646
return RISCVMCExpr::create(ME, RISCVMCExpr::VK_RISCV_32_PCREL, Ctx);
4747
}
48+
49+
void RISCVMCAsmInfo::setUseIntegratedAssembler(bool Value) {
50+
UseIntegratedAssembler = Value;
51+
if (!UseIntegratedAssembler) {
52+
// gas doesn't handle non-constant <u>leb128
53+
HasLEB128Directives = false;
54+
}
55+
}

llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ class RISCVMCAsmInfo : public MCAsmInfoELF {
2626

2727
const MCExpr *getExprForFDESymbol(const MCSymbol *Sym, unsigned Encoding,
2828
MCStreamer &Streamer) const override;
29+
/// Set whether assembly (inline or otherwise) should be parsed.
30+
void setUseIntegratedAssembler(bool Value) override;
2931
};
3032

3133
} // namespace llvm

llvm/lib/Target/RISCV/RISCVInstrInfoZb.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -427,7 +427,7 @@ def UNZIP_RV32 : Unary_r<0b000010001111, 0b101, "unzip">,
427427
// Pseudo Instructions
428428
//===----------------------------------------------------------------------===//
429429

430-
let Predicates = [HasStdExtZba, IsRV64] in {
430+
let Predicates = [HasStdExtZba, IsRV64], EmitPriority = 0 in {
431431
def : InstAlias<"zext.w $rd, $rs", (ADD_UW GPR:$rd, GPR:$rs, X0)>;
432432
} // Predicates = [HasStdExtZba, IsRV64]
433433

llvm/test/CodeGen/RISCV/div-by-constant.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ define i32 @udiv_constant_add(i32 %a) nounwind {
6262
;
6363
; RV64IMZB-LABEL: udiv_constant_add:
6464
; RV64IMZB: # %bb.0:
65-
; RV64IMZB-NEXT: zext.w a1, a0
65+
; RV64IMZB-NEXT: add.uw a1, a0, zero
6666
; RV64IMZB-NEXT: lui a2, 149797
6767
; RV64IMZB-NEXT: addiw a2, a2, -1755
6868
; RV64IMZB-NEXT: mul a1, a1, a2

0 commit comments

Comments
 (0)