Skip to content

Commit

Permalink
Auto merge of #52787 - riscv-rust:riscv-rust-pr, r=alexcrichton
Browse files Browse the repository at this point in the history
Enable RISCV

- Enable LLVM backend.
- Implement call abi.
- Add built-in target riscv32imac-unknown-none.
- Enable CI.
  • Loading branch information
bors committed Aug 2, 2018
2 parents 1d9405f + d974dc9 commit 60c1ee7
Show file tree
Hide file tree
Showing 11 changed files with 139 additions and 4 deletions.
4 changes: 2 additions & 2 deletions config.toml.example
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/bootstrap/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
Expand Down
1 change: 1 addition & 0 deletions src/ci/docker/dist-various-1/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand Down
4 changes: 4 additions & 0 deletions src/librustc_llvm/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
6 changes: 6 additions & 0 deletions src/librustc_llvm/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
3 changes: 3 additions & 0 deletions src/librustc_target/abi/call/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ mod nvptx;
mod nvptx64;
mod powerpc;
mod powerpc64;
mod riscv;
mod s390x;
mod sparc;
mod sparc64;
Expand Down Expand Up @@ -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))
}

Expand Down
59 changes: 59 additions & 0 deletions src/librustc_target/abi/call/riscv.rs
Original file line number Diff line number Diff line change
@@ -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);
}
}
2 changes: 2 additions & 0 deletions src/librustc_target/spec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
52 changes: 52 additions & 0 deletions src/librustc_target/spec/riscv32imac_unknown_none_elf.rs
Original file line number Diff line number Diff line change
@@ -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()
},
})
}
9 changes: 8 additions & 1 deletion src/rustllvm/PassWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -192,7 +198,8 @@ bool LLVMRustPassManagerBuilderPopulateThinLTOPassManager(
SUBTARGET_SYSTEMZ \
SUBTARGET_MSP430 \
SUBTARGET_SPARC \
SUBTARGET_HEXAGON
SUBTARGET_HEXAGON \
SUBTARGET_RISCV \

#define SUBTARGET(x) \
namespace llvm { \
Expand Down
1 change: 1 addition & 0 deletions src/tools/build-manifest/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down

0 comments on commit 60c1ee7

Please sign in to comment.