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:
bors 2018-08-02 02:24:15 +00:00
commit 60c1ee7645
11 changed files with 139 additions and 4 deletions

View file

@ -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

View file

@ -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();
}

View file

@ -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 \

View file

@ -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",

View file

@ -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,

View file

@ -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))
}

View 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);
}
}

View file

@ -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.

View 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()
},
})
}

View file

@ -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 { \

View file

@ -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",