Skip to content

Commit 5b5529a

Browse files
authored
Rollup merge of rust-lang#80525 - devsnek:wasm64, r=nagisa
wasm64 support There is still some upstream llvm work needed before this can land.
2 parents 8ad6a44 + da66a31 commit 5b5529a

File tree

19 files changed

+129
-18
lines changed

19 files changed

+129
-18
lines changed

compiler/rustc_codegen_llvm/src/attributes.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,7 @@ pub fn from_fn_attrs(cx: &CodegenCx<'ll, 'tcx>, llfn: &'ll Value, instance: ty::
317317
// Note that currently the `wasm-import-module` doesn't do anything, but
318318
// eventually LLVM 7 should read this and ferry the appropriate import
319319
// module to the output file.
320-
if cx.tcx.sess.target.arch == "wasm32" {
320+
if cx.tcx.sess.target.is_like_wasm {
321321
if let Some(module) = wasm_import_module(cx.tcx, instance.def_id()) {
322322
llvm::AddFunctionAttrStringValue(
323323
llfn,

compiler/rustc_codegen_llvm/src/back/write.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -170,10 +170,7 @@ pub fn target_machine_factory(
170170
// On the wasm target once the `atomics` feature is enabled that means that
171171
// we're no longer single-threaded, or otherwise we don't want LLVM to
172172
// lower atomic operations to single-threaded operations.
173-
if singlethread
174-
&& sess.target.llvm_target.contains("wasm32")
175-
&& sess.target_features.contains(&sym::atomics)
176-
{
173+
if singlethread && sess.target.is_like_wasm && sess.target_features.contains(&sym::atomics) {
177174
singlethread = false;
178175
}
179176

compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1083,9 +1083,9 @@ pub fn compile_unit_metadata(
10831083
);
10841084
}
10851085

1086-
// Insert `llvm.ident` metadata on the wasm32 targets since that will
1086+
// Insert `llvm.ident` metadata on the wasm targets since that will
10871087
// get hooked up to the "producer" sections `processed-by` information.
1088-
if tcx.sess.opts.target_triple.triple().starts_with("wasm32") {
1088+
if tcx.sess.target.is_like_wasm {
10891089
let name_metadata = llvm::LLVMMDStringInContext(
10901090
debug_context.llcontext,
10911091
rustc_producer.as_ptr().cast(),

compiler/rustc_codegen_ssa/src/back/linker.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ impl<'a> GccLinker<'a> {
186186
// * On OSX they have their own linker, not binutils'
187187
// * For WebAssembly the only functional linker is LLD, which doesn't
188188
// support hint flags
189-
!self.sess.target.is_like_osx && self.sess.target.arch != "wasm32"
189+
!self.sess.target.is_like_osx && !self.sess.target.is_like_wasm
190190
}
191191

192192
// Some platforms take hints about whether a library is static or dynamic.

compiler/rustc_codegen_ssa/src/target_features.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ pub fn supported_target_features(sess: &Session) -> &'static [(&'static str, Opt
161161
"mips" | "mips64" => MIPS_ALLOWED_FEATURES,
162162
"powerpc" | "powerpc64" => POWERPC_ALLOWED_FEATURES,
163163
"riscv32" | "riscv64" => RISCV_ALLOWED_FEATURES,
164-
"wasm32" => WASM_ALLOWED_FEATURES,
164+
"wasm32" | "wasm64" => WASM_ALLOWED_FEATURES,
165165
_ => &[],
166166
}
167167
}

compiler/rustc_session/src/config.rs

+3
Original file line numberDiff line numberDiff line change
@@ -822,6 +822,9 @@ pub fn default_configuration(sess: &Session) -> CrateConfig {
822822
}
823823
}
824824
ret.insert((sym::target_arch, Some(Symbol::intern(arch))));
825+
if sess.target.is_like_wasm {
826+
ret.insert((sym::wasm, None));
827+
}
825828
ret.insert((sym::target_endian, Some(Symbol::intern(end.as_str()))));
826829
ret.insert((sym::target_pointer_width, Some(Symbol::intern(&wordsz))));
827830
ret.insert((sym::target_env, Some(Symbol::intern(env))));

compiler/rustc_span/src/symbol.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1294,6 +1294,7 @@ symbols! {
12941294
vreg,
12951295
vreg_low16,
12961296
warn,
1297+
wasm,
12971298
wasm_import_module,
12981299
wasm_target_feature,
12991300
while_let,

compiler/rustc_symbol_mangling/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ fn compute_symbol_name(
198198
//
199199
// [1]: https://bugs.llvm.org/show_bug.cgi?id=44316
200200
if is_foreign
201-
&& (tcx.sess.target.arch != "wasm32"
201+
&& (!tcx.sess.target.is_like_wasm
202202
|| !tcx.wasm_import_module_map(def_id.krate).contains_key(&def_id))
203203
{
204204
if let Some(name) = attrs.link_name {

compiler/rustc_target/src/abi/call/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ mod sparc;
2020
mod sparc64;
2121
mod wasm32;
2222
mod wasm32_bindgen_compat;
23+
mod wasm64;
2324
mod x86;
2425
mod x86_64;
2526
mod x86_win64;
@@ -652,6 +653,7 @@ impl<'a, Ty> FnAbi<'a, Ty> {
652653
_ => wasm32_bindgen_compat::compute_abi_info(self),
653654
},
654655
"asmjs" => wasm32::compute_abi_info(cx, self),
656+
"wasm64" => wasm64::compute_abi_info(cx, self),
655657
a => return Err(format!("unrecognized arch \"{}\" in target specification", a)),
656658
}
657659

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
use crate::abi::call::{ArgAbi, FnAbi, Uniform};
2+
use crate::abi::{HasDataLayout, LayoutOf, TyAndLayout, TyAndLayoutMethods};
3+
4+
fn unwrap_trivial_aggregate<'a, Ty, C>(cx: &C, val: &mut ArgAbi<'a, Ty>) -> bool
5+
where
6+
Ty: TyAndLayoutMethods<'a, C> + Copy,
7+
C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
8+
{
9+
if val.layout.is_aggregate() {
10+
if let Some(unit) = val.layout.homogeneous_aggregate(cx).ok().and_then(|ha| ha.unit()) {
11+
let size = val.layout.size;
12+
if unit.size == size {
13+
val.cast_to(Uniform { unit, total: size });
14+
return true;
15+
}
16+
}
17+
}
18+
false
19+
}
20+
21+
fn classify_ret<'a, Ty, C>(cx: &C, ret: &mut ArgAbi<'a, Ty>)
22+
where
23+
Ty: TyAndLayoutMethods<'a, C> + Copy,
24+
C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
25+
{
26+
ret.extend_integer_width_to(64);
27+
if ret.layout.is_aggregate() && !unwrap_trivial_aggregate(cx, ret) {
28+
ret.make_indirect();
29+
}
30+
}
31+
32+
fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>)
33+
where
34+
Ty: TyAndLayoutMethods<'a, C> + Copy,
35+
C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
36+
{
37+
arg.extend_integer_width_to(64);
38+
if arg.layout.is_aggregate() && !unwrap_trivial_aggregate(cx, arg) {
39+
arg.make_indirect_byval();
40+
}
41+
}
42+
43+
pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
44+
where
45+
Ty: TyAndLayoutMethods<'a, C> + Copy,
46+
C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
47+
{
48+
if !fn_abi.ret.is_ignore() {
49+
classify_ret(cx, &mut fn_abi.ret);
50+
}
51+
52+
for arg in &mut fn_abi.args {
53+
if arg.is_ignore() {
54+
continue;
55+
}
56+
classify_arg(cx, arg);
57+
}
58+
}

compiler/rustc_target/src/spec/mod.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ mod solaris_base;
7979
mod thumb_base;
8080
mod uefi_msvc_base;
8181
mod vxworks_base;
82-
mod wasm32_base;
82+
mod wasm_base;
8383
mod windows_gnu_base;
8484
mod windows_msvc_base;
8585
mod windows_uwp_gnu_base;
@@ -842,6 +842,7 @@ supported_targets! {
842842
("wasm32-unknown-emscripten", wasm32_unknown_emscripten),
843843
("wasm32-unknown-unknown", wasm32_unknown_unknown),
844844
("wasm32-wasi", wasm32_wasi),
845+
("wasm64-unknown-unknown", wasm64_unknown_unknown),
845846

846847
("thumbv6m-none-eabi", thumbv6m_none_eabi),
847848
("thumbv7m-none-eabi", thumbv7m_none_eabi),
@@ -1076,6 +1077,8 @@ pub struct TargetOptions {
10761077
pub is_like_emscripten: bool,
10771078
/// Whether the target toolchain is like Fuchsia's.
10781079
pub is_like_fuchsia: bool,
1080+
/// Whether a target toolchain is like WASM.
1081+
pub is_like_wasm: bool,
10791082
/// Version of DWARF to use if not using the default.
10801083
/// Useful because some platforms (osx, bsd) only want up to DWARF2.
10811084
pub dwarf_version: Option<u32>,
@@ -1295,6 +1298,7 @@ impl Default for TargetOptions {
12951298
is_like_emscripten: false,
12961299
is_like_msvc: false,
12971300
is_like_fuchsia: false,
1301+
is_like_wasm: false,
12981302
dwarf_version: None,
12991303
linker_is_gnu: false,
13001304
allows_weak_linkage: true,
@@ -1789,6 +1793,7 @@ impl Target {
17891793
key!(is_like_msvc, bool);
17901794
key!(is_like_emscripten, bool);
17911795
key!(is_like_fuchsia, bool);
1796+
key!(is_like_wasm, bool);
17921797
key!(dwarf_version, Option<u32>);
17931798
key!(linker_is_gnu, bool);
17941799
key!(allows_weak_linkage, bool);
@@ -2027,6 +2032,7 @@ impl ToJson for Target {
20272032
target_option_val!(is_like_msvc);
20282033
target_option_val!(is_like_emscripten);
20292034
target_option_val!(is_like_fuchsia);
2035+
target_option_val!(is_like_wasm);
20302036
target_option_val!(dwarf_version);
20312037
target_option_val!(linker_is_gnu);
20322038
target_option_val!(allows_weak_linkage);

compiler/rustc_target/src/spec/tests/tests_impl.rs

+1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ impl Target {
5050
// and you certainly want "unknown" for the OS name.
5151
fn can_use_os_unknown(&self) -> bool {
5252
self.llvm_target == "wasm32-unknown-unknown"
53+
|| self.llvm_target == "wasm64-unknown-unknown"
5354
|| (self.env == "sgx" && self.vendor == "fortanix")
5455
}
5556
}

compiler/rustc_target/src/spec/wasm32_unknown_emscripten.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
use super::wasm32_base;
1+
use super::wasm_base;
22
use super::{LinkArgs, LinkerFlavor, PanicStrategy, Target, TargetOptions};
33

44
pub fn target() -> Target {
5-
let mut options = wasm32_base::options();
5+
let mut options = wasm_base::options();
66

77
let clang_args = options.pre_link_args.entry(LinkerFlavor::Gcc).or_default();
88

compiler/rustc_target/src/spec/wasm32_unknown_unknown.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@
1010
//! This target is more or less managed by the Rust and WebAssembly Working
1111
//! Group nowadays at <https://github.com/rustwasm>.
1212
13-
use super::wasm32_base;
13+
use super::wasm_base;
1414
use super::{LinkerFlavor, LldFlavor, Target};
1515

1616
pub fn target() -> Target {
17-
let mut options = wasm32_base::options();
17+
let mut options = wasm_base::options();
1818
options.os = "unknown".to_string();
1919
options.linker_flavor = LinkerFlavor::Lld(LldFlavor::Wasm);
2020
let clang_args = options.pre_link_args.entry(LinkerFlavor::Gcc).or_default();

compiler/rustc_target/src/spec/wasm32_wasi.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,11 @@
7272
//! best we can with this target. Don't start relying on too much here unless
7373
//! you know what you're getting in to!
7474
75-
use super::wasm32_base;
75+
use super::wasm_base;
7676
use super::{crt_objects, LinkerFlavor, LldFlavor, Target};
7777

7878
pub fn target() -> Target {
79-
let mut options = wasm32_base::options();
79+
let mut options = wasm_base::options();
8080

8181
options.os = "wasi".to_string();
8282
options.linker_flavor = LinkerFlavor::Lld(LldFlavor::Wasm);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
//! A "bare wasm" target representing a WebAssembly output that makes zero
2+
//! assumptions about its environment.
3+
//!
4+
//! The `wasm64-unknown-unknown` target is intended to encapsulate use cases
5+
//! that do not rely on any imported functionality. The binaries generated are
6+
//! entirely self-contained by default when using the standard library. Although
7+
//! the standard library is available, most of it returns an error immediately
8+
//! (e.g. trying to create a TCP stream or something like that).
9+
10+
use super::wasm_base;
11+
use super::{LinkerFlavor, LldFlavor, Target};
12+
13+
pub fn target() -> Target {
14+
let mut options = wasm_base::options();
15+
options.os = "unknown".to_string();
16+
options.linker_flavor = LinkerFlavor::Lld(LldFlavor::Wasm);
17+
let clang_args = options.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap();
18+
19+
// Make sure clang uses LLD as its linker and is configured appropriately
20+
// otherwise
21+
clang_args.push("--target=wasm64-unknown-unknown".to_string());
22+
23+
// For now this target just never has an entry symbol no matter the output
24+
// type, so unconditionally pass this.
25+
clang_args.push("-Wl,--no-entry".to_string());
26+
options
27+
.pre_link_args
28+
.get_mut(&LinkerFlavor::Lld(LldFlavor::Wasm))
29+
.unwrap()
30+
.push("--no-entry".to_string());
31+
32+
Target {
33+
llvm_target: "wasm64-unknown-unknown".to_string(),
34+
pointer_width: 64,
35+
data_layout: "e-m:e-p:64:64-i64:64-n32:64-S128".to_string(),
36+
arch: "wasm64".to_string(),
37+
options,
38+
}
39+
}

compiler/rustc_target/src/spec/wasm32_base.rs renamed to compiler/rustc_target/src/spec/wasm_base.rs

+2
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ pub fn options() -> TargetOptions {
6060
pre_link_args.insert(LinkerFlavor::Gcc, clang_args);
6161

6262
TargetOptions {
63+
is_like_wasm: true,
64+
6365
// we allow dynamic linking, but only cdylibs. Basically we allow a
6466
// final library artifact that exports some symbols (a wasm module) but
6567
// we don't allow intermediate `dylib` crate types

src/doc/rustc/src/platform-support.md

+1
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,7 @@ target | std | host | notes
216216
`thumbv7a-uwp-windows-msvc` | ✓ | |
217217
`thumbv7neon-unknown-linux-musleabihf` | ? | | Thumb2-mode ARMv7a Linux with NEON, MUSL
218218
`thumbv4t-none-eabi` | * | | ARMv4T T32
219+
`wasm64-unknown-unknown` | * | | WebAssembly
219220
`x86_64-apple-ios-macabi` | ✓ | | Apple Catalyst on x86_64
220221
`x86_64-apple-tvos` | * | | x86 64-bit tvOS
221222
`x86_64-unknown-none-linuxkernel` | * | | Linux kernel modules

src/librustdoc/clean/cfg.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,7 @@ impl<'a> fmt::Display for Display<'a> {
487487
"windows" => "Windows",
488488
_ => "",
489489
},
490+
(sym::wasm, None) => "WebAssembly",
490491
(sym::target_arch, Some(arch)) => match &*arch.as_str() {
491492
"aarch64" => "AArch64",
492493
"arm" => "ARM",
@@ -498,7 +499,7 @@ impl<'a> fmt::Display for Display<'a> {
498499
"powerpc64" => "PowerPC-64",
499500
"s390x" => "s390x",
500501
"sparc64" => "SPARC64",
501-
"wasm32" => "WebAssembly",
502+
"wasm32" | "wasm64" => "WebAssembly",
502503
"x86" => "x86",
503504
"x86_64" => "x86-64",
504505
_ => "",

0 commit comments

Comments
 (0)