Rollup merge of #80525 - devsnek:wasm64, r=nagisa
wasm64 support There is still some upstream llvm work needed before this can land.
This commit is contained in:
commit
0d12422f2d
19 changed files with 129 additions and 18 deletions
|
@ -20,6 +20,7 @@ mod sparc;
|
|||
mod sparc64;
|
||||
mod wasm32;
|
||||
mod wasm32_bindgen_compat;
|
||||
mod wasm64;
|
||||
mod x86;
|
||||
mod x86_64;
|
||||
mod x86_win64;
|
||||
|
@ -652,6 +653,7 @@ impl<'a, Ty> FnAbi<'a, Ty> {
|
|||
_ => wasm32_bindgen_compat::compute_abi_info(self),
|
||||
},
|
||||
"asmjs" => wasm32::compute_abi_info(cx, self),
|
||||
"wasm64" => wasm64::compute_abi_info(cx, self),
|
||||
a => return Err(format!("unrecognized arch \"{}\" in target specification", a)),
|
||||
}
|
||||
|
||||
|
|
58
compiler/rustc_target/src/abi/call/wasm64.rs
Normal file
58
compiler/rustc_target/src/abi/call/wasm64.rs
Normal file
|
@ -0,0 +1,58 @@
|
|||
use crate::abi::call::{ArgAbi, FnAbi, Uniform};
|
||||
use crate::abi::{HasDataLayout, LayoutOf, TyAndLayout, TyAndLayoutMethods};
|
||||
|
||||
fn unwrap_trivial_aggregate<'a, Ty, C>(cx: &C, val: &mut ArgAbi<'a, Ty>) -> bool
|
||||
where
|
||||
Ty: TyAndLayoutMethods<'a, C> + Copy,
|
||||
C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
|
||||
{
|
||||
if val.layout.is_aggregate() {
|
||||
if let Some(unit) = val.layout.homogeneous_aggregate(cx).ok().and_then(|ha| ha.unit()) {
|
||||
let size = val.layout.size;
|
||||
if unit.size == size {
|
||||
val.cast_to(Uniform { unit, total: size });
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
fn classify_ret<'a, Ty, C>(cx: &C, ret: &mut ArgAbi<'a, Ty>)
|
||||
where
|
||||
Ty: TyAndLayoutMethods<'a, C> + Copy,
|
||||
C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
|
||||
{
|
||||
ret.extend_integer_width_to(64);
|
||||
if ret.layout.is_aggregate() && !unwrap_trivial_aggregate(cx, ret) {
|
||||
ret.make_indirect();
|
||||
}
|
||||
}
|
||||
|
||||
fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>)
|
||||
where
|
||||
Ty: TyAndLayoutMethods<'a, C> + Copy,
|
||||
C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
|
||||
{
|
||||
arg.extend_integer_width_to(64);
|
||||
if arg.layout.is_aggregate() && !unwrap_trivial_aggregate(cx, arg) {
|
||||
arg.make_indirect_byval();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
|
||||
where
|
||||
Ty: TyAndLayoutMethods<'a, C> + Copy,
|
||||
C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
|
||||
{
|
||||
if !fn_abi.ret.is_ignore() {
|
||||
classify_ret(cx, &mut fn_abi.ret);
|
||||
}
|
||||
|
||||
for arg in &mut fn_abi.args {
|
||||
if arg.is_ignore() {
|
||||
continue;
|
||||
}
|
||||
classify_arg(cx, arg);
|
||||
}
|
||||
}
|
|
@ -79,7 +79,7 @@ mod solaris_base;
|
|||
mod thumb_base;
|
||||
mod uefi_msvc_base;
|
||||
mod vxworks_base;
|
||||
mod wasm32_base;
|
||||
mod wasm_base;
|
||||
mod windows_gnu_base;
|
||||
mod windows_msvc_base;
|
||||
mod windows_uwp_gnu_base;
|
||||
|
@ -842,6 +842,7 @@ supported_targets! {
|
|||
("wasm32-unknown-emscripten", wasm32_unknown_emscripten),
|
||||
("wasm32-unknown-unknown", wasm32_unknown_unknown),
|
||||
("wasm32-wasi", wasm32_wasi),
|
||||
("wasm64-unknown-unknown", wasm64_unknown_unknown),
|
||||
|
||||
("thumbv6m-none-eabi", thumbv6m_none_eabi),
|
||||
("thumbv7m-none-eabi", thumbv7m_none_eabi),
|
||||
|
@ -1076,6 +1077,8 @@ pub struct TargetOptions {
|
|||
pub is_like_emscripten: bool,
|
||||
/// Whether the target toolchain is like Fuchsia's.
|
||||
pub is_like_fuchsia: bool,
|
||||
/// Whether a target toolchain is like WASM.
|
||||
pub is_like_wasm: bool,
|
||||
/// Version of DWARF to use if not using the default.
|
||||
/// Useful because some platforms (osx, bsd) only want up to DWARF2.
|
||||
pub dwarf_version: Option<u32>,
|
||||
|
@ -1295,6 +1298,7 @@ impl Default for TargetOptions {
|
|||
is_like_emscripten: false,
|
||||
is_like_msvc: false,
|
||||
is_like_fuchsia: false,
|
||||
is_like_wasm: false,
|
||||
dwarf_version: None,
|
||||
linker_is_gnu: false,
|
||||
allows_weak_linkage: true,
|
||||
|
@ -1789,6 +1793,7 @@ impl Target {
|
|||
key!(is_like_msvc, bool);
|
||||
key!(is_like_emscripten, bool);
|
||||
key!(is_like_fuchsia, bool);
|
||||
key!(is_like_wasm, bool);
|
||||
key!(dwarf_version, Option<u32>);
|
||||
key!(linker_is_gnu, bool);
|
||||
key!(allows_weak_linkage, bool);
|
||||
|
@ -2027,6 +2032,7 @@ impl ToJson for Target {
|
|||
target_option_val!(is_like_msvc);
|
||||
target_option_val!(is_like_emscripten);
|
||||
target_option_val!(is_like_fuchsia);
|
||||
target_option_val!(is_like_wasm);
|
||||
target_option_val!(dwarf_version);
|
||||
target_option_val!(linker_is_gnu);
|
||||
target_option_val!(allows_weak_linkage);
|
||||
|
|
|
@ -50,6 +50,7 @@ impl Target {
|
|||
// and you certainly want "unknown" for the OS name.
|
||||
fn can_use_os_unknown(&self) -> bool {
|
||||
self.llvm_target == "wasm32-unknown-unknown"
|
||||
|| self.llvm_target == "wasm64-unknown-unknown"
|
||||
|| (self.env == "sgx" && self.vendor == "fortanix")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use super::wasm32_base;
|
||||
use super::wasm_base;
|
||||
use super::{LinkArgs, LinkerFlavor, PanicStrategy, Target, TargetOptions};
|
||||
|
||||
pub fn target() -> Target {
|
||||
let mut options = wasm32_base::options();
|
||||
let mut options = wasm_base::options();
|
||||
|
||||
let clang_args = options.pre_link_args.entry(LinkerFlavor::Gcc).or_default();
|
||||
|
||||
|
|
|
@ -10,11 +10,11 @@
|
|||
//! This target is more or less managed by the Rust and WebAssembly Working
|
||||
//! Group nowadays at <https://github.com/rustwasm>.
|
||||
|
||||
use super::wasm32_base;
|
||||
use super::wasm_base;
|
||||
use super::{LinkerFlavor, LldFlavor, Target};
|
||||
|
||||
pub fn target() -> Target {
|
||||
let mut options = wasm32_base::options();
|
||||
let mut options = wasm_base::options();
|
||||
options.os = "unknown".to_string();
|
||||
options.linker_flavor = LinkerFlavor::Lld(LldFlavor::Wasm);
|
||||
let clang_args = options.pre_link_args.entry(LinkerFlavor::Gcc).or_default();
|
||||
|
|
|
@ -72,11 +72,11 @@
|
|||
//! best we can with this target. Don't start relying on too much here unless
|
||||
//! you know what you're getting in to!
|
||||
|
||||
use super::wasm32_base;
|
||||
use super::wasm_base;
|
||||
use super::{crt_objects, LinkerFlavor, LldFlavor, Target};
|
||||
|
||||
pub fn target() -> Target {
|
||||
let mut options = wasm32_base::options();
|
||||
let mut options = wasm_base::options();
|
||||
|
||||
options.os = "wasi".to_string();
|
||||
options.linker_flavor = LinkerFlavor::Lld(LldFlavor::Wasm);
|
||||
|
|
39
compiler/rustc_target/src/spec/wasm64_unknown_unknown.rs
Normal file
39
compiler/rustc_target/src/spec/wasm64_unknown_unknown.rs
Normal file
|
@ -0,0 +1,39 @@
|
|||
//! A "bare wasm" target representing a WebAssembly output that makes zero
|
||||
//! assumptions about its environment.
|
||||
//!
|
||||
//! The `wasm64-unknown-unknown` target is intended to encapsulate use cases
|
||||
//! that do not rely on any imported functionality. The binaries generated are
|
||||
//! entirely self-contained by default when using the standard library. Although
|
||||
//! the standard library is available, most of it returns an error immediately
|
||||
//! (e.g. trying to create a TCP stream or something like that).
|
||||
|
||||
use super::wasm_base;
|
||||
use super::{LinkerFlavor, LldFlavor, Target};
|
||||
|
||||
pub fn target() -> Target {
|
||||
let mut options = wasm_base::options();
|
||||
options.os = "unknown".to_string();
|
||||
options.linker_flavor = LinkerFlavor::Lld(LldFlavor::Wasm);
|
||||
let clang_args = options.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap();
|
||||
|
||||
// Make sure clang uses LLD as its linker and is configured appropriately
|
||||
// otherwise
|
||||
clang_args.push("--target=wasm64-unknown-unknown".to_string());
|
||||
|
||||
// For now this target just never has an entry symbol no matter the output
|
||||
// type, so unconditionally pass this.
|
||||
clang_args.push("-Wl,--no-entry".to_string());
|
||||
options
|
||||
.pre_link_args
|
||||
.get_mut(&LinkerFlavor::Lld(LldFlavor::Wasm))
|
||||
.unwrap()
|
||||
.push("--no-entry".to_string());
|
||||
|
||||
Target {
|
||||
llvm_target: "wasm64-unknown-unknown".to_string(),
|
||||
pointer_width: 64,
|
||||
data_layout: "e-m:e-p:64:64-i64:64-n32:64-S128".to_string(),
|
||||
arch: "wasm64".to_string(),
|
||||
options,
|
||||
}
|
||||
}
|
|
@ -60,6 +60,8 @@ pub fn options() -> TargetOptions {
|
|||
pre_link_args.insert(LinkerFlavor::Gcc, clang_args);
|
||||
|
||||
TargetOptions {
|
||||
is_like_wasm: true,
|
||||
|
||||
// we allow dynamic linking, but only cdylibs. Basically we allow a
|
||||
// final library artifact that exports some symbols (a wasm module) but
|
||||
// we don't allow intermediate `dylib` crate types
|
Loading…
Add table
Add a link
Reference in a new issue