mirror of https://github.com/rust-lang/rust.git
200 lines
5.0 KiB
Rust
200 lines
5.0 KiB
Rust
// FIXME: add wasm32-unknown when the wasm32-unknown-unknown ABI is fixed
|
|
// see https://github.com/rust-lang/rust/issues/115666
|
|
//@ revisions: wasm64-unknown wasm32-wasip1
|
|
//@ add-core-stubs
|
|
//@ assembly-output: emit-asm
|
|
//@ [wasm64-unknown] compile-flags: --target wasm64-unknown-unknown
|
|
//@ [wasm32-wasip1] compile-flags: --target wasm32-wasip1
|
|
//@ [wasm64-unknown] needs-llvm-components: webassembly
|
|
//@ [wasm32-wasip1] needs-llvm-components: webassembly
|
|
|
|
#![crate_type = "lib"]
|
|
#![feature(no_core, naked_functions, asm_experimental_arch, f128, linkage, fn_align)]
|
|
#![no_core]
|
|
|
|
extern crate minicore;
|
|
use minicore::*;
|
|
|
|
// CHECK: .section .text.nop,"",@
|
|
// CHECK: .globl nop
|
|
// CHECK-LABEL: nop:
|
|
// CHECK: .functype nop () -> ()
|
|
// CHECK-NOT: .size
|
|
// CHECK: end_function
|
|
#[no_mangle]
|
|
#[naked]
|
|
unsafe extern "C" fn nop() {
|
|
naked_asm!("nop")
|
|
}
|
|
|
|
// CHECK: .section .text.weak_aligned_nop,"",@
|
|
// CHECK: .weak weak_aligned_nop
|
|
// CHECK-LABEL: nop:
|
|
// CHECK: .functype weak_aligned_nop () -> ()
|
|
// CHECK-NOT: .size
|
|
// CHECK: end_function
|
|
#[no_mangle]
|
|
#[naked]
|
|
#[linkage = "weak"]
|
|
// wasm functions cannot be aligned, so this has no effect
|
|
#[repr(align(32))]
|
|
unsafe extern "C" fn weak_aligned_nop() {
|
|
naked_asm!("nop")
|
|
}
|
|
|
|
// CHECK-LABEL: fn_i8_i8:
|
|
// CHECK-NEXT: .functype fn_i8_i8 (i32) -> (i32)
|
|
//
|
|
// CHECK-NEXT: local.get 0
|
|
// CHECK-NEXT: local.get 0
|
|
// CHECK-NEXT: i32.mul
|
|
//
|
|
// CHECK-NEXT: end_function
|
|
#[no_mangle]
|
|
#[naked]
|
|
unsafe extern "C" fn fn_i8_i8(num: i8) -> i8 {
|
|
naked_asm!("local.get 0", "local.get 0", "i32.mul")
|
|
}
|
|
|
|
// CHECK-LABEL: fn_i8_i8_i8:
|
|
// CHECK: .functype fn_i8_i8_i8 (i32, i32) -> (i32)
|
|
#[no_mangle]
|
|
#[naked]
|
|
unsafe extern "C" fn fn_i8_i8_i8(a: i8, b: i8) -> i8 {
|
|
naked_asm!("local.get 1", "local.get 0", "i32.mul")
|
|
}
|
|
|
|
// CHECK-LABEL: fn_unit_i8:
|
|
// CHECK: .functype fn_unit_i8 () -> (i32)
|
|
#[no_mangle]
|
|
#[naked]
|
|
unsafe extern "C" fn fn_unit_i8() -> i8 {
|
|
naked_asm!("i32.const 42")
|
|
}
|
|
|
|
// CHECK-LABEL: fn_i8_unit:
|
|
// CHECK: .functype fn_i8_unit (i32) -> ()
|
|
#[no_mangle]
|
|
#[naked]
|
|
unsafe extern "C" fn fn_i8_unit(_: i8) {
|
|
naked_asm!("nop")
|
|
}
|
|
|
|
// CHECK-LABEL: fn_i32_i32:
|
|
// CHECK: .functype fn_i32_i32 (i32) -> (i32)
|
|
#[no_mangle]
|
|
#[naked]
|
|
unsafe extern "C" fn fn_i32_i32(num: i32) -> i32 {
|
|
naked_asm!("local.get 0", "local.get 0", "i32.mul")
|
|
}
|
|
|
|
// CHECK-LABEL: fn_i64_i64:
|
|
// CHECK: .functype fn_i64_i64 (i64) -> (i64)
|
|
#[no_mangle]
|
|
#[naked]
|
|
unsafe extern "C" fn fn_i64_i64(num: i64) -> i64 {
|
|
naked_asm!("local.get 0", "local.get 0", "i64.mul")
|
|
}
|
|
|
|
// CHECK-LABEL: fn_i128_i128:
|
|
// wasm32-wasip1: .functype fn_i128_i128 (i32, i64, i64) -> ()
|
|
// wasm64-unknown: .functype fn_i128_i128 (i64, i64, i64) -> ()
|
|
#[allow(improper_ctypes_definitions)]
|
|
#[no_mangle]
|
|
#[naked]
|
|
unsafe extern "C" fn fn_i128_i128(num: i128) -> i128 {
|
|
naked_asm!(
|
|
"local.get 0",
|
|
"local.get 2",
|
|
"i64.store 8",
|
|
"local.get 0",
|
|
"local.get 1",
|
|
"i64.store 0",
|
|
)
|
|
}
|
|
|
|
// CHECK-LABEL: fn_f128_f128:
|
|
// wasm32-wasip1: .functype fn_f128_f128 (i32, i64, i64) -> ()
|
|
// wasm64-unknown: .functype fn_f128_f128 (i64, i64, i64) -> ()
|
|
#[no_mangle]
|
|
#[naked]
|
|
unsafe extern "C" fn fn_f128_f128(num: f128) -> f128 {
|
|
naked_asm!(
|
|
"local.get 0",
|
|
"local.get 2",
|
|
"i64.store 8",
|
|
"local.get 0",
|
|
"local.get 1",
|
|
"i64.store 0",
|
|
)
|
|
}
|
|
|
|
#[repr(C)]
|
|
struct Compound {
|
|
a: u16,
|
|
b: i64,
|
|
}
|
|
|
|
// CHECK-LABEL: fn_compound_compound:
|
|
// wasm32-wasip1: .functype fn_compound_compound (i32, i32) -> ()
|
|
// wasm64-unknown: .functype fn_compound_compound (i64, i64) -> ()
|
|
#[no_mangle]
|
|
#[naked]
|
|
unsafe extern "C" fn fn_compound_compound(_: Compound) -> Compound {
|
|
// this is the wasm32-wasip1 assembly
|
|
naked_asm!(
|
|
"local.get 0",
|
|
"local.get 1",
|
|
"i64.load 8",
|
|
"i64.store 8",
|
|
"local.get 0",
|
|
"local.get 1",
|
|
"i32.load16_u 0",
|
|
"i32.store16 0",
|
|
)
|
|
}
|
|
|
|
#[repr(C)]
|
|
struct WrapperI32(i32);
|
|
|
|
// CHECK-LABEL: fn_wrapperi32_wrapperi32:
|
|
// CHECK: .functype fn_wrapperi32_wrapperi32 (i32) -> (i32)
|
|
#[no_mangle]
|
|
#[naked]
|
|
unsafe extern "C" fn fn_wrapperi32_wrapperi32(_: WrapperI32) -> WrapperI32 {
|
|
naked_asm!("local.get 0")
|
|
}
|
|
|
|
#[repr(C)]
|
|
struct WrapperI64(i64);
|
|
|
|
// CHECK-LABEL: fn_wrapperi64_wrapperi64:
|
|
// CHECK: .functype fn_wrapperi64_wrapperi64 (i64) -> (i64)
|
|
#[no_mangle]
|
|
#[naked]
|
|
unsafe extern "C" fn fn_wrapperi64_wrapperi64(_: WrapperI64) -> WrapperI64 {
|
|
naked_asm!("local.get 0")
|
|
}
|
|
|
|
#[repr(C)]
|
|
struct WrapperF32(f32);
|
|
|
|
// CHECK-LABEL: fn_wrapperf32_wrapperf32:
|
|
// CHECK: .functype fn_wrapperf32_wrapperf32 (f32) -> (f32)
|
|
#[no_mangle]
|
|
#[naked]
|
|
unsafe extern "C" fn fn_wrapperf32_wrapperf32(_: WrapperF32) -> WrapperF32 {
|
|
naked_asm!("local.get 0")
|
|
}
|
|
|
|
#[repr(C)]
|
|
struct WrapperF64(f64);
|
|
|
|
// CHECK-LABEL: fn_wrapperf64_wrapperf64:
|
|
// CHECK: .functype fn_wrapperf64_wrapperf64 (f64) -> (f64)
|
|
#[no_mangle]
|
|
#[naked]
|
|
unsafe extern "C" fn fn_wrapperf64_wrapperf64(_: WrapperF64) -> WrapperF64 {
|
|
naked_asm!("local.get 0")
|
|
}
|