Auto merge of #52787 - riscv-rust:riscv-rust-pr, r=alexcrichton
Enable RISCV - Enable LLVM backend. - Implement call abi. - Add built-in target riscv32imac-unknown-none. - Enable CI.
This commit is contained in:
commit
60c1ee7645
|
@ -61,8 +61,8 @@
|
|||
# the same format as above, but since these targets are experimental, they are
|
||||
# not built by default and the experimental Rust compilation targets that depend
|
||||
# on them will not work unless the user opts in to building them. By default the
|
||||
# `WebAssembly` target is enabled when compiling LLVM from scratch.
|
||||
#experimental-targets = "WebAssembly"
|
||||
# `WebAssembly` and `RISCV` targets are enabled when compiling LLVM from scratch.
|
||||
#experimental-targets = "WebAssembly;RISCV"
|
||||
|
||||
# Cap the number of parallel linker invocations when compiling LLVM.
|
||||
# This can be useful when building LLVM with debug info, which significantly
|
||||
|
|
|
@ -507,7 +507,7 @@ impl Config {
|
|||
set(&mut config.llvm_link_shared, llvm.link_shared);
|
||||
config.llvm_targets = llvm.targets.clone();
|
||||
config.llvm_experimental_targets = llvm.experimental_targets.clone()
|
||||
.unwrap_or("WebAssembly".to_string());
|
||||
.unwrap_or("WebAssembly;RISCV".to_string());
|
||||
config.llvm_link_jobs = llvm.link_jobs;
|
||||
config.llvm_clang_cl = llvm.clang_cl.clone();
|
||||
}
|
||||
|
|
|
@ -102,6 +102,7 @@ ENV TARGETS=$TARGETS,thumbv6m-none-eabi
|
|||
ENV TARGETS=$TARGETS,thumbv7m-none-eabi
|
||||
ENV TARGETS=$TARGETS,thumbv7em-none-eabi
|
||||
ENV TARGETS=$TARGETS,thumbv7em-none-eabihf
|
||||
ENV TARGETS=$TARGETS,riscv32imac-unknown-none-elf
|
||||
|
||||
ENV CC_mipsel_unknown_linux_musl=mipsel-openwrt-linux-gcc \
|
||||
CC_mips_unknown_linux_musl=mips-openwrt-linux-gcc \
|
||||
|
|
|
@ -100,6 +100,10 @@ fn main() {
|
|||
optional_components.push("hexagon");
|
||||
}
|
||||
|
||||
if major > 6 {
|
||||
optional_components.push("riscv");
|
||||
}
|
||||
|
||||
// FIXME: surely we don't need all these components, right? Stuff like mcjit
|
||||
// or interpreter the compiler itself never uses.
|
||||
let required_components = &["ipo",
|
||||
|
|
|
@ -90,6 +90,12 @@ pub fn initialize_available_targets() {
|
|||
LLVMInitializeMSP430Target,
|
||||
LLVMInitializeMSP430TargetMC,
|
||||
LLVMInitializeMSP430AsmPrinter);
|
||||
init_target!(llvm_component = "riscv",
|
||||
LLVMInitializeRISCVTargetInfo,
|
||||
LLVMInitializeRISCVTarget,
|
||||
LLVMInitializeRISCVTargetMC,
|
||||
LLVMInitializeRISCVAsmPrinter,
|
||||
LLVMInitializeRISCVAsmParser);
|
||||
init_target!(llvm_component = "sparc",
|
||||
LLVMInitializeSparcTargetInfo,
|
||||
LLVMInitializeSparcTarget,
|
||||
|
|
|
@ -23,6 +23,7 @@ mod nvptx;
|
|||
mod nvptx64;
|
||||
mod powerpc;
|
||||
mod powerpc64;
|
||||
mod riscv;
|
||||
mod s390x;
|
||||
mod sparc;
|
||||
mod sparc64;
|
||||
|
@ -500,6 +501,8 @@ impl<'a, Ty> FnType<'a, Ty> {
|
|||
"nvptx" => nvptx::compute_abi_info(self),
|
||||
"nvptx64" => nvptx64::compute_abi_info(self),
|
||||
"hexagon" => hexagon::compute_abi_info(self),
|
||||
"riscv32" => riscv::compute_abi_info(self, 32),
|
||||
"riscv64" => riscv::compute_abi_info(self, 64),
|
||||
a => return Err(format!("unrecognized arch \"{}\" in target specification", a))
|
||||
}
|
||||
|
||||
|
|
59
src/librustc_target/abi/call/riscv.rs
Normal file
59
src/librustc_target/abi/call/riscv.rs
Normal file
|
@ -0,0 +1,59 @@
|
|||
// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// Reference: RISC-V ELF psABI specification
|
||||
// https://github.com/riscv/riscv-elf-psabi-doc
|
||||
|
||||
use abi::call::{ArgType, FnType};
|
||||
|
||||
fn classify_ret_ty<Ty>(arg: &mut ArgType<Ty>, xlen: u64) {
|
||||
// "Scalars wider than 2✕XLEN are passed by reference and are replaced in
|
||||
// the argument list with the address."
|
||||
// "Aggregates larger than 2✕XLEN bits are passed by reference and are
|
||||
// replaced in the argument list with the address, as are C++ aggregates
|
||||
// with nontrivial copy constructors, destructors, or vtables."
|
||||
if arg.layout.size.bits() > 2 * xlen {
|
||||
arg.make_indirect();
|
||||
}
|
||||
|
||||
// "When passed in registers, scalars narrower than XLEN bits are widened
|
||||
// according to the sign of their type up to 32 bits, then sign-extended to
|
||||
// XLEN bits."
|
||||
arg.extend_integer_width_to(xlen); // this method only affects integer scalars
|
||||
}
|
||||
|
||||
fn classify_arg_ty<Ty>(arg: &mut ArgType<Ty>, xlen: u64) {
|
||||
// "Scalars wider than 2✕XLEN are passed by reference and are replaced in
|
||||
// the argument list with the address."
|
||||
// "Aggregates larger than 2✕XLEN bits are passed by reference and are
|
||||
// replaced in the argument list with the address, as are C++ aggregates
|
||||
// with nontrivial copy constructors, destructors, or vtables."
|
||||
if arg.layout.size.bits() > 2 * xlen {
|
||||
arg.make_indirect();
|
||||
}
|
||||
|
||||
// "When passed in registers, scalars narrower than XLEN bits are widened
|
||||
// according to the sign of their type up to 32 bits, then sign-extended to
|
||||
// XLEN bits."
|
||||
arg.extend_integer_width_to(xlen); // this method only affects integer scalars
|
||||
}
|
||||
|
||||
pub fn compute_abi_info<Ty>(fty: &mut FnType<Ty>, xlen: u64) {
|
||||
if !fty.ret.is_ignore() {
|
||||
classify_ret_ty(&mut fty.ret, xlen);
|
||||
}
|
||||
|
||||
for arg in &mut fty.args {
|
||||
if arg.is_ignore() {
|
||||
continue;
|
||||
}
|
||||
classify_arg_ty(arg, xlen);
|
||||
}
|
||||
}
|
|
@ -377,6 +377,8 @@ supported_targets! {
|
|||
|
||||
("aarch64-unknown-hermit", aarch64_unknown_hermit),
|
||||
("x86_64-unknown-hermit", x86_64_unknown_hermit),
|
||||
|
||||
("riscv32imac-unknown-none-elf", riscv32imac_unknown_none_elf),
|
||||
}
|
||||
|
||||
/// Everything `rustc` knows about how to compile for a specific target.
|
||||
|
|
52
src/librustc_target/spec/riscv32imac_unknown_none_elf.rs
Normal file
52
src/librustc_target/spec/riscv32imac_unknown_none_elf.rs
Normal file
|
@ -0,0 +1,52 @@
|
|||
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use spec::{LinkerFlavor, PanicStrategy, Target, TargetOptions, TargetResult};
|
||||
use spec::abi::{Abi};
|
||||
|
||||
pub fn target() -> TargetResult {
|
||||
Ok(Target {
|
||||
data_layout: "e-m:e-p:32:32-i64:64-n32-S128".to_string(),
|
||||
llvm_target: "riscv32".to_string(),
|
||||
target_endian: "little".to_string(),
|
||||
target_pointer_width: "32".to_string(),
|
||||
target_c_int_width: "32".to_string(),
|
||||
target_os: "none".to_string(),
|
||||
target_env: "".to_string(),
|
||||
target_vendor: "unknown".to_string(),
|
||||
arch: "riscv32".to_string(),
|
||||
linker_flavor: LinkerFlavor::Ld,
|
||||
|
||||
options: TargetOptions {
|
||||
linker: Some("riscv32-unknown-elf-ld".to_string()),
|
||||
cpu: "generic-rv32".to_string(),
|
||||
max_atomic_width: Some(32),
|
||||
atomic_cas: false, // incomplete +a extension
|
||||
features: "+m,+a".to_string(), // disable +c extension
|
||||
executables: true,
|
||||
panic_strategy: PanicStrategy::Abort,
|
||||
relocation_model: "static".to_string(),
|
||||
abi_blacklist: vec![
|
||||
Abi::Cdecl,
|
||||
Abi::Stdcall,
|
||||
Abi::Fastcall,
|
||||
Abi::Vectorcall,
|
||||
Abi::Thiscall,
|
||||
Abi::Aapcs,
|
||||
Abi::Win64,
|
||||
Abi::SysV64,
|
||||
Abi::PtxKernel,
|
||||
Abi::Msp430Interrupt,
|
||||
Abi::X86Interrupt,
|
||||
],
|
||||
.. Default::default()
|
||||
},
|
||||
})
|
||||
}
|
|
@ -171,6 +171,12 @@ bool LLVMRustPassManagerBuilderPopulateThinLTOPassManager(
|
|||
#define SUBTARGET_MSP430
|
||||
#endif
|
||||
|
||||
#ifdef LLVM_COMPONENT_RISCV
|
||||
#define SUBTARGET_RISCV SUBTARGET(RISCV)
|
||||
#else
|
||||
#define SUBTARGET_RISCV
|
||||
#endif
|
||||
|
||||
#ifdef LLVM_COMPONENT_SPARC
|
||||
#define SUBTARGET_SPARC SUBTARGET(Sparc)
|
||||
#else
|
||||
|
@ -192,7 +198,8 @@ bool LLVMRustPassManagerBuilderPopulateThinLTOPassManager(
|
|||
SUBTARGET_SYSTEMZ \
|
||||
SUBTARGET_MSP430 \
|
||||
SUBTARGET_SPARC \
|
||||
SUBTARGET_HEXAGON
|
||||
SUBTARGET_HEXAGON \
|
||||
SUBTARGET_RISCV \
|
||||
|
||||
#define SUBTARGET(x) \
|
||||
namespace llvm { \
|
||||
|
|
|
@ -89,6 +89,7 @@ static TARGETS: &'static [&'static str] = &[
|
|||
"powerpc64-unknown-linux-gnu",
|
||||
"powerpc64le-unknown-linux-gnu",
|
||||
"powerpc64le-unknown-linux-musl",
|
||||
"riscv32imac-unknown-none-elf",
|
||||
"s390x-unknown-linux-gnu",
|
||||
"sparc-unknown-linux-gnu",
|
||||
"sparc64-unknown-linux-gnu",
|
||||
|
|
Loading…
Reference in a new issue