diff --git a/Cargo.lock b/Cargo.lock index 15fdc60c99f..64a2ed70a51 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -680,9 +680,9 @@ dependencies = [ [[package]] name = "compiler_builtins" -version = "0.1.55" +version = "0.1.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9ac60765140c97aaf531dae151a287646b0805ec725805da9e2a3ee31cd501c" +checksum = "ed37ea958309f2451e1cea7fd2b37aa56b1894c9a9fbdbbe6a194f7b78f0362d" dependencies = [ "cc", "rustc-std-workspace-core", diff --git a/compiler/rustc_codegen_gcc/tests/run/asm.rs b/compiler/rustc_codegen_gcc/tests/run/asm.rs index 9c0055b0b6b..48c0203d594 100644 --- a/compiler/rustc_codegen_gcc/tests/run/asm.rs +++ b/compiler/rustc_codegen_gcc/tests/run/asm.rs @@ -3,8 +3,6 @@ // Run-time: // status: 0 -#![feature(asm, global_asm)] - global_asm!(" .global add_asm add_asm: diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 5dbcc1655c9..61695109a89 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -3147,7 +3147,8 @@ fn is_zero(expr: &hir::Expr<'_>) -> bool { /// ### Example /// /// ```rust,compile_fail - /// #![feature(asm)] + /// use std::arch::asm; + /// /// fn main() { /// unsafe { /// asm!("foo: bar"); @@ -3164,10 +3165,7 @@ fn is_zero(expr: &hir::Expr<'_>) -> bool { /// of this, GNU assembler [local labels] *must* be used instead of labels /// with a name. Using named labels might cause assembler or linker errors. /// - /// See the [unstable book] for more details. - /// /// [local labels]: https://sourceware.org/binutils/docs/as/Symbol-Names.html#Local-Labels - /// [unstable book]: https://doc.rust-lang.org/nightly/unstable-book/library-features/asm.html#labels pub NAMED_ASM_LABELS, Deny, "named labels in inline assembly", diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index 3c79020523a..800b6d4a79d 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -772,7 +772,7 @@ fn lookup_with_diagnostics( } BuiltinLintDiagnostics::NamedAsmLabel(help) => { db.help(&help); - db.note("see the asm section of the unstable book for more information"); + //db.note("see the asm section of the unstable book for more information"); } } // Rewrap `db`, and pass control to the user. diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index c9294c68a7d..d1adb4a19de 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -2419,8 +2419,8 @@ /// /// ### Example /// - /// ```rust,ignore (fails on system llvm) - /// #![feature(asm)] + /// ```rust + /// use std::arch::asm; /// /// fn main() { /// #[cfg(target_arch="x86_64")] @@ -2430,19 +2430,7 @@ /// } /// ``` /// - /// This will produce: - /// - /// ```text - /// warning: formatting may not be suitable for sub-register argument - /// --> src/main.rs:6:19 - /// | - /// 6 | asm!("mov {0}, {0}", in(reg) 0i16); - /// | ^^^ ^^^ ---- for this argument - /// | - /// = note: `#[warn(asm_sub_register)]` on by default - /// = help: use the `x` modifier to have the register formatted as `ax` - /// = help: or use the `r` modifier to keep the default formatting of `rax` - /// ``` + /// {{produces}} /// /// ### Explanation /// @@ -2455,10 +2443,6 @@ /// register size, to alert you of possibly using the incorrect width. To /// fix this, add the suggested modifier to the template, or cast the /// value to the correct size. - /// - /// See [register template modifiers] for more details. - /// - /// [register template modifiers]: https://doc.rust-lang.org/nightly/unstable-book/library-features/asm.html#register-template-modifiers pub ASM_SUB_REGISTER, Warn, "using only a subset of a register for inline asm inputs", @@ -2470,34 +2454,21 @@ /// /// ### Example /// - /// ```rust,ignore (fails on system llvm) - /// #![feature(asm)] + /// ```rust + /// use std::arch::asm; /// /// fn main() { /// #[cfg(target_arch="x86_64")] /// unsafe { /// asm!( /// ".att_syntax", - /// "movl {0}, {0}", in(reg) 0usize + /// "movq %{0}, %{0}", in(reg) 0usize /// ); /// } /// } /// ``` /// - /// This will produce: - /// - /// ```text - /// warning: avoid using `.att_syntax`, prefer using `options(att_syntax)` instead - /// --> test.rs:7:14 - /// | - /// 7 | ".att_syntax", - /// | ^^^^^^^^^^^ - /// 8 | "movq {0}, {0}", out(reg) _, - /// 9 | ); - /// | - help: add option: `, options(att_syntax)` - /// | - /// = note: `#[warn(bad_asm_style)]` on by default - /// ``` + /// {{produces}} /// /// ### Explanation /// @@ -2739,7 +2710,8 @@ /// /// ```rust /// #![feature(naked_functions)] - /// #![feature(asm)] + /// + /// use std::arch::asm; /// /// #[naked] /// pub fn default_abi() -> u32 { diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index d9a40a9b2ec..a2c95b253f8 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -152,7 +152,6 @@ #![feature(abi_unadjusted)] #![feature(allow_internal_unsafe)] #![feature(allow_internal_unstable)] -#![feature(asm)] #![feature(associated_type_bounds)] #![feature(auto_traits)] #![feature(cfg_target_has_atomic)] @@ -372,26 +371,14 @@ pub mod arch { pub use crate::core_arch::arch::*; /// Inline assembly. - /// - /// Read the [unstable book] for the usage. - /// - /// [unstable book]: ../../unstable-book/library-features/asm.html - #[unstable( - feature = "asm", - issue = "72016", - reason = "inline assembly is not stable enough for use and is subject to change" - )] + #[stable(feature = "asm", since = "1.59.0")] #[rustc_builtin_macro] pub macro asm("assembly template", $(operands,)* $(options($(option),*))?) { /* compiler built-in */ } /// Module-level inline assembly. - #[unstable( - feature = "global_asm", - issue = "35119", - reason = "`global_asm!` is not stable enough for use and is subject to change" - )] + #[stable(feature = "global_asm", since = "1.59.0")] #[rustc_builtin_macro] pub macro global_asm("assembly template", $(operands,)* $(options($(option),*))?) { /* compiler built-in */ diff --git a/library/core/src/num/dec2flt/fpu.rs b/library/core/src/num/dec2flt/fpu.rs index 24492d9a1dd..ec5fa45fdad 100644 --- a/library/core/src/num/dec2flt/fpu.rs +++ b/library/core/src/num/dec2flt/fpu.rs @@ -10,6 +10,7 @@ // computations are performed in the desired precision. #[cfg(all(target_arch = "x86", not(target_feature = "sse2")))] mod fpu_precision { + use core::arch::asm; use core::mem::size_of; /// A structure used to preserve the original value of the FPU control word, so that it can be diff --git a/library/core/src/prelude/v1.rs b/library/core/src/prelude/v1.rs index 8705eb39468..54f498d1dc1 100644 --- a/library/core/src/prelude/v1.rs +++ b/library/core/src/prelude/v1.rs @@ -69,22 +69,6 @@ #[doc(no_inline)] pub use crate::concat_bytes; -#[unstable( - feature = "asm", - issue = "72016", - reason = "inline assembly is not stable enough for use and is subject to change" -)] -#[doc(no_inline)] -pub use crate::arch::asm; - -#[unstable( - feature = "global_asm", - issue = "35119", - reason = "`global_asm!` is not stable enough for use and is subject to change" -)] -#[doc(no_inline)] -pub use crate::arch::global_asm; - #[stable(feature = "builtin_macro_prelude", since = "1.38.0")] #[allow(deprecated, deprecated_in_future)] #[doc(no_inline)] diff --git a/library/panic_abort/src/lib.rs b/library/panic_abort/src/lib.rs index dec5e0b2123..5c5632a9d01 100644 --- a/library/panic_abort/src/lib.rs +++ b/library/panic_abort/src/lib.rs @@ -14,7 +14,6 @@ #![feature(std_internals)] #![feature(staged_api)] #![feature(rustc_attrs)] -#![feature(asm)] #![feature(c_unwind)] #[cfg(target_os = "android")] @@ -69,11 +68,11 @@ unsafe fn abort() -> ! { const FAST_FAIL_FATAL_APP_EXIT: usize = 7; cfg_if::cfg_if! { if #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] { - asm!("int $$0x29", in("ecx") FAST_FAIL_FATAL_APP_EXIT); + core::arch::asm!("int $$0x29", in("ecx") FAST_FAIL_FATAL_APP_EXIT); } else if #[cfg(all(target_arch = "arm", target_feature = "thumb-mode"))] { - asm!(".inst 0xDEFB", in("r0") FAST_FAIL_FATAL_APP_EXIT); + core::arch::asm!(".inst 0xDEFB", in("r0") FAST_FAIL_FATAL_APP_EXIT); } else if #[cfg(target_arch = "aarch64")] { - asm!("brk 0xF003", in("x0") FAST_FAIL_FATAL_APP_EXIT); + core::arch::asm!("brk 0xF003", in("x0") FAST_FAIL_FATAL_APP_EXIT); } else { core::intrinsics::abort(); } diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index f7111748321..b71faf76f69 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -16,7 +16,7 @@ panic_unwind = { path = "../panic_unwind", optional = true } panic_abort = { path = "../panic_abort" } core = { path = "../core" } libc = { version = "0.2.108", default-features = false, features = ['rustc-dep-of-std'] } -compiler_builtins = { version = "0.1.55" } +compiler_builtins = { version = "0.1.65" } profiler_builtins = { path = "../profiler_builtins", optional = true } unwind = { path = "../unwind" } hashbrown = { version = "0.11", default-features = false, features = ['rustc-dep-of-std'] } diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index d4ff642cd13..b725fc8bd52 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -233,7 +233,6 @@ #![feature(allow_internal_unstable)] #![feature(arbitrary_self_types)] #![feature(array_error_internals)] -#![feature(asm)] #![feature(assert_matches)] #![feature(associated_type_bounds)] #![feature(async_stream)] @@ -288,7 +287,6 @@ #![feature(gen_future)] #![feature(generator_trait)] #![feature(get_mut_unchecked)] -#![feature(global_asm)] #![feature(hashmap_internals)] #![feature(int_error_internals)] #![feature(integer_atomics)] diff --git a/library/std/src/os/fortanix_sgx/arch.rs b/library/std/src/os/fortanix_sgx/arch.rs index 4ce482e23cb..8358cb9e81b 100644 --- a/library/std/src/os/fortanix_sgx/arch.rs +++ b/library/std/src/os/fortanix_sgx/arch.rs @@ -5,6 +5,7 @@ #![unstable(feature = "sgx_platform", issue = "56975")] use crate::mem::MaybeUninit; +use core::arch::asm; /// Wrapper struct to force 16-byte alignment. #[repr(align(16))] diff --git a/library/std/src/prelude/v1.rs b/library/std/src/prelude/v1.rs index 9b23aa37e31..743dd51333d 100644 --- a/library/std/src/prelude/v1.rs +++ b/library/std/src/prelude/v1.rs @@ -54,22 +54,6 @@ #[doc(no_inline)] pub use core::prelude::v1::concat_bytes; -#[unstable( - feature = "asm", - issue = "72016", - reason = "inline assembly is not stable enough for use and is subject to change" -)] -#[doc(no_inline)] -pub use core::prelude::v1::asm; - -#[unstable( - feature = "global_asm", - issue = "35119", - reason = "`global_asm!` is not stable enough for use and is subject to change" -)] -#[doc(no_inline)] -pub use core::prelude::v1::global_asm; - // FIXME: Attribute and internal derive macros are not documented because for them rustdoc generates // dead links which fail link checker testing. #[stable(feature = "builtin_macro_prelude", since = "1.38.0")] diff --git a/library/std/src/sys/sgx/abi/mem.rs b/library/std/src/sys/sgx/abi/mem.rs index 52e8bec937c..18e6d5b3fa2 100644 --- a/library/std/src/sys/sgx/abi/mem.rs +++ b/library/std/src/sys/sgx/abi/mem.rs @@ -1,3 +1,5 @@ +use core::arch::asm; + // Do not remove inline: will result in relocation failure #[inline(always)] pub(crate) unsafe fn rel_ptr(offset: u64) -> *const T { diff --git a/library/std/src/sys/sgx/abi/mod.rs b/library/std/src/sys/sgx/abi/mod.rs index 231cc15b849..5df08a4ff59 100644 --- a/library/std/src/sys/sgx/abi/mod.rs +++ b/library/std/src/sys/sgx/abi/mod.rs @@ -1,6 +1,7 @@ #![cfg_attr(test, allow(unused))] // RT initialization logic is not compiled for test use crate::io::Write; +use core::arch::global_asm; use core::sync::atomic::{AtomicUsize, Ordering}; // runtime features diff --git a/library/std/src/sys/solid/abi/mod.rs b/library/std/src/sys/solid/abi/mod.rs index 3205f0db85f..bbbee4fd6d1 100644 --- a/library/std/src/sys/solid/abi/mod.rs +++ b/library/std/src/sys/solid/abi/mod.rs @@ -10,9 +10,9 @@ pub fn breakpoint_program_exited(tid: usize) { match () { // SOLID_BP_PROGRAM_EXITED = 15 #[cfg(target_arch = "arm")] - () => asm!("bkpt #15", in("r0") tid), - #[cfg(target_arch = "aarch64")] - () => asm!("hlt #15", in("x0") tid), + () => core::arch::asm!("bkpt #15", in("r0") tid), + #[cfg(core::arch::asm = "aarch64")] + () => core::arch::asm!("hlt #15", in("x0") tid), } } } @@ -23,9 +23,9 @@ pub fn breakpoint_abort() { match () { // SOLID_BP_CSABORT = 16 #[cfg(target_arch = "arm")] - () => asm!("bkpt #16"), + () => core::arch::asm!("bkpt #16"), #[cfg(target_arch = "aarch64")] - () => asm!("hlt #16"), + () => core::arch::asm!("hlt #16"), } } } diff --git a/library/std/src/sys/windows/mod.rs b/library/std/src/sys/windows/mod.rs index 28fec817f86..084af4325e7 100644 --- a/library/std/src/sys/windows/mod.rs +++ b/library/std/src/sys/windows/mod.rs @@ -288,13 +288,13 @@ pub fn abort_internal() -> ! { unsafe { cfg_if::cfg_if! { if #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] { - asm!("int $$0x29", in("ecx") FAST_FAIL_FATAL_APP_EXIT); + core::arch::asm!("int $$0x29", in("ecx") FAST_FAIL_FATAL_APP_EXIT); crate::intrinsics::unreachable(); } else if #[cfg(all(target_arch = "arm", target_feature = "thumb-mode"))] { - asm!(".inst 0xDEFB", in("r0") FAST_FAIL_FATAL_APP_EXIT); + core::arch::asm!(".inst 0xDEFB", in("r0") FAST_FAIL_FATAL_APP_EXIT); crate::intrinsics::unreachable(); } else if #[cfg(target_arch = "aarch64")] { - asm!("brk 0xF003", in("x0") FAST_FAIL_FATAL_APP_EXIT); + core::arch::asm!("brk 0xF003", in("x0") FAST_FAIL_FATAL_APP_EXIT); crate::intrinsics::unreachable(); } } diff --git a/library/stdarch b/library/stdarch index b70ae88ef2a..d219ad63c50 160000 --- a/library/stdarch +++ b/library/stdarch @@ -1 +1 @@ -Subproject commit b70ae88ef2a6c83acad0a1e83d5bd78f9655fd05 +Subproject commit d219ad63c5075098fc224a57deb4852b9734327d diff --git a/src/doc/unstable-book/src/compiler-flags/sanitizer.md b/src/doc/unstable-book/src/compiler-flags/sanitizer.md index b3dbc9a9956..b946d8cf21c 100644 --- a/src/doc/unstable-book/src/compiler-flags/sanitizer.md +++ b/src/doc/unstable-book/src/compiler-flags/sanitizer.md @@ -199,7 +199,7 @@ LLVM CFI can be enabled with -Zsanitizer=cfi and requires LTO (i.e., -Clto). ## Example ```text -#![feature(asm, naked_functions)] +#![feature(naked_functions)] use std::mem; diff --git a/src/doc/unstable-book/src/library-features/asm.md b/src/doc/unstable-book/src/library-features/asm.md deleted file mode 100644 index 59987cccde6..00000000000 --- a/src/doc/unstable-book/src/library-features/asm.md +++ /dev/null @@ -1,910 +0,0 @@ -# `asm` - -The tracking issue for this feature is: [#72016] - -[#72016]: https://github.com/rust-lang/rust/issues/72016 - ------------------------- - -For extremely low-level manipulations and performance reasons, one -might wish to control the CPU directly. Rust supports using inline -assembly to do this via the `asm!` macro. - -# Guide-level explanation -[guide-level-explanation]: #guide-level-explanation - -Rust provides support for inline assembly via the `asm!` macro. -It can be used to embed handwritten assembly in the assembly output generated by the compiler. -Generally this should not be necessary, but might be where the required performance or timing -cannot be otherwise achieved. Accessing low level hardware primitives, e.g. in kernel code, may also demand this functionality. - -> **Note**: the examples here are given in x86/x86-64 assembly, but other architectures are also supported. - -Inline assembly is currently supported on the following architectures: -- x86 and x86-64 -- ARM -- AArch64 -- RISC-V -- NVPTX -- PowerPC -- Hexagon -- MIPS32r2 and MIPS64r2 -- wasm32 -- BPF -- SPIR-V -- AVR - -## Basic usage - -Let us start with the simplest possible example: - -```rust,allow_fail -#![feature(asm)] -unsafe { - asm!("nop"); -} -``` - -This will insert a NOP (no operation) instruction into the assembly generated by the compiler. -Note that all `asm!` invocations have to be inside an `unsafe` block, as they could insert -arbitrary instructions and break various invariants. The instructions to be inserted are listed -in the first argument of the `asm!` macro as a string literal. - -## Inputs and outputs - -Now inserting an instruction that does nothing is rather boring. Let us do something that -actually acts on data: - -```rust,allow_fail -#![feature(asm)] -let x: u64; -unsafe { - asm!("mov {}, 5", out(reg) x); -} -assert_eq!(x, 5); -``` - -This will write the value `5` into the `u64` variable `x`. -You can see that the string literal we use to specify instructions is actually a template string. -It is governed by the same rules as Rust [format strings][format-syntax]. -The arguments that are inserted into the template however look a bit different than you may -be familiar with. First we need to specify if the variable is an input or an output of the -inline assembly. In this case it is an output. We declared this by writing `out`. -We also need to specify in what kind of register the assembly expects the variable. -In this case we put it in an arbitrary general purpose register by specifying `reg`. -The compiler will choose an appropriate register to insert into -the template and will read the variable from there after the inline assembly finishes executing. - -Let us see another example that also uses an input: - -```rust,allow_fail -#![feature(asm)] -let i: u64 = 3; -let o: u64; -unsafe { - asm!( - "mov {0}, {1}", - "add {0}, {number}", - out(reg) o, - in(reg) i, - number = const 5, - ); -} -assert_eq!(o, 8); -``` - -This will add `5` to the input in variable `i` and write the result to variable `o`. -The particular way this assembly does this is first copying the value from `i` to the output, -and then adding `5` to it. - -The example shows a few things: - -First, we can see that `asm!` allows multiple template string arguments; each -one is treated as a separate line of assembly code, as if they were all joined -together with newlines between them. This makes it easy to format assembly -code. - -Second, we can see that inputs are declared by writing `in` instead of `out`. - -Third, one of our operands has a type we haven't seen yet, `const`. -This tells the compiler to expand this argument to a value directly inside the assembly template. -This is only possible for constants and literals. - -Fourth, we can see that we can specify an argument number, or name as in any format string. -For inline assembly templates this is particularly useful as arguments are often used more than once. -For more complex inline assembly using this facility is generally recommended, as it improves -readability, and allows reordering instructions without changing the argument order. - -We can further refine the above example to avoid the `mov` instruction: - -```rust,allow_fail -#![feature(asm)] -let mut x: u64 = 3; -unsafe { - asm!("add {0}, {number}", inout(reg) x, number = const 5); -} -assert_eq!(x, 8); -``` - -We can see that `inout` is used to specify an argument that is both input and output. -This is different from specifying an input and output separately in that it is guaranteed to assign both to the same register. - -It is also possible to specify different variables for the input and output parts of an `inout` operand: - -```rust,allow_fail -#![feature(asm)] -let x: u64 = 3; -let y: u64; -unsafe { - asm!("add {0}, {number}", inout(reg) x => y, number = const 5); -} -assert_eq!(y, 8); -``` - -## Late output operands - -The Rust compiler is conservative with its allocation of operands. It is assumed that an `out` -can be written at any time, and can therefore not share its location with any other argument. -However, to guarantee optimal performance it is important to use as few registers as possible, -so they won't have to be saved and reloaded around the inline assembly block. -To achieve this Rust provides a `lateout` specifier. This can be used on any output that is -written only after all inputs have been consumed. -There is also a `inlateout` variant of this specifier. - -Here is an example where `inlateout` *cannot* be used: - -```rust,allow_fail -#![feature(asm)] -let mut a: u64 = 4; -let b: u64 = 4; -let c: u64 = 4; -unsafe { - asm!( - "add {0}, {1}", - "add {0}, {2}", - inout(reg) a, - in(reg) b, - in(reg) c, - ); -} -assert_eq!(a, 12); -``` - -Here the compiler is free to allocate the same register for inputs `b` and `c` since it knows they have the same value. However it must allocate a separate register for `a` since it uses `inout` and not `inlateout`. If `inlateout` was used, then `a` and `c` could be allocated to the same register, in which case the first instruction to overwrite the value of `c` and cause the assembly code to produce the wrong result. - -However the following example can use `inlateout` since the output is only modified after all input registers have been read: - -```rust,allow_fail -#![feature(asm)] -let mut a: u64 = 4; -let b: u64 = 4; -unsafe { - asm!("add {0}, {1}", inlateout(reg) a, in(reg) b); -} -assert_eq!(a, 8); -``` - -As you can see, this assembly fragment will still work correctly if `a` and `b` are assigned to the same register. - -## Explicit register operands - -Some instructions require that the operands be in a specific register. -Therefore, Rust inline assembly provides some more specific constraint specifiers. -While `reg` is generally available on any architecture, explicit registers are highly architecture specific. E.g. for x86 the general purpose registers `eax`, `ebx`, `ecx`, `edx`, `ebp`, `esi`, and `edi` among others can be addressed by their name. - -```rust,allow_fail,no_run -#![feature(asm)] -let cmd = 0xd1; -unsafe { - asm!("out 0x64, eax", in("eax") cmd); -} -``` - -In this example we call the `out` instruction to output the content of the `cmd` variable to port `0x64`. Since the `out` instruction only accepts `eax` (and its sub registers) as operand we had to use the `eax` constraint specifier. - -> **Note**: unlike other operand types, explicit register operands cannot be used in the template string: you can't use `{}` and should write the register name directly instead. Also, they must appear at the end of the operand list after all other operand types. - -Consider this example which uses the x86 `mul` instruction: - -```rust,allow_fail -#![feature(asm)] -fn mul(a: u64, b: u64) -> u128 { - let lo: u64; - let hi: u64; - - unsafe { - asm!( - // The x86 mul instruction takes rax as an implicit input and writes - // the 128-bit result of the multiplication to rax:rdx. - "mul {}", - in(reg) a, - inlateout("rax") b => lo, - lateout("rdx") hi - ); - } - - ((hi as u128) << 64) + lo as u128 -} -``` - -This uses the `mul` instruction to multiply two 64-bit inputs with a 128-bit result. -The only explicit operand is a register, that we fill from the variable `a`. -The second operand is implicit, and must be the `rax` register, which we fill from the variable `b`. -The lower 64 bits of the result are stored in `rax` from which we fill the variable `lo`. -The higher 64 bits are stored in `rdx` from which we fill the variable `hi`. - -## Clobbered registers - -In many cases inline assembly will modify state that is not needed as an output. -Usually this is either because we have to use a scratch register in the assembly or because instructions modify state that we don't need to further examine. -This state is generally referred to as being "clobbered". -We need to tell the compiler about this since it may need to save and restore this state around the inline assembly block. - -```rust,allow_fail -#![feature(asm)] -let ebx: u32; -let ecx: u32; - -unsafe { - asm!( - "cpuid", - // EAX 4 selects the "Deterministic Cache Parameters" CPUID leaf - inout("eax") 4 => _, - // ECX 0 selects the L0 cache information. - inout("ecx") 0 => ecx, - lateout("ebx") ebx, - lateout("edx") _, - ); -} - -println!( - "L0 Cache: {}", - ((ebx >> 22) + 1) * (((ebx >> 12) & 0x3ff) + 1) * ((ebx & 0xfff) + 1) * (ecx + 1) -); -``` - -In the example above we use the `cpuid` instruction to get the L1 cache size. -This instruction writes to `eax`, `ebx`, `ecx`, and `edx`, but for the cache size we only care about the contents of `ebx` and `ecx`. - -However we still need to tell the compiler that `eax` and `edx` have been modified so that it can save any values that were in these registers before the asm. This is done by declaring these as outputs but with `_` instead of a variable name, which indicates that the output value is to be discarded. - -This can also be used with a general register class (e.g. `reg`) to obtain a scratch register for use inside the asm code: - -```rust,allow_fail -#![feature(asm)] -// Multiply x by 6 using shifts and adds -let mut x: u64 = 4; -unsafe { - asm!( - "mov {tmp}, {x}", - "shl {tmp}, 1", - "shl {x}, 2", - "add {x}, {tmp}", - x = inout(reg) x, - tmp = out(reg) _, - ); -} -assert_eq!(x, 4 * 6); -``` - -## Symbol operands and ABI clobbers - -A special operand type, `sym`, allows you to use the symbol name of a `fn` or `static` in inline assembly code. -This allows you to call a function or access a global variable without needing to keep its address in a register. - -```rust,allow_fail -#![feature(asm)] -extern "C" fn foo(arg: i32) -> i32 { - println!("arg = {}", arg); - arg * 2 -} - -fn call_foo(arg: i32) -> i32 { - unsafe { - let result; - asm!( - "call {}", - sym foo, - // 1st argument in rdi - in("rdi") arg, - // Return value in rax - out("rax") result, - // Mark all registers which are not preserved by the "C" calling - // convention as clobbered. - clobber_abi("C"), - ); - result - } -} -``` - -Note that the `fn` or `static` item does not need to be public or `#[no_mangle]`: the compiler will automatically insert the appropriate mangled symbol name into the assembly code. - -By default, `asm!` assumes that any register not specified as an output will have its contents preserved by the assembly code. The [`clobber_abi`](#abi-clobbers) argument to `asm!` tells the compiler to automatically insert the necessary clobber operands according to the given calling convention ABI: any register which is not fully preserved in that ABI will be treated as clobbered. Multiple `clobber_abi` arguments may be provided and all clobbers from all specified ABIs will be inserted. - -## Register template modifiers - -In some cases, fine control is needed over the way a register name is formatted when inserted into the template string. This is needed when an architecture's assembly language has several names for the same register, each typically being a "view" over a subset of the register (e.g. the low 32 bits of a 64-bit register). - -By default the compiler will always choose the name that refers to the full register size (e.g. `rax` on x86-64, `eax` on x86, etc). - -This default can be overriden by using modifiers on the template string operands, just like you would with format strings: - -```rust,allow_fail -#![feature(asm)] -let mut x: u16 = 0xab; - -unsafe { - asm!("mov {0:h}, {0:l}", inout(reg_abcd) x); -} - -assert_eq!(x, 0xabab); -``` - -In this example, we use the `reg_abcd` register class to restrict the register allocator to the 4 legacy x86 register (`ax`, `bx`, `cx`, `dx`) of which the first two bytes can be addressed independently. - -Let us assume that the register allocator has chosen to allocate `x` in the `ax` register. -The `h` modifier will emit the register name for the high byte of that register and the `l` modifier will emit the register name for the low byte. The asm code will therefore be expanded as `mov ah, al` which copies the low byte of the value into the high byte. - -If you use a smaller data type (e.g. `u16`) with an operand and forget the use template modifiers, the compiler will emit a warning and suggest the correct modifier to use. - -## Memory address operands - -Sometimes assembly instructions require operands passed via memory addresses/memory locations. -You have to manually use the memory address syntax specified by the target architecture. -For example, on x86/x86_64 using intel assembly syntax, you should wrap inputs/outputs in `[]` to indicate they are memory operands: - -```rust,allow_fail -#![feature(asm, llvm_asm)] -# fn load_fpu_control_word(control: u16) { -unsafe { - asm!("fldcw [{}]", in(reg) &control, options(nostack)); - - // Previously this would have been written with the deprecated `llvm_asm!` like this - llvm_asm!("fldcw $0" :: "m" (control) :: "volatile"); -} -# } -``` - -## Labels - -Any reuse of a named label, local or otherwise, can result in a assembler or linker error or may cause other strange behavior. Reuse of a named label can happen in a variety of ways including: - -- explicitly: using a label more than once in one `asm!` block, or multiple times across blocks -- implicitly via inlining: the compiler is allowed to instantiate multiple copies of an `asm!` block, for example when the function containing it is inlined in multiple places. -- implicitly via LTO: LTO can cause code from *other crates* to be placed in the same codegen unit, and so could bring in arbitrary labels - -As a consequence, you should only use GNU assembler **numeric** [local labels] inside inline assembly code. Defining symbols in assembly code may lead to assembler and/or linker errors due to duplicate symbol definitions. - -Moreover, on x86 when using the default intel syntax, due to [an llvm bug], you shouldn't use labels exclusively made of `0` and `1` digits, e.g. `0`, `11` or `101010`, as they may end up being interpreted as binary values. Using `options(att_syntax)` will avoid any ambiguity, but that affects the syntax of the _entire_ `asm!` block. - -```rust,allow_fail -#![feature(asm)] - -let mut a = 0; -unsafe { - asm!( - "mov {0}, 10", - "2:", - "sub {0}, 1", - "cmp {0}, 3", - "jle 2f", - "jmp 2b", - "2:", - "add {0}, 2", - out(reg) a - ); -} -assert_eq!(a, 5); -``` - -This will decrement the `{0}` register value from 10 to 3, then add 2 and store it in `a`. - -This example shows a few things: - -First that the same number can be used as a label multiple times in the same inline block. - -Second, that when a numeric label is used as a reference (as an instruction operand, for example), the suffixes b (“backward”) or f (“forward”) should be added to the numeric label. It will then refer to the nearest label defined by this number in this direction. - -[local labels]: https://sourceware.org/binutils/docs/as/Symbol-Names.html#Local-Labels -[an llvm bug]: https://bugs.llvm.org/show_bug.cgi?id=36144 - -## Options - -By default, an inline assembly block is treated the same way as an external FFI function call with a custom calling convention: it may read/write memory, have observable side effects, etc. However, in many cases it is desirable to give the compiler more information about what the assembly code is actually doing so that it can optimize better. - -Let's take our previous example of an `add` instruction: - -```rust,allow_fail -#![feature(asm)] -let mut a: u64 = 4; -let b: u64 = 4; -unsafe { - asm!( - "add {0}, {1}", - inlateout(reg) a, in(reg) b, - options(pure, nomem, nostack), - ); -} -assert_eq!(a, 8); -``` - -Options can be provided as an optional final argument to the `asm!` macro. We specified three options here: -- `pure` means that the asm code has no observable side effects and that its output depends only on its inputs. This allows the compiler optimizer to call the inline asm fewer times or even eliminate it entirely. -- `nomem` means that the asm code does not read or write to memory. By default the compiler will assume that inline assembly can read or write any memory address that is accessible to it (e.g. through a pointer passed as an operand, or a global). -- `nostack` means that the asm code does not push any data onto the stack. This allows the compiler to use optimizations such as the stack red zone on x86-64 to avoid stack pointer adjustments. - -These allow the compiler to better optimize code using `asm!`, for example by eliminating pure `asm!` blocks whose outputs are not needed. - -See the reference for the full list of available options and their effects. - -# Reference-level explanation -[reference-level-explanation]: #reference-level-explanation - -Inline assembler is implemented as an unsafe macro `asm!()`. -The first argument to this macro is a template string literal used to build the final assembly. -The following arguments specify input and output operands. -When required, options are specified as the final argument. - -The following ABNF specifies the general syntax: - -```text -dir_spec := "in" / "out" / "lateout" / "inout" / "inlateout" -reg_spec := / "" -operand_expr := expr / "_" / expr "=>" expr / expr "=>" "_" -reg_operand := dir_spec "(" reg_spec ")" operand_expr -operand := reg_operand / "const" const_expr / "sym" path -clobber_abi := "clobber_abi(" *["," ] [","] ")" -option := "pure" / "nomem" / "readonly" / "preserves_flags" / "noreturn" / "nostack" / "att_syntax" / "raw" / "may_unwind" -options := "options(" option *["," option] [","] ")" -asm := "asm!(" format_string *("," format_string) *("," [ident "="] operand) *("," clobber_abi) *("," options) [","] ")" -``` - -Inline assembly is currently supported on the following architectures: -- x86 and x86-64 -- ARM -- AArch64 -- RISC-V -- NVPTX -- PowerPC -- Hexagon -- MIPS32r2 and MIPS64r2 -- wasm32 -- BPF -- SPIR-V -- AVR - -Support for more targets may be added in the future. The compiler will emit an error if `asm!` is used on an unsupported target. - -[format-syntax]: https://doc.rust-lang.org/std/fmt/#syntax - -## Template string arguments - -The assembler template uses the same syntax as [format strings][format-syntax] (i.e. placeholders are specified by curly braces). The corresponding arguments are accessed in order, by index, or by name. However, implicit named arguments (introduced by [RFC #2795][rfc-2795]) are not supported. - -An `asm!` invocation may have one or more template string arguments; an `asm!` with multiple template string arguments is treated as if all the strings were concatenated with a `\n` between them. The expected usage is for each template string argument to correspond to a line of assembly code. All template string arguments must appear before any other arguments. - -As with format strings, named arguments must appear after positional arguments. Explicit register operands must appear at the end of the operand list, after named arguments if any. - -Explicit register operands cannot be used by placeholders in the template string. All other named and positional operands must appear at least once in the template string, otherwise a compiler error is generated. - -The exact assembly code syntax is target-specific and opaque to the compiler except for the way operands are substituted into the template string to form the code passed to the assembler. - -The 5 targets specified in this RFC (x86, ARM, AArch64, RISC-V, Hexagon) all use the assembly code syntax of the GNU assembler (GAS). On x86, the `.intel_syntax noprefix` mode of GAS is used by default. On ARM, the `.syntax unified` mode is used. These targets impose an additional restriction on the assembly code: any assembler state (e.g. the current section which can be changed with `.section`) must be restored to its original value at the end of the asm string. Assembly code that does not conform to the GAS syntax will result in assembler-specific behavior. - -[rfc-2795]: https://github.com/rust-lang/rfcs/pull/2795 - -## Operand type - -Several types of operands are supported: - -* `in() ` - - `` can refer to a register class or an explicit register. The allocated register name is substituted into the asm template string. - - The allocated register will contain the value of `` at the start of the asm code. - - The allocated register must contain the same value at the end of the asm code (except if a `lateout` is allocated to the same register). -* `out() ` - - `` can refer to a register class or an explicit register. The allocated register name is substituted into the asm template string. - - The allocated register will contain an undefined value at the start of the asm code. - - `` must be a (possibly uninitialized) place expression, to which the contents of the allocated register is written to at the end of the asm code. - - An underscore (`_`) may be specified instead of an expression, which will cause the contents of the register to be discarded at the end of the asm code (effectively acting as a clobber). -* `lateout() ` - - Identical to `out` except that the register allocator can reuse a register allocated to an `in`. - - You should only write to the register after all inputs are read, otherwise you may clobber an input. -* `inout() ` - - `` can refer to a register class or an explicit register. The allocated register name is substituted into the asm template string. - - The allocated register will contain the value of `` at the start of the asm code. - - `` must be a mutable initialized place expression, to which the contents of the allocated register is written to at the end of the asm code. -* `inout() => ` - - Same as `inout` except that the initial value of the register is taken from the value of ``. - - `` must be a (possibly uninitialized) place expression, to which the contents of the allocated register is written to at the end of the asm code. - - An underscore (`_`) may be specified instead of an expression for ``, which will cause the contents of the register to be discarded at the end of the asm code (effectively acting as a clobber). - - `` and `` may have different types. -* `inlateout() ` / `inlateout() => ` - - Identical to `inout` except that the register allocator can reuse a register allocated to an `in` (this can happen if the compiler knows the `in` has the same initial value as the `inlateout`). - - You should only write to the register after all inputs are read, otherwise you may clobber an input. -* `const ` - - `` must be an integer constant expression. - - The value of the expression is formatted as a string and substituted directly into the asm template string. -* `sym ` - - `` must refer to a `fn` or `static`. - - A mangled symbol name referring to the item is substituted into the asm template string. - - The substituted string does not include any modifiers (e.g. GOT, PLT, relocations, etc). - - `` is allowed to point to a `#[thread_local]` static, in which case the asm code can combine the symbol with relocations (e.g. `@plt`, `@TPOFF`) to read from thread-local data. - -Operand expressions are evaluated from left to right, just like function call arguments. After the `asm!` has executed, outputs are written to in left to right order. This is significant if two outputs point to the same place: that place will contain the value of the rightmost output. - -## Register operands - -Input and output operands can be specified either as an explicit register or as a register class from which the register allocator can select a register. Explicit registers are specified as string literals (e.g. `"eax"`) while register classes are specified as identifiers (e.g. `reg`). Using string literals for register names enables support for architectures that use special characters in register names, such as MIPS (`$0`, `$1`, etc). - -Note that explicit registers treat register aliases (e.g. `r14` vs `lr` on ARM) and smaller views of a register (e.g. `eax` vs `rax`) as equivalent to the base register. It is a compile-time error to use the same explicit register for two input operands or two output operands. Additionally, it is also a compile-time error to use overlapping registers (e.g. ARM VFP) in input operands or in output operands. - -Only the following types are allowed as operands for inline assembly: -- Integers (signed and unsigned) -- Floating-point numbers -- Pointers (thin only) -- Function pointers -- SIMD vectors (structs defined with `#[repr(simd)]` and which implement `Copy`). This includes architecture-specific vector types defined in `std::arch` such as `__m128` (x86) or `int8x16_t` (ARM). - -Here is the list of currently supported register classes: - -| Architecture | Register class | Registers | LLVM constraint code | -| ------------ | -------------- | --------- | -------------------- | -| x86 | `reg` | `ax`, `bx`, `cx`, `dx`, `si`, `di`, `bp`, `r[8-15]` (x86-64 only) | `r` | -| x86 | `reg_abcd` | `ax`, `bx`, `cx`, `dx` | `Q` | -| x86-32 | `reg_byte` | `al`, `bl`, `cl`, `dl`, `ah`, `bh`, `ch`, `dh` | `q` | -| x86-64 | `reg_byte`\* | `al`, `bl`, `cl`, `dl`, `sil`, `dil`, `bpl`, `r[8-15]b` | `q` | -| x86 | `xmm_reg` | `xmm[0-7]` (x86) `xmm[0-15]` (x86-64) | `x` | -| x86 | `ymm_reg` | `ymm[0-7]` (x86) `ymm[0-15]` (x86-64) | `x` | -| x86 | `zmm_reg` | `zmm[0-7]` (x86) `zmm[0-31]` (x86-64) | `v` | -| x86 | `kreg` | `k[1-7]` | `Yk` | -| x86 | `x87_reg` | `st([0-7])` | Only clobbers | -| x86 | `mmx_reg` | `mm[0-7]` | Only clobbers | -| AArch64 | `reg` | `x[0-30]` | `r` | -| AArch64 | `vreg` | `v[0-31]` | `w` | -| AArch64 | `vreg_low16` | `v[0-15]` | `x` | -| AArch64 | `preg` | `p[0-15]`, `ffr` | Only clobbers | -| ARM (ARM/Thumb2) | `reg` | `r[0-12]`, `r14` | `r` | -| ARM (Thumb1) | `reg` | `r[0-7]` | `r` | -| ARM | `sreg` | `s[0-31]` | `t` | -| ARM | `sreg_low16` | `s[0-15]` | `x` | -| ARM | `dreg` | `d[0-31]` | `w` | -| ARM | `dreg_low16` | `d[0-15]` | `t` | -| ARM | `dreg_low8` | `d[0-8]` | `x` | -| ARM | `qreg` | `q[0-15]` | `w` | -| ARM | `qreg_low8` | `q[0-7]` | `t` | -| ARM | `qreg_low4` | `q[0-3]` | `x` | -| MIPS | `reg` | `$[2-25]` | `r` | -| MIPS | `freg` | `$f[0-31]` | `f` | -| NVPTX | `reg16` | None\* | `h` | -| NVPTX | `reg32` | None\* | `r` | -| NVPTX | `reg64` | None\* | `l` | -| RISC-V | `reg` | `x1`, `x[5-7]`, `x[9-15]`, `x[16-31]` (non-RV32E) | `r` | -| RISC-V | `freg` | `f[0-31]` | `f` | -| RISC-V | `vreg` | `v[0-31]` | Only clobbers | -| Hexagon | `reg` | `r[0-28]` | `r` | -| PowerPC | `reg` | `r[0-31]` | `r` | -| PowerPC | `reg_nonzero` | | `r[1-31]` | `b` | -| PowerPC | `freg` | `f[0-31]` | `f` | -| PowerPC | `cr` | `cr[0-7]`, `cr` | Only clobbers | -| PowerPC | `xer` | `xer` | Only clobbers | -| wasm32 | `local` | None\* | `r` | -| BPF | `reg` | `r[0-10]` | `r` | -| BPF | `wreg` | `w[0-10]` | `w` | -| AVR | `reg` | `r[2-25]`, `XH`, `XL`, `ZH`, `ZL` | `r` | -| AVR | `reg_upper` | `r[16-25]`, `XH`, `XL`, `ZH`, `ZL` | `d` | -| AVR | `reg_pair` | `r3r2` .. `r25r24`, `X`, `Z` | `r` | -| AVR | `reg_iw` | `r25r24`, `X`, `Z` | `w` | -| AVR | `reg_ptr` | `X`, `Z` | `e` | - -> **Note**: On x86 we treat `reg_byte` differently from `reg` because the compiler can allocate `al` and `ah` separately whereas `reg` reserves the whole register. -> -> Note #2: On x86-64 the high byte registers (e.g. `ah`) are not available in the `reg_byte` register class. -> -> Note #3: NVPTX doesn't have a fixed register set, so named registers are not supported. -> -> Note #4: WebAssembly doesn't have registers, so named registers are not supported. -> -> Note #5: Some register classes are marked as "Only clobbers" which means that they cannot be used for inputs or outputs, only clobbers of the form `out("reg") _` or `lateout("reg") _`. - -Additional register classes may be added in the future based on demand (e.g. MMX, x87, etc). - -Each register class has constraints on which value types they can be used with. This is necessary because the way a value is loaded into a register depends on its type. For example, on big-endian systems, loading a `i32x4` and a `i8x16` into a SIMD register may result in different register contents even if the byte-wise memory representation of both values is identical. The availability of supported types for a particular register class may depend on what target features are currently enabled. - -| Architecture | Register class | Target feature | Allowed types | -| ------------ | -------------- | -------------- | ------------- | -| x86-32 | `reg` | None | `i16`, `i32`, `f32` | -| x86-64 | `reg` | None | `i16`, `i32`, `f32`, `i64`, `f64` | -| x86 | `reg_byte` | None | `i8` | -| x86 | `xmm_reg` | `sse` | `i32`, `f32`, `i64`, `f64`,
`i8x16`, `i16x8`, `i32x4`, `i64x2`, `f32x4`, `f64x2` | -| x86 | `ymm_reg` | `avx` | `i32`, `f32`, `i64`, `f64`,
`i8x16`, `i16x8`, `i32x4`, `i64x2`, `f32x4`, `f64x2`
`i8x32`, `i16x16`, `i32x8`, `i64x4`, `f32x8`, `f64x4` | -| x86 | `zmm_reg` | `avx512f` | `i32`, `f32`, `i64`, `f64`,
`i8x16`, `i16x8`, `i32x4`, `i64x2`, `f32x4`, `f64x2`
`i8x32`, `i16x16`, `i32x8`, `i64x4`, `f32x8`, `f64x4`
`i8x64`, `i16x32`, `i32x16`, `i64x8`, `f32x16`, `f64x8` | -| x86 | `kreg` | `avx512f` | `i8`, `i16` | -| x86 | `kreg` | `avx512bw` | `i32`, `i64` | -| x86 | `mmx_reg` | N/A | Only clobbers | -| x86 | `x87_reg` | N/A | Only clobbers | -| AArch64 | `reg` | None | `i8`, `i16`, `i32`, `f32`, `i64`, `f64` | -| AArch64 | `vreg` | `fp` | `i8`, `i16`, `i32`, `f32`, `i64`, `f64`,
`i8x8`, `i16x4`, `i32x2`, `i64x1`, `f32x2`, `f64x1`,
`i8x16`, `i16x8`, `i32x4`, `i64x2`, `f32x4`, `f64x2` | -| AArch64 | `preg` | N/A | Only clobbers | -| ARM | `reg` | None | `i8`, `i16`, `i32`, `f32` | -| ARM | `sreg` | `vfp2` | `i32`, `f32` | -| ARM | `dreg` | `vfp2` | `i64`, `f64`, `i8x8`, `i16x4`, `i32x2`, `i64x1`, `f32x2` | -| ARM | `qreg` | `neon` | `i8x16`, `i16x8`, `i32x4`, `i64x2`, `f32x4` | -| MIPS32 | `reg` | None | `i8`, `i16`, `i32`, `f32` | -| MIPS32 | `freg` | None | `f32`, `f64` | -| MIPS64 | `reg` | None | `i8`, `i16`, `i32`, `i64`, `f32`, `f64` | -| MIPS64 | `freg` | None | `f32`, `f64` | -| NVPTX | `reg16` | None | `i8`, `i16` | -| NVPTX | `reg32` | None | `i8`, `i16`, `i32`, `f32` | -| NVPTX | `reg64` | None | `i8`, `i16`, `i32`, `f32`, `i64`, `f64` | -| RISC-V32 | `reg` | None | `i8`, `i16`, `i32`, `f32` | -| RISC-V64 | `reg` | None | `i8`, `i16`, `i32`, `f32`, `i64`, `f64` | -| RISC-V | `freg` | `f` | `f32` | -| RISC-V | `freg` | `d` | `f64` | -| RISC-V | `vreg` | N/A | Only clobbers | -| Hexagon | `reg` | None | `i8`, `i16`, `i32`, `f32` | -| PowerPC | `reg` | None | `i8`, `i16`, `i32` | -| PowerPC | `reg_nonzero` | None | `i8`, `i16`, `i32` | -| PowerPC | `freg` | None | `f32`, `f64` | -| PowerPC | `cr` | N/A | Only clobbers | -| PowerPC | `xer` | N/A | Only clobbers | -| wasm32 | `local` | None | `i8` `i16` `i32` `i64` `f32` `f64` | -| BPF | `reg` | None | `i8` `i16` `i32` `i64` | -| BPF | `wreg` | `alu32` | `i8` `i16` `i32` | -| AVR | `reg`, `reg_upper` | None | `i8` | -| AVR | `reg_pair`, `reg_iw`, `reg_ptr` | None | `i16` | - -> **Note**: For the purposes of the above table pointers, function pointers and `isize`/`usize` are treated as the equivalent integer type (`i16`/`i32`/`i64` depending on the target). - -If a value is of a smaller size than the register it is allocated in then the upper bits of that register will have an undefined value for inputs and will be ignored for outputs. The only exception is the `freg` register class on RISC-V where `f32` values are NaN-boxed in a `f64` as required by the RISC-V architecture. - -When separate input and output expressions are specified for an `inout` operand, both expressions must have the same type. The only exception is if both operands are pointers or integers, in which case they are only required to have the same size. This restriction exists because the register allocators in LLVM and GCC sometimes cannot handle tied operands with different types. - -## Register names - -Some registers have multiple names. These are all treated by the compiler as identical to the base register name. Here is the list of all supported register aliases: - -| Architecture | Base register | Aliases | -| ------------ | ------------- | ------- | -| x86 | `ax` | `eax`, `rax` | -| x86 | `bx` | `ebx`, `rbx` | -| x86 | `cx` | `ecx`, `rcx` | -| x86 | `dx` | `edx`, `rdx` | -| x86 | `si` | `esi`, `rsi` | -| x86 | `di` | `edi`, `rdi` | -| x86 | `bp` | `bpl`, `ebp`, `rbp` | -| x86 | `sp` | `spl`, `esp`, `rsp` | -| x86 | `ip` | `eip`, `rip` | -| x86 | `st(0)` | `st` | -| x86 | `r[8-15]` | `r[8-15]b`, `r[8-15]w`, `r[8-15]d` | -| x86 | `xmm[0-31]` | `ymm[0-31]`, `zmm[0-31]` | -| AArch64 | `x[0-30]` | `w[0-30]` | -| AArch64 | `x29` | `fp` | -| AArch64 | `x30` | `lr` | -| AArch64 | `sp` | `wsp` | -| AArch64 | `xzr` | `wzr` | -| AArch64 | `v[0-31]` | `b[0-31]`, `h[0-31]`, `s[0-31]`, `d[0-31]`, `q[0-31]` | -| ARM | `r[0-3]` | `a[1-4]` | -| ARM | `r[4-9]` | `v[1-6]` | -| ARM | `r9` | `rfp` | -| ARM | `r10` | `sl` | -| ARM | `r11` | `fp` | -| ARM | `r12` | `ip` | -| ARM | `r13` | `sp` | -| ARM | `r14` | `lr` | -| ARM | `r15` | `pc` | -| RISC-V | `x0` | `zero` | -| RISC-V | `x1` | `ra` | -| RISC-V | `x2` | `sp` | -| RISC-V | `x3` | `gp` | -| RISC-V | `x4` | `tp` | -| RISC-V | `x[5-7]` | `t[0-2]` | -| RISC-V | `x8` | `fp`, `s0` | -| RISC-V | `x9` | `s1` | -| RISC-V | `x[10-17]` | `a[0-7]` | -| RISC-V | `x[18-27]` | `s[2-11]` | -| RISC-V | `x[28-31]` | `t[3-6]` | -| RISC-V | `f[0-7]` | `ft[0-7]` | -| RISC-V | `f[8-9]` | `fs[0-1]` | -| RISC-V | `f[10-17]` | `fa[0-7]` | -| RISC-V | `f[18-27]` | `fs[2-11]` | -| RISC-V | `f[28-31]` | `ft[8-11]` | -| Hexagon | `r29` | `sp` | -| Hexagon | `r30` | `fr` | -| Hexagon | `r31` | `lr` | -| BPF | `r[0-10]` | `w[0-10]` | -| AVR | `XH` | `r27` | -| AVR | `XL` | `r26` | -| AVR | `ZH` | `r31` | -| AVR | `ZL` | `r30` | - -Some registers cannot be used for input or output operands: - -| Architecture | Unsupported register | Reason | -| ------------ | -------------------- | ------ | -| All | `sp` | The stack pointer must be restored to its original value at the end of an asm code block. | -| All | `bp` (x86), `x29` (AArch64), `x8` (RISC-V), `fr` (Hexagon), `$fp` (MIPS), `Y` (AVR) | The frame pointer cannot be used as an input or output. | -| ARM | `r7` or `r11` | On ARM the frame pointer can be either `r7` or `r11` depending on the target. The frame pointer cannot be used as an input or output. | -| All | `si` (x86-32), `bx` (x86-64), `r6` (ARM), `x19` (AArch64), `r19` (Hexagon), `x9` (RISC-V) | This is used internally by LLVM as a "base pointer" for functions with complex stack frames. | -| x86 | `k0` | This is a constant zero register which can't be modified. | -| x86 | `ip` | This is the program counter, not a real register. | -| x86 | `mm[0-7]` | MMX registers are not currently supported (but may be in the future). | -| x86 | `st([0-7])` | x87 registers are not currently supported (but may be in the future). | -| AArch64 | `xzr` | This is a constant zero register which can't be modified. | -| ARM | `pc` | This is the program counter, not a real register. | -| ARM | `r9` | This is a reserved register on some ARM targets. | -| MIPS | `$0` or `$zero` | This is a constant zero register which can't be modified. | -| MIPS | `$1` or `$at` | Reserved for assembler. | -| MIPS | `$26`/`$k0`, `$27`/`$k1` | OS-reserved registers. | -| MIPS | `$28`/`$gp` | Global pointer cannot be used as inputs or outputs. | -| MIPS | `$ra` | Return address cannot be used as inputs or outputs. | -| RISC-V | `x0` | This is a constant zero register which can't be modified. | -| RISC-V | `gp`, `tp` | These registers are reserved and cannot be used as inputs or outputs. | -| Hexagon | `lr` | This is the link register which cannot be used as an input or output. | -| AVR | `r0`, `r1`, `r1r0` | Due to an issue in LLVM, the `r0` and `r1` registers cannot be used as inputs or outputs. If modified, they must be restored to their original values before the end of the block. | - -In some cases LLVM will allocate a "reserved register" for `reg` operands even though this register cannot be explicitly specified. Assembly code making use of reserved registers should be careful since `reg` operands may alias with those registers. Reserved registers are the frame pointer and base pointer -- The frame pointer and LLVM base pointer on all architectures. -- `r9` on ARM. -- `x18` on AArch64. -- `r0` and `r1` on AVR. - -## Template modifiers - -The placeholders can be augmented by modifiers which are specified after the `:` in the curly braces. These modifiers do not affect register allocation, but change the way operands are formatted when inserted into the template string. Only one modifier is allowed per template placeholder. - -The supported modifiers are a subset of LLVM's (and GCC's) [asm template argument modifiers][llvm-argmod], but do not use the same letter codes. - -| Architecture | Register class | Modifier | Example output | LLVM modifier | -| ------------ | -------------- | -------- | -------------- | ------------- | -| x86-32 | `reg` | None | `eax` | `k` | -| x86-64 | `reg` | None | `rax` | `q` | -| x86-32 | `reg_abcd` | `l` | `al` | `b` | -| x86-64 | `reg` | `l` | `al` | `b` | -| x86 | `reg_abcd` | `h` | `ah` | `h` | -| x86 | `reg` | `x` | `ax` | `w` | -| x86 | `reg` | `e` | `eax` | `k` | -| x86-64 | `reg` | `r` | `rax` | `q` | -| x86 | `reg_byte` | None | `al` / `ah` | None | -| x86 | `xmm_reg` | None | `xmm0` | `x` | -| x86 | `ymm_reg` | None | `ymm0` | `t` | -| x86 | `zmm_reg` | None | `zmm0` | `g` | -| x86 | `*mm_reg` | `x` | `xmm0` | `x` | -| x86 | `*mm_reg` | `y` | `ymm0` | `t` | -| x86 | `*mm_reg` | `z` | `zmm0` | `g` | -| x86 | `kreg` | None | `k1` | None | -| AArch64 | `reg` | None | `x0` | `x` | -| AArch64 | `reg` | `w` | `w0` | `w` | -| AArch64 | `reg` | `x` | `x0` | `x` | -| AArch64 | `vreg` | None | `v0` | None | -| AArch64 | `vreg` | `v` | `v0` | None | -| AArch64 | `vreg` | `b` | `b0` | `b` | -| AArch64 | `vreg` | `h` | `h0` | `h` | -| AArch64 | `vreg` | `s` | `s0` | `s` | -| AArch64 | `vreg` | `d` | `d0` | `d` | -| AArch64 | `vreg` | `q` | `q0` | `q` | -| ARM | `reg` | None | `r0` | None | -| ARM | `sreg` | None | `s0` | None | -| ARM | `dreg` | None | `d0` | `P` | -| ARM | `qreg` | None | `q0` | `q` | -| ARM | `qreg` | `e` / `f` | `d0` / `d1` | `e` / `f` | -| MIPS | `reg` | None | `$2` | None | -| MIPS | `freg` | None | `$f0` | None | -| NVPTX | `reg16` | None | `rs0` | None | -| NVPTX | `reg32` | None | `r0` | None | -| NVPTX | `reg64` | None | `rd0` | None | -| RISC-V | `reg` | None | `x1` | None | -| RISC-V | `freg` | None | `f0` | None | -| Hexagon | `reg` | None | `r0` | None | -| PowerPC | `reg` | None | `0` | None | -| PowerPC | `reg_nonzero` | None | `3` | `b` | -| PowerPC | `freg` | None | `0` | None | - -> Notes: -> - on ARM `e` / `f`: this prints the low or high doubleword register name of a NEON quad (128-bit) register. -> - on x86: our behavior for `reg` with no modifiers differs from what GCC does. GCC will infer the modifier based on the operand value type, while we default to the full register size. -> - on x86 `xmm_reg`: the `x`, `t` and `g` LLVM modifiers are not yet implemented in LLVM (they are supported by GCC only), but this should be a simple change. - -As stated in the previous section, passing an input value smaller than the register width will result in the upper bits of the register containing undefined values. This is not a problem if the inline asm only accesses the lower bits of the register, which can be done by using a template modifier to use a subregister name in the asm code (e.g. `ax` instead of `rax`). Since this an easy pitfall, the compiler will suggest a template modifier to use where appropriate given the input type. If all references to an operand already have modifiers then the warning is suppressed for that operand. - -[llvm-argmod]: http://llvm.org/docs/LangRef.html#asm-template-argument-modifiers - -## ABI clobbers - -The `clobber_abi` keyword can be used to apply a default set of clobbers to an `asm` block. This will automatically insert the necessary clobber constraints as needed for calling a function with a particular calling convention: if the calling convention does not fully preserve the value of a register across a call then a `lateout("reg") _` is implicitly added to the operands list. - -`clobber_abi` may be specified any number of times. It will insert a clobber for all unique registers in the union of all specified calling conventions. - -Generic register class outputs are disallowed by the compiler when `clobber_abi` is used: all outputs must specify an explicit register. Explicit register outputs have precedence over the implicit clobbers inserted by `clobber_abi`: a clobber will only be inserted for a register if that register is not used as an output. -The following ABIs can be used with `clobber_abi`: - -| Architecture | ABI name | Clobbered registers | -| ------------ | -------- | ------------------- | -| x86-32 | `"C"`, `"system"`, `"efiapi"`, `"cdecl"`, `"stdcall"`, `"fastcall"` | `ax`, `cx`, `dx`, `xmm[0-7]`, `mm[0-7]`, `k[1-7]`, `st([0-7])` | -| x86-64 | `"C"`, `"system"` (on Windows), `"efiapi"`, `"win64"` | `ax`, `cx`, `dx`, `r[8-11]`, `xmm[0-31]`, `mm[0-7]`, `k[1-7]`, `st([0-7])` | -| x86-64 | `"C"`, `"system"` (on non-Windows), `"sysv64"` | `ax`, `cx`, `dx`, `si`, `di`, `r[8-11]`, `xmm[0-31]`, `mm[0-7]`, `k[1-7]`, `st([0-7])` | -| AArch64 | `"C"`, `"system"`, `"efiapi"` | `x[0-17]`, `x30`, `v[0-31]`, `p[0-15]`, `ffr` | -| ARM | `"C"`, `"system"`, `"efiapi"`, `"aapcs"` | `r[0-3]`, `r12`, `r14`, `s[0-15]`, `d[0-7]`, `d[16-31]` | -| RISC-V | `"C"`, `"system"`, `"efiapi"` | `x1`, `x[5-7]`, `x[10-17]`, `x[28-31]`, `f[0-7]`, `f[10-17]`, `f[28-31]`, `v[0-31]` | - -The list of clobbered registers for each ABI is updated in rustc as architectures gain new registers: this ensures that `asm` clobbers will continue to be correct when LLVM starts using these new registers in its generated code. - -## Options - -Flags are used to further influence the behavior of the inline assembly block. -Currently the following options are defined: -- `pure`: The `asm` block has no side effects, and its outputs depend only on its direct inputs (i.e. the values themselves, not what they point to) or values read from memory (unless the `nomem` options is also set). This allows the compiler to execute the `asm` block fewer times than specified in the program (e.g. by hoisting it out of a loop) or even eliminate it entirely if the outputs are not used. -- `nomem`: The `asm` blocks does not read or write to any memory. This allows the compiler to cache the values of modified global variables in registers across the `asm` block since it knows that they are not read or written to by the `asm`. -- `readonly`: The `asm` block does not write to any memory. This allows the compiler to cache the values of unmodified global variables in registers across the `asm` block since it knows that they are not written to by the `asm`. -- `preserves_flags`: The `asm` block does not modify the flags register (defined in the rules below). This allows the compiler to avoid recomputing the condition flags after the `asm` block. -- `noreturn`: The `asm` block never returns, and its return type is defined as `!` (never). Behavior is undefined if execution falls through past the end of the asm code. A `noreturn` asm block behaves just like a function which doesn't return; notably, local variables in scope are not dropped before it is invoked. -- `nostack`: The `asm` block does not push data to the stack, or write to the stack red-zone (if supported by the target). If this option is *not* used then the stack pointer is guaranteed to be suitably aligned (according to the target ABI) for a function call. -- `att_syntax`: This option is only valid on x86, and causes the assembler to use the `.att_syntax prefix` mode of the GNU assembler. Register operands are substituted in with a leading `%`. -- `may_unwind`: The `asm` block may unwind the stack and be part of the stack unwinding process (This option is only supported by the LLVM backend right now). -- `raw`: This causes the template string to be parsed as a raw assembly string, with no special handling for `{` and `}`. This is primarily useful when including raw assembly code from an external file using `include_str!`. - -The compiler performs some additional checks on options: -- The `nomem` and `readonly` options are mutually exclusive: it is a compile-time error to specify both. -- The `pure` option must be combined with either the `nomem` or `readonly` options, otherwise a compile-time error is emitted. -- It is a compile-time error to specify `pure` on an asm block with no outputs or only discarded outputs (`_`). -- It is a compile-time error to specify `noreturn` on an asm block with outputs. - -## Rules for inline assembly - -- Any registers not specified as inputs will contain an undefined value on entry to the asm block. - - An "undefined value" in the context of inline assembly means that the register can (non-deterministically) have any one of the possible values allowed by the architecture. Notably it is not the same as an LLVM `undef` which can have a different value every time you read it (since such a concept does not exist in assembly code). -- Any registers not specified as outputs must have the same value upon exiting the asm block as they had on entry, otherwise behavior is undefined. - - This only applies to registers which can be specified as an input or output. Other registers follow target-specific rules. - - Note that a `lateout` may be allocated to the same register as an `in`, in which case this rule does not apply. Code should not rely on this however since it depends on the results of register allocation. -- Behavior is undefined if execution unwinds out of an asm block. - - This also applies if the assembly code calls a function which then unwinds. -- The set of memory locations that assembly code is allowed to read and write are the same as those allowed for an FFI function. - - Refer to the unsafe code guidelines for the exact rules. - - If the `readonly` option is set, then only memory reads are allowed. - - If the `nomem` option is set then no reads or writes to memory are allowed. - - These rules do not apply to memory which is private to the asm code, such as stack space allocated within the asm block. -- The compiler cannot assume that the instructions in the asm are the ones that will actually end up executed. - - This effectively means that the compiler must treat the `asm!` as a black box and only take the interface specification into account, not the instructions themselves. - - Runtime code patching is allowed, via target-specific mechanisms (outside the scope of this RFC). -- Unless the `nostack` option is set, asm code is allowed to use stack space below the stack pointer. - - On entry to the asm block the stack pointer is guaranteed to be suitably aligned (according to the target ABI) for a function call. - - You are responsible for making sure you don't overflow the stack (e.g. use stack probing to ensure you hit a guard page). - - You should adjust the stack pointer when allocating stack memory as required by the target ABI. - - The stack pointer must be restored to its original value before leaving the asm block. -- If the `noreturn` option is set then behavior is undefined if execution falls through to the end of the asm block. -- If the `pure` option is set then behavior is undefined if the `asm` has side-effects other than its direct outputs. Behavior is also undefined if two executions of the `asm` code with the same inputs result in different outputs. - - When used with the `nomem` option, "inputs" are just the direct inputs of the `asm!`. - - When used with the `readonly` option, "inputs" comprise the direct inputs of the `asm!` and any memory that the `asm!` block is allowed to read. -- These flags registers must be restored upon exiting the asm block if the `preserves_flags` option is set: - - x86 - - Status flags in `EFLAGS` (CF, PF, AF, ZF, SF, OF). - - Floating-point status word (all). - - Floating-point exception flags in `MXCSR` (PE, UE, OE, ZE, DE, IE). - - ARM - - Condition flags in `CPSR` (N, Z, C, V) - - Saturation flag in `CPSR` (Q) - - Greater than or equal flags in `CPSR` (GE). - - Condition flags in `FPSCR` (N, Z, C, V) - - Saturation flag in `FPSCR` (QC) - - Floating-point exception flags in `FPSCR` (IDC, IXC, UFC, OFC, DZC, IOC). - - AArch64 - - Condition flags (`NZCV` register). - - Floating-point status (`FPSR` register). - - RISC-V - - Floating-point exception flags in `fcsr` (`fflags`). - - Vector extension state (`vtype`, `vl`, `vcsr`). - - AVR - - The status register `SREG`. -- On x86, the direction flag (DF in `EFLAGS`) is clear on entry to an asm block and must be clear on exit. - - Behavior is undefined if the direction flag is set on exiting an asm block. -- The requirement of restoring the stack pointer and non-output registers to their original value only applies when exiting an `asm!` block. - - This means that `asm!` blocks that never return (even if not marked `noreturn`) don't need to preserve these registers. - - When returning to a different `asm!` block than you entered (e.g. for context switching), these registers must contain the value they had upon entering the `asm!` block that you are *exiting*. - - You cannot exit an `asm!` block that has not been entered. Neither can you exit an `asm!` block that has already been exited. - - You are responsible for switching any target-specific state (e.g. thread-local storage, stack bounds). - - The set of memory locations that you may access is the intersection of those allowed by the `asm!` blocks you entered and exited. -- You cannot assume that an `asm!` block will appear exactly once in the output binary. The compiler is allowed to instantiate multiple copies of the `asm!` block, for example when the function containing it is inlined in multiple places. -- On x86, inline assembly must not end with an instruction prefix (such as `LOCK`) that would apply to instructions generated by the compiler. - - The compiler is currently unable to detect this due to the way inline assembly is compiled, but may catch and reject this in the future. - -> **Note**: As a general rule, the flags covered by `preserves_flags` are those which are *not* preserved when performing a function call. diff --git a/src/doc/unstable-book/src/library-features/global-asm.md b/src/doc/unstable-book/src/library-features/global-asm.md deleted file mode 100644 index 3f8e165841d..00000000000 --- a/src/doc/unstable-book/src/library-features/global-asm.md +++ /dev/null @@ -1,113 +0,0 @@ -# `global_asm` - -The tracking issue for this feature is: [#35119] - -[#35119]: https://github.com/rust-lang/rust/issues/35119 - ------------------------- - -The `global_asm!` macro allows the programmer to write arbitrary -assembly outside the scope of a function body, passing it through -`rustc` and `llvm` to the assembler. That is to say, `global_asm!` is -equivalent to assembling the asm with an external assembler and then -linking the resulting object file with the current crate. - -`global_asm!` fills a role not currently satisfied by either `asm!` -or `#[naked]` functions. The programmer has _all_ features of the -assembler at their disposal. The linker will expect to resolve any -symbols defined in the inline assembly, modulo any symbols marked as -external. It also means syntax for directives and assembly follow the -conventions of the assembler in your toolchain. - -A simple usage looks like this: - -```rust,ignore (requires-external-file) -#![feature(global_asm)] -# // you also need relevant target_arch cfgs -global_asm!(include_str!("something_neato.s")); -``` - -And a more complicated usage looks like this: - -```rust,no_run -#![feature(global_asm)] -# #[cfg(any(target_arch="x86", target_arch="x86_64"))] -# mod x86 { - -pub mod sally { - global_asm!( - ".global foo", - "foo:", - "jmp baz", - ); - - #[no_mangle] - pub unsafe extern "C" fn baz() {} -} - -// the symbols `foo` and `bar` are global, no matter where -// `global_asm!` was used. -extern "C" { - fn foo(); - fn bar(); -} - -pub mod harry { - global_asm!( - ".global bar", - "bar:", - "jmp quux", - ); - - #[no_mangle] - pub unsafe extern "C" fn quux() {} -} -# } -``` - -You may use `global_asm!` multiple times, anywhere in your crate, in -whatever way suits you. However, you should not rely on assembler state -(e.g. assembler macros) defined in one `global_asm!` to be available in -another one. It is implementation-defined whether the multiple usages -are concatenated into one or assembled separately. - -`global_asm!` also supports `const` operands like `asm!`, which allows -constants defined in Rust to be used in assembly code: - -```rust,no_run -#![feature(global_asm, asm_const)] -# #[cfg(any(target_arch="x86", target_arch="x86_64"))] -# mod x86 { -const C: i32 = 1234; -global_asm!( - ".global bar", - "bar: .word {c}", - c = const C, -); -# } -``` - -The syntax for passing operands is the same as `asm!` except that only -`const` operands are allowed. Refer to the [asm](asm.md) documentation -for more details. - -On x86, the assembly code will use intel syntax by default. You can -override this by adding `options(att_syntax)` at the end of the macro -arguments list: - -```rust,no_run -#![feature(global_asm, asm_const)] -# #[cfg(any(target_arch="x86", target_arch="x86_64"))] -# mod x86 { -global_asm!("movl ${}, %ecx", const 5, options(att_syntax)); -// is equivalent to -global_asm!("mov ecx, {}", const 5); -# } -``` - ------------------------- - -If you don't need quite as much power and flexibility as -`global_asm!` provides, and you don't mind restricting your inline -assembly to `fn` bodies only, you might try the -[asm](asm.md) feature instead. diff --git a/src/doc/unstable-book/src/library-features/llvm-asm.md b/src/doc/unstable-book/src/library-features/llvm-asm.md index 07fc16261d8..094124998b6 100644 --- a/src/doc/unstable-book/src/library-features/llvm-asm.md +++ b/src/doc/unstable-book/src/library-features/llvm-asm.md @@ -188,6 +188,3 @@ documentation as well][llvm-docs] for more information about clobbers, constraints, etc. [llvm-docs]: http://llvm.org/docs/LangRef.html#inline-assembler-expressions - -If you need more power and don't mind losing some of the niceties of -`llvm_asm!`, check out [global_asm](global-asm.md). diff --git a/src/test/assembly/asm/global_asm.rs b/src/test/assembly/asm/global_asm.rs index 7e48c386abc..0358bc6d27c 100644 --- a/src/test/assembly/asm/global_asm.rs +++ b/src/test/assembly/asm/global_asm.rs @@ -2,9 +2,11 @@ // assembly-output: emit-asm // compile-flags: -C llvm-args=--x86-asm-syntax=intel -#![feature(global_asm, asm_const)] +#![feature(asm_const)] #![crate_type = "rlib"] +use std::arch::global_asm; + // CHECK: mov eax, eax global_asm!("mov eax, eax"); // CHECK: mov ebx, 5 diff --git a/src/test/assembly/x86_64-fortanix-unknown-sgx-lvi-inline-assembly.rs b/src/test/assembly/x86_64-fortanix-unknown-sgx-lvi-inline-assembly.rs index 7e440169edb..720850e91e8 100644 --- a/src/test/assembly/x86_64-fortanix-unknown-sgx-lvi-inline-assembly.rs +++ b/src/test/assembly/x86_64-fortanix-unknown-sgx-lvi-inline-assembly.rs @@ -4,11 +4,11 @@ // compile-flags: --crate-type staticlib // only-x86_64-fortanix-unknown-sgx -#![feature(asm)] +use std::arch::asm; #[no_mangle] -pub extern fn get(ptr: *const u64) -> u64 { - let value : u64; +pub extern "C" fn get(ptr: *const u64) -> u64 { + let value: u64; unsafe { asm!(".start_inline_asm:", "mov {}, [{}]", @@ -26,11 +26,13 @@ // CHECK-NEXT: .end_inline_asm #[no_mangle] -pub extern fn myret() { +pub extern "C" fn myret() { unsafe { - asm!(".start_myret_inline_asm: + asm!( + ".start_myret_inline_asm: ret - .end_myret_inline_asm:"); + .end_myret_inline_asm:" + ); } } diff --git a/src/test/codegen/asm-clobber_abi.rs b/src/test/codegen/asm-clobber_abi.rs index d589a7c6688..69e35270266 100644 --- a/src/test/codegen/asm-clobber_abi.rs +++ b/src/test/codegen/asm-clobber_abi.rs @@ -2,7 +2,8 @@ // only-x86_64 #![crate_type = "rlib"] -#![feature(asm)] + +use std::arch::asm; // CHECK-LABEL: @clobber_sysv64 // CHECK: ={ax},={cx},={dx},={si},={di},={r8},={r9},={r10},={r11},={xmm0},={xmm1},={xmm2},={xmm3},={xmm4},={xmm5},={xmm6},={xmm7},={xmm8},={xmm9},={xmm10},={xmm11},={xmm12},={xmm13},={xmm14},={xmm15},~{xmm16},~{xmm17},~{xmm18},~{xmm19},~{xmm20},~{xmm21},~{xmm22},~{xmm23},~{xmm24},~{xmm25},~{xmm26},~{xmm27},~{xmm28},~{xmm29},~{xmm30},~{xmm31},~{k1},~{k2},~{k3},~{k4},~{k5},~{k6},~{k7},~{st},~{st(1)},~{st(2)},~{st(3)},~{st(4)},~{st(5)},~{st(6)},~{st(7)},~{dirflag},~{fpsr},~{flags},~{memory} diff --git a/src/test/codegen/asm-clobbers.rs b/src/test/codegen/asm-clobbers.rs index 9d7c8b5f155..2ef10a2837d 100644 --- a/src/test/codegen/asm-clobbers.rs +++ b/src/test/codegen/asm-clobbers.rs @@ -2,7 +2,8 @@ // only-x86_64 #![crate_type = "rlib"] -#![feature(asm)] + +use std::arch::asm; // CHECK-LABEL: @x87_clobber // CHECK: ~{st},~{st(1)},~{st(2)},~{st(3)},~{st(4)},~{st(5)},~{st(6)},~{st(7)} diff --git a/src/test/codegen/asm-may_unwind.rs b/src/test/codegen/asm-may_unwind.rs index 85cae8b2b1c..3b34d79c3a9 100644 --- a/src/test/codegen/asm-may_unwind.rs +++ b/src/test/codegen/asm-may_unwind.rs @@ -3,7 +3,9 @@ // only-x86_64 #![crate_type = "rlib"] -#![feature(asm, asm_unwind)] +#![feature(asm_unwind)] + +use std::arch::asm; #[no_mangle] pub extern "C" fn panicky() {} diff --git a/src/test/codegen/asm-multiple-options.rs b/src/test/codegen/asm-multiple-options.rs index baf9f3e9bd1..1ae37d627d6 100644 --- a/src/test/codegen/asm-multiple-options.rs +++ b/src/test/codegen/asm-multiple-options.rs @@ -2,7 +2,8 @@ // only-x86_64 #![crate_type = "rlib"] -#![feature(asm)] + +use std::arch::asm; // CHECK-LABEL: @pure // CHECK-NOT: asm diff --git a/src/test/codegen/asm-options.rs b/src/test/codegen/asm-options.rs index 28df0f9b852..963b60cfe35 100644 --- a/src/test/codegen/asm-options.rs +++ b/src/test/codegen/asm-options.rs @@ -2,7 +2,8 @@ // only-x86_64 #![crate_type = "rlib"] -#![feature(asm)] + +use std::arch::asm; // CHECK-LABEL: @pure // CHECK-NOT: asm diff --git a/src/test/codegen/asm-target-clobbers.rs b/src/test/codegen/asm-target-clobbers.rs index f637cdcd234..8845cfbe767 100644 --- a/src/test/codegen/asm-target-clobbers.rs +++ b/src/test/codegen/asm-target-clobbers.rs @@ -3,7 +3,8 @@ // [avx512]compile-flags: -C target-feature=+avx512f #![crate_type = "rlib"] -#![feature(asm)] + +use std::arch::asm; // CHECK-LABEL: @avx512_clobber // base: call void asm sideeffect inteldialect "", "~{xmm31}"() diff --git a/src/test/codegen/global_asm.rs b/src/test/codegen/global_asm.rs index 57d8aeb165b..fab84868fdf 100644 --- a/src/test/codegen/global_asm.rs +++ b/src/test/codegen/global_asm.rs @@ -39,18 +39,21 @@ // ignore-emscripten // compile-flags: -C no-prepopulate-passes -#![feature(global_asm)] #![crate_type = "lib"] +use std::arch::global_asm; + // CHECK-LABEL: foo // CHECK: module asm // this regex will capture the correct unconditional branch inst. // CHECK: module asm "{{[[:space:]]+}}jmp baz" -global_asm!(r#" +global_asm!( + r#" .global foo foo: jmp baz -"#); +"# +); extern "C" { fn foo(); diff --git a/src/test/codegen/global_asm_include.rs b/src/test/codegen/global_asm_include.rs index 44402619c43..02ee916458f 100644 --- a/src/test/codegen/global_asm_include.rs +++ b/src/test/codegen/global_asm_include.rs @@ -39,9 +39,10 @@ // ignore-emscripten // compile-flags: -C no-prepopulate-passes -#![feature(global_asm)] #![crate_type = "lib"] +use std::arch::global_asm; + // CHECK-LABEL: foo // CHECK: module asm // CHECK: module asm "{{[[:space:]]+}}jmp baz" diff --git a/src/test/codegen/global_asm_x2.rs b/src/test/codegen/global_asm_x2.rs index d632d0dde00..bdcf0ea843c 100644 --- a/src/test/codegen/global_asm_x2.rs +++ b/src/test/codegen/global_asm_x2.rs @@ -39,9 +39,10 @@ // ignore-emscripten // compile-flags: -C no-prepopulate-passes -#![feature(global_asm)] #![crate_type = "lib"] -#[no_std] +#![no_std] + +use core::arch::global_asm; // CHECK-LABEL: foo // CHECK: module asm @@ -49,11 +50,13 @@ // any other global_asm will be appended to this first block, so: // CHECK-LABEL: bar // CHECK: module asm "{{[[:space:]]+}}jmp quux" -global_asm!(r#" +global_asm!( + r#" .global foo foo: jmp baz -"#); +"# +); extern "C" { fn foo(); @@ -64,11 +67,13 @@ pub unsafe extern "C" fn baz() {} // no checks here; this has been appended to the first occurrence -global_asm!(r#" +global_asm!( + r#" .global bar bar: jmp quux -"#); +"# +); extern "C" { fn bar(); diff --git a/src/test/codegen/naked-noinline.rs b/src/test/codegen/naked-noinline.rs index d576a53826c..e34ccf5c5fe 100644 --- a/src/test/codegen/naked-noinline.rs +++ b/src/test/codegen/naked-noinline.rs @@ -3,28 +3,29 @@ // needs-asm-support // ignore-wasm32 #![crate_type = "lib"] -#![feature(asm)] #![feature(naked_functions)] +use std::arch::asm; + #[inline(always)] #[naked] #[no_mangle] pub unsafe extern "C" fn f() { -// Check that f has naked and noinline attributes. -// -// CHECK: define void @f() unnamed_addr [[ATTR:#[0-9]+]] -// CHECK-NEXT: start: -// CHECK-NEXT: call void asm + // Check that f has naked and noinline attributes. + // + // CHECK: define void @f() unnamed_addr [[ATTR:#[0-9]+]] + // CHECK-NEXT: start: + // CHECK-NEXT: call void asm asm!("", options(noreturn)); } #[no_mangle] pub unsafe fn g() { -// Check that call to f is not inlined. -// -// CHECK-LABEL: define void @g() -// CHECK-NEXT: start: -// CHECK-NEXT: call void @f() + // Check that call to f is not inlined. + // + // CHECK-LABEL: define void @g() + // CHECK-NEXT: start: + // CHECK-NEXT: call void @f() f(); } diff --git a/src/test/incremental/issue-72386.rs b/src/test/incremental/issue-72386.rs index 3dc7f502a59..be624faad04 100644 --- a/src/test/incremental/issue-72386.rs +++ b/src/test/incremental/issue-72386.rs @@ -4,13 +4,11 @@ // Checks that we don't ICE when switching to an invalid register // and back again -#![feature(asm)] +use std::arch::asm; #[cfg(any(rpass1, rpass3))] fn main() { - unsafe { - asm!("nop") - } + unsafe { asm!("nop") } } #[cfg(cfail1)] diff --git a/src/test/pretty/asm.pp b/src/test/pretty/asm.pp index a2065039692..5eade2933b8 100644 --- a/src/test/pretty/asm.pp +++ b/src/test/pretty/asm.pp @@ -1,15 +1,15 @@ #![feature(prelude_import)] #![no_std] -#![feature(asm)] #[prelude_import] use ::std::prelude::rust_2015::*; #[macro_use] extern crate std; - // pretty-mode:expanded // pp-exact:asm.pp // only-x86_64 +use std::arch::asm; + pub fn main() { let a: i32; let mut b = 4i32; diff --git a/src/test/pretty/asm.rs b/src/test/pretty/asm.rs index 1156ab769a0..1a3f972c8f2 100644 --- a/src/test/pretty/asm.rs +++ b/src/test/pretty/asm.rs @@ -1,9 +1,9 @@ -#![feature(asm)] - // pretty-mode:expanded // pp-exact:asm.pp // only-x86_64 +use std::arch::asm; + pub fn main() { let a: i32; let mut b = 4i32; @@ -20,8 +20,10 @@ pub fn main() { asm!("inst1 {}, 42", "inst2 {}, 24", in(reg) a, out(reg) b); asm!("inst2 {1}, 24", "inst1 {0}, 42", in(reg) a, out(reg) b); asm!("inst1 {}, 42", "inst2 {name}, 24", in(reg) a, name = out(reg) b); - asm!("inst1 -inst2"); + asm!( + "inst1 +inst2" + ); asm!("inst1\ninst2"); asm!("inst1\n\tinst2"); asm!("inst1\ninst2", "inst3\ninst4"); diff --git a/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/enclave/src/main.rs b/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/enclave/src/main.rs index 791dec2ed69..cde38aacf7f 100644 --- a/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/enclave/src/main.rs +++ b/src/test/run-make/x86_64-fortanix-unknown-sgx-lvi/enclave/src/main.rs @@ -1,6 +1,5 @@ -#![feature(global_asm)] - -global_asm!( r#" +std::arch::global_asm!( + r#" .text .global rust_plus_one_global_asm .type rust_plus_one_global_asm, @function @@ -8,41 +7,43 @@ movl (%rdi), %eax inc %eax retq -"#, options(att_syntax)); +"#, + options(att_syntax) +); -extern { - fn cc_plus_one_c(arg : &u32) -> u32; - fn cc_plus_one_c_asm(arg : &u32) -> u32; - fn cc_plus_one_cxx(arg : &u32) -> u32; - fn cc_plus_one_cxx_asm(arg : &u32) -> u32; - fn cc_plus_one_asm(arg : &u32) -> u32; - fn cmake_plus_one_c(arg : &u32) -> u32; - fn cmake_plus_one_c_asm(arg : &u32) -> u32; - fn cmake_plus_one_cxx(arg : &u32) -> u32; - fn cmake_plus_one_cxx_asm(arg : &u32) -> u32; - fn cmake_plus_one_c_global_asm(arg : &u32) -> u32; - fn cmake_plus_one_cxx_global_asm(arg : &u32) -> u32; - fn cmake_plus_one_asm(arg : &u32) -> u32; - fn rust_plus_one_global_asm(arg : &u32) -> u32; +extern "C" { + fn cc_plus_one_c(arg: &u32) -> u32; + fn cc_plus_one_c_asm(arg: &u32) -> u32; + fn cc_plus_one_cxx(arg: &u32) -> u32; + fn cc_plus_one_cxx_asm(arg: &u32) -> u32; + fn cc_plus_one_asm(arg: &u32) -> u32; + fn cmake_plus_one_c(arg: &u32) -> u32; + fn cmake_plus_one_c_asm(arg: &u32) -> u32; + fn cmake_plus_one_cxx(arg: &u32) -> u32; + fn cmake_plus_one_cxx_asm(arg: &u32) -> u32; + fn cmake_plus_one_c_global_asm(arg: &u32) -> u32; + fn cmake_plus_one_cxx_global_asm(arg: &u32) -> u32; + fn cmake_plus_one_asm(arg: &u32) -> u32; + fn rust_plus_one_global_asm(arg: &u32) -> u32; } fn main() { - let value : u32 = 41; + let value: u32 = 41; let question = "Answer to the Ultimate Question of Life, the Universe, and Everything:"; - unsafe{ - println!("{}: {}!", question,rust_plus_one_global_asm(&value)); - println!("{}: {}!", question,cc_plus_one_c(&value)); - println!("{}: {}!", question,cc_plus_one_c_asm(&value)); - println!("{}: {}!", question,cc_plus_one_cxx(&value)); - println!("{}: {}!", question,cc_plus_one_cxx_asm(&value)); - println!("{}: {}!", question,cc_plus_one_asm(&value)); - println!("{}: {}!", question,cmake_plus_one_c(&value)); - println!("{}: {}!", question,cmake_plus_one_c_asm(&value)); - println!("{}: {}!", question,cmake_plus_one_cxx(&value)); - println!("{}: {}!", question,cmake_plus_one_cxx_asm(&value)); - println!("{}: {}!", question,cmake_plus_one_c_global_asm(&value)); - println!("{}: {}!", question,cmake_plus_one_cxx_global_asm(&value)); - println!("{}: {}!", question,cmake_plus_one_asm(&value)); + unsafe { + println!("{}: {}!", question, rust_plus_one_global_asm(&value)); + println!("{}: {}!", question, cc_plus_one_c(&value)); + println!("{}: {}!", question, cc_plus_one_c_asm(&value)); + println!("{}: {}!", question, cc_plus_one_cxx(&value)); + println!("{}: {}!", question, cc_plus_one_cxx_asm(&value)); + println!("{}: {}!", question, cc_plus_one_asm(&value)); + println!("{}: {}!", question, cmake_plus_one_c(&value)); + println!("{}: {}!", question, cmake_plus_one_c_asm(&value)); + println!("{}: {}!", question, cmake_plus_one_cxx(&value)); + println!("{}: {}!", question, cmake_plus_one_cxx_asm(&value)); + println!("{}: {}!", question, cmake_plus_one_c_global_asm(&value)); + println!("{}: {}!", question, cmake_plus_one_cxx_global_asm(&value)); + println!("{}: {}!", question, cmake_plus_one_asm(&value)); } } diff --git a/src/test/rustdoc/asm-foreign.rs b/src/test/rustdoc/asm-foreign.rs index 570ed043dd9..d7550ca5aca 100644 --- a/src/test/rustdoc/asm-foreign.rs +++ b/src/test/rustdoc/asm-foreign.rs @@ -1,6 +1,6 @@ // Make sure rustdoc accepts asm! for a foreign architecture. -#![feature(asm)] +use std::arch::asm; // @has asm_foreign/fn.aarch64.html pub unsafe fn aarch64(a: f64, b: f64) -> f64 { diff --git a/src/test/rustdoc/asm-foreign2.rs b/src/test/rustdoc/asm-foreign2.rs index 34e313e7eac..87306901eb7 100644 --- a/src/test/rustdoc/asm-foreign2.rs +++ b/src/test/rustdoc/asm-foreign2.rs @@ -1,7 +1,7 @@ // only-aarch64 // Make sure rustdoc accepts options(att_syntax) asm! on non-x86 targets. -#![feature(asm)] +use std::arch::asm; // @has asm_foreign2/fn.x86.html pub unsafe fn x86(x: i64) -> i64 { diff --git a/src/test/ui/asm/aarch64/bad-options.rs b/src/test/ui/asm/aarch64/bad-options.rs index 8775eba4a78..6172027a2fa 100644 --- a/src/test/ui/asm/aarch64/bad-options.rs +++ b/src/test/ui/asm/aarch64/bad-options.rs @@ -1,6 +1,6 @@ // only-aarch64 -#![feature(asm, global_asm)] +use std::arch::{asm, global_asm}; fn main() { let mut foo = 0; diff --git a/src/test/ui/asm/aarch64/bad-reg.rs b/src/test/ui/asm/aarch64/bad-reg.rs index e346f8d992a..8619b3960a6 100644 --- a/src/test/ui/asm/aarch64/bad-reg.rs +++ b/src/test/ui/asm/aarch64/bad-reg.rs @@ -1,7 +1,9 @@ // only-aarch64 // compile-flags: -C target-feature=+fp -#![feature(asm, asm_const, asm_sym)] +#![feature(asm_const, asm_sym)] + +use std::arch::asm; fn main() { let mut foo = 0; diff --git a/src/test/ui/asm/aarch64/const.rs b/src/test/ui/asm/aarch64/const.rs index 49fe48600c2..73512dcc446 100644 --- a/src/test/ui/asm/aarch64/const.rs +++ b/src/test/ui/asm/aarch64/const.rs @@ -3,7 +3,9 @@ // revisions: mirunsafeck thirunsafeck // [thirunsafeck]compile-flags: -Z thir-unsafeck -#![feature(asm, global_asm, asm_const)] +#![feature(asm_const)] + +use std::arch::{asm, global_asm}; fn const_generic() -> usize { unsafe { diff --git a/src/test/ui/asm/aarch64/duplicate-options.fixed b/src/test/ui/asm/aarch64/duplicate-options.fixed index d95c646e9f9..7cc378e34d8 100644 --- a/src/test/ui/asm/aarch64/duplicate-options.fixed +++ b/src/test/ui/asm/aarch64/duplicate-options.fixed @@ -1,8 +1,6 @@ // only-aarch64 // run-rustfix -#![feature(asm, global_asm)] - fn main() { unsafe { asm!("", options(nomem, )); diff --git a/src/test/ui/asm/aarch64/duplicate-options.rs b/src/test/ui/asm/aarch64/duplicate-options.rs index eec356463d4..bd1f1570136 100644 --- a/src/test/ui/asm/aarch64/duplicate-options.rs +++ b/src/test/ui/asm/aarch64/duplicate-options.rs @@ -1,7 +1,7 @@ // only-aarch64 // run-rustfix -#![feature(asm, global_asm)] +use std::arch::asm; fn main() { unsafe { @@ -19,8 +19,8 @@ fn main() { "", options(nomem, noreturn), options(preserves_flags, noreturn), //~ ERROR the `noreturn` option was already provided - options(nomem, nostack), //~ ERROR the `nomem` option was already provided - options(noreturn), //~ ERROR the `noreturn` option was already provided + options(nomem, nostack), //~ ERROR the `nomem` option was already provided + options(noreturn), //~ ERROR the `noreturn` option was already provided ); } } diff --git a/src/test/ui/asm/aarch64/interpolated-idents.rs b/src/test/ui/asm/aarch64/interpolated-idents.rs index 1cdf0965667..ece62ce3930 100644 --- a/src/test/ui/asm/aarch64/interpolated-idents.rs +++ b/src/test/ui/asm/aarch64/interpolated-idents.rs @@ -1,6 +1,6 @@ // only-aarch64 -#![feature(asm)] +use std::arch::asm; macro_rules! m { ($in:ident $out:ident $lateout:ident $inout:ident $inlateout:ident $const:ident $sym:ident diff --git a/src/test/ui/asm/aarch64/may_unwind.rs b/src/test/ui/asm/aarch64/may_unwind.rs index 94cc7d75049..ac8cc62027e 100644 --- a/src/test/ui/asm/aarch64/may_unwind.rs +++ b/src/test/ui/asm/aarch64/may_unwind.rs @@ -3,8 +3,9 @@ // run-pass // needs-asm-support -#![feature(asm, asm_sym, asm_unwind)] +#![feature(asm_sym, asm_unwind)] +use std::arch::asm; use std::panic::{catch_unwind, resume_unwind, AssertUnwindSafe}; struct Foo<'a>(&'a mut bool); diff --git a/src/test/ui/asm/aarch64/parse-error.rs b/src/test/ui/asm/aarch64/parse-error.rs index bc0aed8fe55..59d6b28d0fd 100644 --- a/src/test/ui/asm/aarch64/parse-error.rs +++ b/src/test/ui/asm/aarch64/parse-error.rs @@ -1,6 +1,8 @@ // only-aarch64 -#![feature(asm, global_asm, asm_const)] +#![feature(asm_const)] + +use std::arch::{asm, global_asm}; fn main() { let mut foo = 0; diff --git a/src/test/ui/asm/aarch64/srcloc.rs b/src/test/ui/asm/aarch64/srcloc.rs index 143ed182403..609f5e80d24 100644 --- a/src/test/ui/asm/aarch64/srcloc.rs +++ b/src/test/ui/asm/aarch64/srcloc.rs @@ -1,7 +1,8 @@ // only-aarch64 // build-fail // compile-flags: -Ccodegen-units=1 -#![feature(asm)] + +use std::arch::asm; // Checks that inline asm errors are mapped to the correct line in the source code. diff --git a/src/test/ui/asm/aarch64/sym.rs b/src/test/ui/asm/aarch64/sym.rs index b0dd143a0a1..4fd31070ec7 100644 --- a/src/test/ui/asm/aarch64/sym.rs +++ b/src/test/ui/asm/aarch64/sym.rs @@ -2,7 +2,9 @@ // only-linux // run-pass -#![feature(asm, thread_local, asm_sym)] +#![feature(thread_local, asm_sym)] + +use std::arch::asm; extern "C" fn f1() -> i32 { 111 diff --git a/src/test/ui/asm/aarch64/type-check-2.rs b/src/test/ui/asm/aarch64/type-check-2.rs index e1e8a91dda6..1b91f5d0678 100644 --- a/src/test/ui/asm/aarch64/type-check-2.rs +++ b/src/test/ui/asm/aarch64/type-check-2.rs @@ -1,6 +1,8 @@ // only-aarch64 -#![feature(asm, repr_simd, never_type, asm_sym)] +#![feature(repr_simd, never_type, asm_sym)] + +use std::arch::asm; #[repr(simd)] #[derive(Clone, Copy)] diff --git a/src/test/ui/asm/aarch64/type-check-3.rs b/src/test/ui/asm/aarch64/type-check-3.rs index fc1831a520a..8cac18b8052 100644 --- a/src/test/ui/asm/aarch64/type-check-3.rs +++ b/src/test/ui/asm/aarch64/type-check-3.rs @@ -1,9 +1,10 @@ // only-aarch64 // compile-flags: -C target-feature=+neon -#![feature(asm, global_asm, repr_simd, stdsimd, asm_const)] +#![feature(repr_simd, stdsimd, asm_const)] use std::arch::aarch64::float64x2_t; +use std::arch::{asm, global_asm}; #[repr(simd)] #[derive(Copy, Clone)] diff --git a/src/test/ui/asm/issue-72570.rs b/src/test/ui/asm/issue-72570.rs index 960f7427e34..bb13816348d 100644 --- a/src/test/ui/asm/issue-72570.rs +++ b/src/test/ui/asm/issue-72570.rs @@ -2,7 +2,7 @@ // needs-asm-support // Also test for #72960 -#![feature(asm)] +use std::arch::asm; fn main() { unsafe { diff --git a/src/test/ui/asm/issue-87802.rs b/src/test/ui/asm/issue-87802.rs index 5b6453c42c6..5b2e636c29f 100644 --- a/src/test/ui/asm/issue-87802.rs +++ b/src/test/ui/asm/issue-87802.rs @@ -4,7 +4,7 @@ // ignore-wasm32 // Make sure rustc doesn't ICE on asm! when output type is !. -#![feature(asm)] +use std::arch::asm; fn hmm() -> ! { let x; diff --git a/src/test/ui/asm/issue-89305.rs b/src/test/ui/asm/issue-89305.rs index a4b22e21028..05677912dff 100644 --- a/src/test/ui/asm/issue-89305.rs +++ b/src/test/ui/asm/issue-89305.rs @@ -4,9 +4,10 @@ // check-pass // needs-asm-support -#![feature(asm)] #![warn(unused)] +use std::arch::asm; + fn main() { unsafe { let x: () = asm!("nop"); diff --git a/src/test/ui/asm/issue-89305.stderr b/src/test/ui/asm/issue-89305.stderr index 3fb1526183b..7efc5102042 100644 --- a/src/test/ui/asm/issue-89305.stderr +++ b/src/test/ui/asm/issue-89305.stderr @@ -1,11 +1,11 @@ warning: unused variable: `x` - --> $DIR/issue-89305.rs:12:13 + --> $DIR/issue-89305.rs:13:13 | LL | let x: () = asm!("nop"); | ^ help: if this is intentional, prefix it with an underscore: `_x` | note: the lint level is defined here - --> $DIR/issue-89305.rs:8:9 + --> $DIR/issue-89305.rs:7:9 | LL | #![warn(unused)] | ^^^^^^ diff --git a/src/test/ui/asm/may_unwind.rs b/src/test/ui/asm/may_unwind.rs index 436e8b9d95a..117c0a63aa4 100644 --- a/src/test/ui/asm/may_unwind.rs +++ b/src/test/ui/asm/may_unwind.rs @@ -2,7 +2,9 @@ // run-pass // needs-asm-support -#![feature(asm, asm_unwind)] +#![feature(asm_unwind)] + +use std::arch::asm; fn main() { unsafe { asm!("", options(may_unwind)) }; diff --git a/src/test/ui/asm/naked-functions-ffi.rs b/src/test/ui/asm/naked-functions-ffi.rs index f6725605b92..c8bee504d02 100644 --- a/src/test/ui/asm/naked-functions-ffi.rs +++ b/src/test/ui/asm/naked-functions-ffi.rs @@ -1,12 +1,15 @@ // check-pass // needs-asm-support -#![feature(asm)] #![feature(naked_functions)] #![crate_type = "lib"] +use std::arch::asm; + #[naked] pub extern "C" fn naked(p: char) -> u128 { //~^ WARN uses type `char` //~| WARN uses type `u128` - unsafe { asm!("", options(noreturn)); } + unsafe { + asm!("", options(noreturn)); + } } diff --git a/src/test/ui/asm/naked-functions-ffi.stderr b/src/test/ui/asm/naked-functions-ffi.stderr index a6772badeb6..ac743551311 100644 --- a/src/test/ui/asm/naked-functions-ffi.stderr +++ b/src/test/ui/asm/naked-functions-ffi.stderr @@ -1,5 +1,5 @@ warning: `extern` fn uses type `char`, which is not FFI-safe - --> $DIR/naked-functions-ffi.rs:8:28 + --> $DIR/naked-functions-ffi.rs:9:28 | LL | pub extern "C" fn naked(p: char) -> u128 { | ^^^^ not FFI-safe @@ -9,7 +9,7 @@ LL | pub extern "C" fn naked(p: char) -> u128 { = note: the `char` type has no C equivalent warning: `extern` fn uses type `u128`, which is not FFI-safe - --> $DIR/naked-functions-ffi.rs:8:37 + --> $DIR/naked-functions-ffi.rs:9:37 | LL | pub extern "C" fn naked(p: char) -> u128 { | ^^^^ not FFI-safe diff --git a/src/test/ui/asm/naked-functions-unused.rs b/src/test/ui/asm/naked-functions-unused.rs index 4c5c2ac1c19..4360d9addf0 100644 --- a/src/test/ui/asm/naked-functions-unused.rs +++ b/src/test/ui/asm/naked-functions-unused.rs @@ -2,7 +2,6 @@ //[x86_64] only-x86_64 //[aarch64] only-aarch64 #![deny(unused)] -#![feature(asm)] #![feature(naked_functions)] #![crate_type = "lib"] @@ -12,6 +11,8 @@ pub trait Trait { } pub mod normal { + use std::arch::asm; + pub extern "C" fn function(a: usize, b: usize) -> usize { //~^ ERROR unused variable: `a` //~| ERROR unused variable: `b` @@ -50,6 +51,8 @@ extern "C" fn trait_method(&self, a: usize, b: usize) -> usize { } pub mod naked { + use std::arch::asm; + #[naked] pub extern "C" fn function(a: usize, b: usize) -> usize { unsafe { asm!("", options(noreturn)); } diff --git a/src/test/ui/asm/naked-functions-unused.x86_64.stderr b/src/test/ui/asm/naked-functions-unused.x86_64.stderr index a898ab19a73..cf4a1d9174e 100644 --- a/src/test/ui/asm/naked-functions-unused.x86_64.stderr +++ b/src/test/ui/asm/naked-functions-unused.x86_64.stderr @@ -1,5 +1,5 @@ error: unused variable: `a` - --> $DIR/naked-functions-unused.rs:15:32 + --> $DIR/naked-functions-unused.rs:16:32 | LL | pub extern "C" fn function(a: usize, b: usize) -> usize { | ^ help: if this is intentional, prefix it with an underscore: `_a` @@ -12,55 +12,55 @@ LL | #![deny(unused)] = note: `#[deny(unused_variables)]` implied by `#[deny(unused)]` error: unused variable: `b` - --> $DIR/naked-functions-unused.rs:15:42 + --> $DIR/naked-functions-unused.rs:16:42 | LL | pub extern "C" fn function(a: usize, b: usize) -> usize { | ^ help: if this is intentional, prefix it with an underscore: `_b` error: unused variable: `a` - --> $DIR/naked-functions-unused.rs:24:38 + --> $DIR/naked-functions-unused.rs:25:38 | LL | pub extern "C" fn associated(a: usize, b: usize) -> usize { | ^ help: if this is intentional, prefix it with an underscore: `_a` error: unused variable: `b` - --> $DIR/naked-functions-unused.rs:24:48 + --> $DIR/naked-functions-unused.rs:25:48 | LL | pub extern "C" fn associated(a: usize, b: usize) -> usize { | ^ help: if this is intentional, prefix it with an underscore: `_b` error: unused variable: `a` - --> $DIR/naked-functions-unused.rs:30:41 + --> $DIR/naked-functions-unused.rs:31:41 | LL | pub extern "C" fn method(&self, a: usize, b: usize) -> usize { | ^ help: if this is intentional, prefix it with an underscore: `_a` error: unused variable: `b` - --> $DIR/naked-functions-unused.rs:30:51 + --> $DIR/naked-functions-unused.rs:31:51 | LL | pub extern "C" fn method(&self, a: usize, b: usize) -> usize { | ^ help: if this is intentional, prefix it with an underscore: `_b` error: unused variable: `a` - --> $DIR/naked-functions-unused.rs:38:40 + --> $DIR/naked-functions-unused.rs:39:40 | LL | extern "C" fn trait_associated(a: usize, b: usize) -> usize { | ^ help: if this is intentional, prefix it with an underscore: `_a` error: unused variable: `b` - --> $DIR/naked-functions-unused.rs:38:50 + --> $DIR/naked-functions-unused.rs:39:50 | LL | extern "C" fn trait_associated(a: usize, b: usize) -> usize { | ^ help: if this is intentional, prefix it with an underscore: `_b` error: unused variable: `a` - --> $DIR/naked-functions-unused.rs:44:43 + --> $DIR/naked-functions-unused.rs:45:43 | LL | extern "C" fn trait_method(&self, a: usize, b: usize) -> usize { | ^ help: if this is intentional, prefix it with an underscore: `_a` error: unused variable: `b` - --> $DIR/naked-functions-unused.rs:44:53 + --> $DIR/naked-functions-unused.rs:45:53 | LL | extern "C" fn trait_method(&self, a: usize, b: usize) -> usize { | ^ help: if this is intentional, prefix it with an underscore: `_b` diff --git a/src/test/ui/asm/naked-functions.rs b/src/test/ui/asm/naked-functions.rs index 7154ce26efc..b44204b9005 100644 --- a/src/test/ui/asm/naked-functions.rs +++ b/src/test/ui/asm/naked-functions.rs @@ -3,7 +3,6 @@ // ignore-spirv // ignore-wasm32 -#![feature(asm)] #![feature(llvm_asm)] #![feature(naked_functions)] #![feature(or_patterns)] @@ -11,6 +10,8 @@ #![crate_type = "lib"] #![allow(deprecated)] // llvm_asm! +use std::arch::asm; + #[repr(C)] pub struct P { x: u8, diff --git a/src/test/ui/asm/naked-functions.stderr b/src/test/ui/asm/naked-functions.stderr index e4ddb97ca27..8e177f5a52c 100644 --- a/src/test/ui/asm/naked-functions.stderr +++ b/src/test/ui/asm/naked-functions.stderr @@ -1,35 +1,35 @@ error: asm with the `pure` option must have at least one output - --> $DIR/naked-functions.rs:135:14 + --> $DIR/naked-functions.rs:136:14 | LL | asm!("", options(readonly, nostack), options(pure)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^ error: patterns not allowed in naked function parameters - --> $DIR/naked-functions.rs:22:5 + --> $DIR/naked-functions.rs:23:5 | LL | mut a: u32, | ^^^^^ error: patterns not allowed in naked function parameters - --> $DIR/naked-functions.rs:24:5 + --> $DIR/naked-functions.rs:25:5 | LL | &b: &i32, | ^^ error: patterns not allowed in naked function parameters - --> $DIR/naked-functions.rs:26:6 + --> $DIR/naked-functions.rs:27:6 | LL | (None | Some(_)): Option>, | ^^^^^^^^^^^^^^ error: patterns not allowed in naked function parameters - --> $DIR/naked-functions.rs:28:5 + --> $DIR/naked-functions.rs:29:5 | LL | P { x, y }: P, | ^^^^^^^^^^ error: referencing function parameters is not allowed in naked functions - --> $DIR/naked-functions.rs:38:5 + --> $DIR/naked-functions.rs:39:5 | LL | a + 1 | ^ @@ -37,7 +37,7 @@ LL | a + 1 = help: follow the calling convention in asm block to use parameters warning: naked functions must contain a single asm block - --> $DIR/naked-functions.rs:35:1 + --> $DIR/naked-functions.rs:36:1 | LL | / pub unsafe extern "C" fn inc(a: u32) -> u32 { LL | | @@ -53,7 +53,7 @@ LL | | } = note: for more information, see issue #32408 error: referencing function parameters is not allowed in naked functions - --> $DIR/naked-functions.rs:44:31 + --> $DIR/naked-functions.rs:45:31 | LL | asm!("/* {0} */", in(reg) a, options(noreturn)); | ^ @@ -61,7 +61,7 @@ LL | asm!("/* {0} */", in(reg) a, options(noreturn)); = help: follow the calling convention in asm block to use parameters warning: only `const` and `sym` operands are supported in naked functions - --> $DIR/naked-functions.rs:44:23 + --> $DIR/naked-functions.rs:45:23 | LL | asm!("/* {0} */", in(reg) a, options(noreturn)); | ^^^^^^^^^ @@ -70,7 +70,7 @@ LL | asm!("/* {0} */", in(reg) a, options(noreturn)); = note: for more information, see issue #32408 warning: naked functions must contain a single asm block - --> $DIR/naked-functions.rs:51:1 + --> $DIR/naked-functions.rs:52:1 | LL | / pub unsafe extern "C" fn inc_closure(a: u32) -> u32 { LL | | @@ -84,7 +84,7 @@ LL | | } = note: for more information, see issue #32408 warning: only `const` and `sym` operands are supported in naked functions - --> $DIR/naked-functions.rs:71:10 + --> $DIR/naked-functions.rs:72:10 | LL | in(reg) a, | ^^^^^^^^^ @@ -102,7 +102,7 @@ LL | out(reg) e, = note: for more information, see issue #32408 warning: asm in naked functions must use `noreturn` option - --> $DIR/naked-functions.rs:68:5 + --> $DIR/naked-functions.rs:69:5 | LL | / asm!("/* {0} {1} {2} {3} {4} {5} {6} */", LL | | @@ -117,7 +117,7 @@ LL | | ); = note: for more information, see issue #32408 warning: naked functions must contain a single asm block - --> $DIR/naked-functions.rs:58:1 + --> $DIR/naked-functions.rs:59:1 | LL | / pub unsafe extern "C" fn unsupported_operands() { LL | | @@ -141,7 +141,7 @@ LL | | } = note: for more information, see issue #32408 warning: naked functions must contain a single asm block - --> $DIR/naked-functions.rs:84:1 + --> $DIR/naked-functions.rs:85:1 | LL | / pub extern "C" fn missing_assembly() { LL | | @@ -153,7 +153,7 @@ LL | | } = note: for more information, see issue #32408 warning: asm in naked functions must use `noreturn` option - --> $DIR/naked-functions.rs:93:5 + --> $DIR/naked-functions.rs:94:5 | LL | asm!(""); | ^^^^^^^^ @@ -162,7 +162,7 @@ LL | asm!(""); = note: for more information, see issue #32408 warning: asm in naked functions must use `noreturn` option - --> $DIR/naked-functions.rs:96:5 + --> $DIR/naked-functions.rs:97:5 | LL | asm!(""); | ^^^^^^^^ @@ -171,7 +171,7 @@ LL | asm!(""); = note: for more information, see issue #32408 warning: asm in naked functions must use `noreturn` option - --> $DIR/naked-functions.rs:99:5 + --> $DIR/naked-functions.rs:100:5 | LL | asm!(""); | ^^^^^^^^ @@ -180,7 +180,7 @@ LL | asm!(""); = note: for more information, see issue #32408 warning: naked functions must contain a single asm block - --> $DIR/naked-functions.rs:90:1 + --> $DIR/naked-functions.rs:91:1 | LL | / pub extern "C" fn too_many_asm_blocks() { LL | | @@ -202,7 +202,7 @@ LL | | } = note: for more information, see issue #32408 error: referencing function parameters is not allowed in naked functions - --> $DIR/naked-functions.rs:110:11 + --> $DIR/naked-functions.rs:111:11 | LL | *&y | ^ @@ -210,7 +210,7 @@ LL | *&y = help: follow the calling convention in asm block to use parameters warning: naked functions must contain a single asm block - --> $DIR/naked-functions.rs:107:5 + --> $DIR/naked-functions.rs:108:5 | LL | / pub extern "C" fn inner(y: usize) -> usize { LL | | @@ -225,7 +225,7 @@ LL | | } = note: for more information, see issue #32408 warning: the LLVM-style inline assembly is unsupported in naked functions - --> $DIR/naked-functions.rs:120:5 + --> $DIR/naked-functions.rs:121:5 | LL | llvm_asm!(""); | ^^^^^^^^^^^^^ @@ -236,7 +236,7 @@ LL | llvm_asm!(""); = note: this warning originates in the macro `llvm_asm` (in Nightly builds, run with -Z macro-backtrace for more info) warning: naked functions must contain a single asm block - --> $DIR/naked-functions.rs:117:1 + --> $DIR/naked-functions.rs:118:1 | LL | / unsafe extern "C" fn llvm() -> ! { LL | | @@ -252,7 +252,7 @@ LL | | } = note: for more information, see issue #32408 warning: asm options unsupported in naked functions: `nomem`, `preserves_flags` - --> $DIR/naked-functions.rs:128:5 + --> $DIR/naked-functions.rs:129:5 | LL | asm!("", options(nomem, preserves_flags, noreturn)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -261,7 +261,7 @@ LL | asm!("", options(nomem, preserves_flags, noreturn)); = note: for more information, see issue #32408 warning: asm options unsupported in naked functions: `nostack`, `pure`, `readonly` - --> $DIR/naked-functions.rs:135:5 + --> $DIR/naked-functions.rs:136:5 | LL | asm!("", options(readonly, nostack), options(pure)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -270,7 +270,7 @@ LL | asm!("", options(readonly, nostack), options(pure)); = note: for more information, see issue #32408 warning: asm in naked functions must use `noreturn` option - --> $DIR/naked-functions.rs:135:5 + --> $DIR/naked-functions.rs:136:5 | LL | asm!("", options(readonly, nostack), options(pure)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -279,7 +279,7 @@ LL | asm!("", options(readonly, nostack), options(pure)); = note: for more information, see issue #32408 warning: Rust ABI is unsupported in naked functions - --> $DIR/naked-functions.rs:144:15 + --> $DIR/naked-functions.rs:145:15 | LL | pub unsafe fn default_abi() { | ^^^^^^^^^^^ @@ -287,13 +287,13 @@ LL | pub unsafe fn default_abi() { = note: `#[warn(undefined_naked_function_abi)]` on by default warning: Rust ABI is unsupported in naked functions - --> $DIR/naked-functions.rs:150:15 + --> $DIR/naked-functions.rs:151:15 | LL | pub unsafe fn rust_abi() { | ^^^^^^^^ warning: naked functions cannot be inlined - --> $DIR/naked-functions.rs:190:1 + --> $DIR/naked-functions.rs:191:1 | LL | #[inline] | ^^^^^^^^^ @@ -302,7 +302,7 @@ LL | #[inline] = note: for more information, see issue #32408 warning: naked functions cannot be inlined - --> $DIR/naked-functions.rs:198:1 + --> $DIR/naked-functions.rs:199:1 | LL | #[inline(always)] | ^^^^^^^^^^^^^^^^^ @@ -311,7 +311,7 @@ LL | #[inline(always)] = note: for more information, see issue #32408 warning: naked functions cannot be inlined - --> $DIR/naked-functions.rs:206:1 + --> $DIR/naked-functions.rs:207:1 | LL | #[inline(never)] | ^^^^^^^^^^^^^^^^ @@ -320,7 +320,7 @@ LL | #[inline(never)] = note: for more information, see issue #32408 warning: naked functions cannot be inlined - --> $DIR/naked-functions.rs:214:1 + --> $DIR/naked-functions.rs:215:1 | LL | #[inline] | ^^^^^^^^^ @@ -329,7 +329,7 @@ LL | #[inline] = note: for more information, see issue #32408 warning: naked functions cannot be inlined - --> $DIR/naked-functions.rs:217:1 + --> $DIR/naked-functions.rs:218:1 | LL | #[inline(always)] | ^^^^^^^^^^^^^^^^^ @@ -338,7 +338,7 @@ LL | #[inline(always)] = note: for more information, see issue #32408 warning: naked functions cannot be inlined - --> $DIR/naked-functions.rs:220:1 + --> $DIR/naked-functions.rs:221:1 | LL | #[inline(never)] | ^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/asm/naked-invalid-attr.rs b/src/test/ui/asm/naked-invalid-attr.rs index 2576d1124c8..ea8f560ff5d 100644 --- a/src/test/ui/asm/naked-invalid-attr.rs +++ b/src/test/ui/asm/naked-invalid-attr.rs @@ -1,10 +1,11 @@ // Checks that #[naked] attribute can be placed on function definitions only. // // needs-asm-support -#![feature(asm)] #![feature(naked_functions)] #![naked] //~ ERROR should be applied to a function definition +use std::arch::asm; + extern "C" { #[naked] //~ ERROR should be applied to a function definition fn f(); diff --git a/src/test/ui/asm/naked-invalid-attr.stderr b/src/test/ui/asm/naked-invalid-attr.stderr index 565c2986a66..58344be9334 100644 --- a/src/test/ui/asm/naked-invalid-attr.stderr +++ b/src/test/ui/asm/naked-invalid-attr.stderr @@ -1,5 +1,5 @@ error: attribute should be applied to a function definition - --> $DIR/naked-invalid-attr.rs:13:1 + --> $DIR/naked-invalid-attr.rs:14:1 | LL | #[naked] | ^^^^^^^^ @@ -11,13 +11,13 @@ LL | | } | |_- not a function definition error: attribute should be applied to a function definition - --> $DIR/naked-invalid-attr.rs:50:5 + --> $DIR/naked-invalid-attr.rs:51:5 | LL | #[naked] || {}; | ^^^^^^^^ ----- not a function definition error: attribute should be applied to a function definition - --> $DIR/naked-invalid-attr.rs:21:5 + --> $DIR/naked-invalid-attr.rs:22:5 | LL | #[naked] | ^^^^^^^^ @@ -25,7 +25,7 @@ LL | extern "C" fn invoke(&self); | ---------------------------- not a function definition error: attribute should be applied to a function definition - --> $DIR/naked-invalid-attr.rs:9:5 + --> $DIR/naked-invalid-attr.rs:10:5 | LL | #[naked] | ^^^^^^^^ @@ -33,7 +33,7 @@ LL | fn f(); | ------- not a function definition error: attribute should be applied to a function definition - --> $DIR/naked-invalid-attr.rs:6:1 + --> $DIR/naked-invalid-attr.rs:5:1 | LL | #![naked] | ^^^^^^^^^ diff --git a/src/test/ui/asm/named-asm-labels.rs b/src/test/ui/asm/named-asm-labels.rs index c87188e46a2..160dbf617c4 100644 --- a/src/test/ui/asm/named-asm-labels.rs +++ b/src/test/ui/asm/named-asm-labels.rs @@ -11,7 +11,9 @@ // which causes less readable LLVM errors and in the worst cases causes ICEs // or segfaults based on system dependent behavior and codegen flags. -#![feature(asm, global_asm, naked_functions, asm_const)] +#![feature(naked_functions, asm_const)] + +use std::arch::{asm, global_asm}; #[no_mangle] pub static FOO: usize = 42; diff --git a/src/test/ui/asm/named-asm-labels.stderr b/src/test/ui/asm/named-asm-labels.stderr index 75c848cdc57..b8ff42d86b5 100644 --- a/src/test/ui/asm/named-asm-labels.stderr +++ b/src/test/ui/asm/named-asm-labels.stderr @@ -1,141 +1,126 @@ error: avoid using named labels in inline assembly - --> $DIR/named-asm-labels.rs:22:15 + --> $DIR/named-asm-labels.rs:24:15 | LL | asm!("bar: nop"); | ^^^ | = note: `#[deny(named_asm_labels)]` on by default = help: only local labels of the form `:` should be used in inline asm - = note: see the asm section of the unstable book for more information error: avoid using named labels in inline assembly - --> $DIR/named-asm-labels.rs:25:15 + --> $DIR/named-asm-labels.rs:27:15 | LL | asm!("abcd:"); | ^^^^ | = help: only local labels of the form `:` should be used in inline asm - = note: see the asm section of the unstable book for more information error: avoid using named labels in inline assembly - --> $DIR/named-asm-labels.rs:28:15 + --> $DIR/named-asm-labels.rs:30:15 | LL | asm!("foo: bar1: nop"); | ^^^ ^^^^ | = help: only local labels of the form `:` should be used in inline asm - = note: see the asm section of the unstable book for more information error: avoid using named labels in inline assembly - --> $DIR/named-asm-labels.rs:32:15 + --> $DIR/named-asm-labels.rs:34:15 | LL | asm!("foo1: nop", "nop"); | ^^^^ | = help: only local labels of the form `:` should be used in inline asm - = note: see the asm section of the unstable book for more information error: avoid using named labels in inline assembly - --> $DIR/named-asm-labels.rs:33:15 + --> $DIR/named-asm-labels.rs:35:15 | LL | asm!("foo2: foo3: nop", "nop"); | ^^^^ ^^^^ | = help: only local labels of the form `:` should be used in inline asm - = note: see the asm section of the unstable book for more information error: avoid using named labels in inline assembly - --> $DIR/named-asm-labels.rs:35:22 + --> $DIR/named-asm-labels.rs:37:22 | LL | asm!("nop", "foo4: nop"); | ^^^^ | = help: only local labels of the form `:` should be used in inline asm - = note: see the asm section of the unstable book for more information error: avoid using named labels in inline assembly - --> $DIR/named-asm-labels.rs:36:15 + --> $DIR/named-asm-labels.rs:38:15 | LL | asm!("foo5: nop", "foo6: nop"); | ^^^^ | = help: only local labels of the form `:` should be used in inline asm - = note: see the asm section of the unstable book for more information error: avoid using named labels in inline assembly - --> $DIR/named-asm-labels.rs:36:28 + --> $DIR/named-asm-labels.rs:38:28 | LL | asm!("foo5: nop", "foo6: nop"); | ^^^^ | = help: only local labels of the form `:` should be used in inline asm - = note: see the asm section of the unstable book for more information error: avoid using named labels in inline assembly - --> $DIR/named-asm-labels.rs:41:15 + --> $DIR/named-asm-labels.rs:43:15 | LL | asm!("foo7: nop; foo8: nop"); | ^^^^ ^^^^ | = help: only local labels of the form `:` should be used in inline asm - = note: see the asm section of the unstable book for more information error: avoid using named labels in inline assembly - --> $DIR/named-asm-labels.rs:43:15 + --> $DIR/named-asm-labels.rs:45:15 | LL | asm!("foo9: nop; nop"); | ^^^^ | = help: only local labels of the form `:` should be used in inline asm - = note: see the asm section of the unstable book for more information error: avoid using named labels in inline assembly - --> $DIR/named-asm-labels.rs:44:20 + --> $DIR/named-asm-labels.rs:46:20 | LL | asm!("nop; foo10: nop"); | ^^^^^ | = help: only local labels of the form `:` should be used in inline asm - = note: see the asm section of the unstable book for more information error: avoid using named labels in inline assembly - --> $DIR/named-asm-labels.rs:47:15 + --> $DIR/named-asm-labels.rs:49:15 | LL | asm!("bar2: nop\n bar3: nop"); | ^^^^ ^^^^ | = help: only local labels of the form `:` should be used in inline asm - = note: see the asm section of the unstable book for more information error: avoid using named labels in inline assembly - --> $DIR/named-asm-labels.rs:49:15 + --> $DIR/named-asm-labels.rs:51:15 | LL | asm!("bar4: nop\n nop"); | ^^^^ | = help: only local labels of the form `:` should be used in inline asm - = note: see the asm section of the unstable book for more information error: avoid using named labels in inline assembly - --> $DIR/named-asm-labels.rs:50:21 + --> $DIR/named-asm-labels.rs:52:21 | LL | asm!("nop\n bar5: nop"); | ^^^^ | = help: only local labels of the form `:` should be used in inline asm - = note: see the asm section of the unstable book for more information error: avoid using named labels in inline assembly - --> $DIR/named-asm-labels.rs:51:21 + --> $DIR/named-asm-labels.rs:53:21 | LL | asm!("nop\n bar6: bar7: nop"); | ^^^^ ^^^^ | = help: only local labels of the form `:` should be used in inline asm - = note: see the asm section of the unstable book for more information error: avoid using named labels in inline assembly - --> $DIR/named-asm-labels.rs:57:13 + --> $DIR/named-asm-labels.rs:59:13 | LL | blah2: nop | ^^^^^ @@ -143,192 +128,171 @@ LL | blah3: nop | ^^^^^ | = help: only local labels of the form `:` should be used in inline asm - = note: see the asm section of the unstable book for more information error: avoid using named labels in inline assembly - --> $DIR/named-asm-labels.rs:66:19 + --> $DIR/named-asm-labels.rs:68:19 | LL | nop ; blah4: nop | ^^^^^ | = help: only local labels of the form `:` should be used in inline asm - = note: see the asm section of the unstable book for more information error: avoid using named labels in inline assembly - --> $DIR/named-asm-labels.rs:80:15 + --> $DIR/named-asm-labels.rs:82:15 | LL | asm!("blah1: 2bar: nop"); | ^^^^^ | = help: only local labels of the form `:` should be used in inline asm - = note: see the asm section of the unstable book for more information error: avoid using named labels in inline assembly - --> $DIR/named-asm-labels.rs:83:15 + --> $DIR/named-asm-labels.rs:85:15 | LL | asm!("def: def: nop"); | ^^^ | = help: only local labels of the form `:` should be used in inline asm - = note: see the asm section of the unstable book for more information error: avoid using named labels in inline assembly - --> $DIR/named-asm-labels.rs:84:15 + --> $DIR/named-asm-labels.rs:86:15 | LL | asm!("def: nop\ndef: nop"); | ^^^ | = help: only local labels of the form `:` should be used in inline asm - = note: see the asm section of the unstable book for more information error: avoid using named labels in inline assembly - --> $DIR/named-asm-labels.rs:85:15 + --> $DIR/named-asm-labels.rs:87:15 | LL | asm!("def: nop; def: nop"); | ^^^ | = help: only local labels of the form `:` should be used in inline asm - = note: see the asm section of the unstable book for more information error: avoid using named labels in inline assembly - --> $DIR/named-asm-labels.rs:93:15 + --> $DIR/named-asm-labels.rs:95:15 | LL | asm!("fooo\u{003A} nop"); | ^^^^^^^^^^^^^^^^ | = help: only local labels of the form `:` should be used in inline asm - = note: see the asm section of the unstable book for more information error: avoid using named labels in inline assembly - --> $DIR/named-asm-labels.rs:94:15 + --> $DIR/named-asm-labels.rs:96:15 | LL | asm!("foooo\x3A nop"); | ^^^^^^^^^^^^^ | = help: only local labels of the form `:` should be used in inline asm - = note: see the asm section of the unstable book for more information error: avoid using named labels in inline assembly - --> $DIR/named-asm-labels.rs:97:15 + --> $DIR/named-asm-labels.rs:99:15 | LL | asm!("fooooo:\u{000A} nop"); | ^^^^^^ | = help: only local labels of the form `:` should be used in inline asm - = note: see the asm section of the unstable book for more information error: avoid using named labels in inline assembly - --> $DIR/named-asm-labels.rs:98:15 + --> $DIR/named-asm-labels.rs:100:15 | LL | asm!("foooooo:\x0A nop"); | ^^^^^^^ | = help: only local labels of the form `:` should be used in inline asm - = note: see the asm section of the unstable book for more information error: avoid using named labels in inline assembly - --> $DIR/named-asm-labels.rs:102:14 + --> $DIR/named-asm-labels.rs:104:14 | LL | asm!("\x41\x42\x43\x3A\x20\x6E\x6F\x70"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: only local labels of the form `:` should be used in inline asm - = note: see the asm section of the unstable book for more information error: avoid using named labels in inline assembly - --> $DIR/named-asm-labels.rs:110:13 + --> $DIR/named-asm-labels.rs:112:13 | LL | ab: nop // ab: does foo | ^^ | = help: only local labels of the form `:` should be used in inline asm - = note: see the asm section of the unstable book for more information error: avoid using named labels in inline assembly - --> $DIR/named-asm-labels.rs:122:14 + --> $DIR/named-asm-labels.rs:124:14 | LL | asm!(include_str!("named-asm-labels.s")); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: only local labels of the form `:` should be used in inline asm - = note: see the asm section of the unstable book for more information warning: avoid using named labels in inline assembly - --> $DIR/named-asm-labels.rs:132:19 + --> $DIR/named-asm-labels.rs:134:19 | LL | asm!("warned: nop"); | ^^^^^^ | note: the lint level is defined here - --> $DIR/named-asm-labels.rs:130:16 + --> $DIR/named-asm-labels.rs:132:16 | LL | #[warn(named_asm_labels)] | ^^^^^^^^^^^^^^^^ = help: only local labels of the form `:` should be used in inline asm - = note: see the asm section of the unstable book for more information error: avoid using named labels in inline assembly - --> $DIR/named-asm-labels.rs:141:20 + --> $DIR/named-asm-labels.rs:143:20 | LL | unsafe { asm!(".Lfoo: mov rax, {}; ret;", "nop", const 1, options(noreturn)) } | ^^^^^ | = help: only local labels of the form `:` should be used in inline asm - = note: see the asm section of the unstable book for more information error: avoid using named labels in inline assembly - --> $DIR/named-asm-labels.rs:147:20 + --> $DIR/named-asm-labels.rs:149:20 | LL | unsafe { asm!(".Lbar: mov rax, {}; ret;", "nop", const 1, options(noreturn)) } | ^^^^^ | = help: only local labels of the form `:` should be used in inline asm - = note: see the asm section of the unstable book for more information error: avoid using named labels in inline assembly - --> $DIR/named-asm-labels.rs:155:20 + --> $DIR/named-asm-labels.rs:157:20 | LL | unsafe { asm!(".Laaa: nop; ret;", options(noreturn)) } | ^^^^^ | = help: only local labels of the form `:` should be used in inline asm - = note: see the asm section of the unstable book for more information error: avoid using named labels in inline assembly - --> $DIR/named-asm-labels.rs:165:24 + --> $DIR/named-asm-labels.rs:167:24 | LL | unsafe { asm!(".Lbbb: nop; ret;", options(noreturn)) } | ^^^^^ | = help: only local labels of the form `:` should be used in inline asm - = note: see the asm section of the unstable book for more information error: avoid using named labels in inline assembly - --> $DIR/named-asm-labels.rs:174:15 + --> $DIR/named-asm-labels.rs:176:15 | LL | asm!("closure1: nop"); | ^^^^^^^^ | = help: only local labels of the form `:` should be used in inline asm - = note: see the asm section of the unstable book for more information error: avoid using named labels in inline assembly - --> $DIR/named-asm-labels.rs:178:15 + --> $DIR/named-asm-labels.rs:180:15 | LL | asm!("closure2: nop"); | ^^^^^^^^ | = help: only local labels of the form `:` should be used in inline asm - = note: see the asm section of the unstable book for more information error: avoid using named labels in inline assembly - --> $DIR/named-asm-labels.rs:188:19 + --> $DIR/named-asm-labels.rs:190:19 | LL | asm!("closure3: nop"); | ^^^^^^^^ | = help: only local labels of the form `:` should be used in inline asm - = note: see the asm section of the unstable book for more information error: aborting due to 35 previous errors; 1 warning emitted diff --git a/src/test/ui/asm/noreturn.rs b/src/test/ui/asm/noreturn.rs index cb92ff0ad1d..03fa087ae37 100644 --- a/src/test/ui/asm/noreturn.rs +++ b/src/test/ui/asm/noreturn.rs @@ -1,9 +1,11 @@ // needs-asm-support // check-pass -#![feature(asm, never_type)] +#![feature(never_type)] #![crate_type = "rlib"] +use std::arch::asm; + pub unsafe fn asm1() { let _: () = asm!(""); } diff --git a/src/test/ui/asm/type-check-1.rs b/src/test/ui/asm/type-check-1.rs index 1e463107b18..695fd27efd4 100644 --- a/src/test/ui/asm/type-check-1.rs +++ b/src/test/ui/asm/type-check-1.rs @@ -3,7 +3,9 @@ // ignore-spirv // ignore-wasm32 -#![feature(asm, global_asm, asm_const)] +#![feature(asm_const)] + +use std::arch::{asm, global_asm}; fn main() { unsafe { diff --git a/src/test/ui/asm/type-check-1.stderr b/src/test/ui/asm/type-check-1.stderr index c9080a3c030..d774c78ca9a 100644 --- a/src/test/ui/asm/type-check-1.stderr +++ b/src/test/ui/asm/type-check-1.stderr @@ -1,5 +1,5 @@ error[E0435]: attempt to use a non-constant value in a constant - --> $DIR/type-check-1.rs:37:26 + --> $DIR/type-check-1.rs:39:26 | LL | let x = 0; | ----- help: consider using `const` instead of `let`: `const x` @@ -8,7 +8,7 @@ LL | asm!("{}", const x); | ^ non-constant value error[E0435]: attempt to use a non-constant value in a constant - --> $DIR/type-check-1.rs:40:36 + --> $DIR/type-check-1.rs:42:36 | LL | let x = 0; | ----- help: consider using `const` instead of `let`: `const x` @@ -17,7 +17,7 @@ LL | asm!("{}", const const_foo(x)); | ^ non-constant value error[E0435]: attempt to use a non-constant value in a constant - --> $DIR/type-check-1.rs:43:36 + --> $DIR/type-check-1.rs:45:36 | LL | let x = 0; | ----- help: consider using `const` instead of `let`: `const x` @@ -26,13 +26,13 @@ LL | asm!("{}", const const_bar(x)); | ^ non-constant value error[E0308]: mismatched types - --> $DIR/type-check-1.rs:51:26 + --> $DIR/type-check-1.rs:53:26 | LL | asm!("{}", const 0f32); | ^^^^ expected integer, found `f32` error[E0308]: mismatched types - --> $DIR/type-check-1.rs:53:26 + --> $DIR/type-check-1.rs:55:26 | LL | asm!("{}", const 0 as *mut u8); | ^^^^^^^^^^^^ expected integer, found *-ptr @@ -41,7 +41,7 @@ LL | asm!("{}", const 0 as *mut u8); found raw pointer `*mut u8` error[E0308]: mismatched types - --> $DIR/type-check-1.rs:55:26 + --> $DIR/type-check-1.rs:57:26 | LL | asm!("{}", const &0); | ^^ expected integer, found `&{integer}` @@ -53,19 +53,19 @@ LL + asm!("{}", const 0); | error: invalid asm output - --> $DIR/type-check-1.rs:13:29 + --> $DIR/type-check-1.rs:15:29 | LL | asm!("{}", out(reg) 1 + 2); | ^^^^^ cannot assign to this expression error: invalid asm output - --> $DIR/type-check-1.rs:15:31 + --> $DIR/type-check-1.rs:17:31 | LL | asm!("{}", inout(reg) 1 + 2); | ^^^^^ cannot assign to this expression error[E0277]: the size for values of type `[u64]` cannot be known at compilation time - --> $DIR/type-check-1.rs:21:28 + --> $DIR/type-check-1.rs:23:28 | LL | asm!("{}", in(reg) v[..]); | ^^^^^ doesn't have a size known at compile-time @@ -74,7 +74,7 @@ LL | asm!("{}", in(reg) v[..]); = note: all inline asm arguments must have a statically known size error[E0277]: the size for values of type `[u64]` cannot be known at compilation time - --> $DIR/type-check-1.rs:23:29 + --> $DIR/type-check-1.rs:25:29 | LL | asm!("{}", out(reg) v[..]); | ^^^^^ doesn't have a size known at compile-time @@ -83,7 +83,7 @@ LL | asm!("{}", out(reg) v[..]); = note: all inline asm arguments must have a statically known size error[E0277]: the size for values of type `[u64]` cannot be known at compilation time - --> $DIR/type-check-1.rs:25:31 + --> $DIR/type-check-1.rs:27:31 | LL | asm!("{}", inout(reg) v[..]); | ^^^^^ doesn't have a size known at compile-time @@ -92,13 +92,13 @@ LL | asm!("{}", inout(reg) v[..]); = note: all inline asm arguments must have a statically known size error[E0308]: mismatched types - --> $DIR/type-check-1.rs:65:25 + --> $DIR/type-check-1.rs:67:25 | LL | global_asm!("{}", const 0f32); | ^^^^ expected integer, found `f32` error[E0308]: mismatched types - --> $DIR/type-check-1.rs:67:25 + --> $DIR/type-check-1.rs:69:25 | LL | global_asm!("{}", const 0 as *mut u8); | ^^^^^^^^^^^^ expected integer, found *-ptr diff --git a/src/test/ui/asm/type-check-4.rs b/src/test/ui/asm/type-check-4.rs index c9826662009..666d2c67783 100644 --- a/src/test/ui/asm/type-check-4.rs +++ b/src/test/ui/asm/type-check-4.rs @@ -3,7 +3,7 @@ // ignore-spirv // ignore-wasm32 -#![feature(asm)] +use std::arch::asm; fn main() { unsafe { diff --git a/src/test/ui/asm/x86_64/bad-clobber-abi.rs b/src/test/ui/asm/x86_64/bad-clobber-abi.rs index f4ca033048d..ddcd2065bfe 100644 --- a/src/test/ui/asm/x86_64/bad-clobber-abi.rs +++ b/src/test/ui/asm/x86_64/bad-clobber-abi.rs @@ -1,9 +1,9 @@ // needs-asm-support // only-x86_64 -// checks various modes of failure for the `clobber_abi` argument (after parsing) +use std::arch::asm; -#![feature(asm)] +// checks various modes of failure for the `clobber_abi` argument (after parsing) fn main() { unsafe { diff --git a/src/test/ui/asm/x86_64/bad-options.rs b/src/test/ui/asm/x86_64/bad-options.rs index 3facc876415..f7c2cd6c505 100644 --- a/src/test/ui/asm/x86_64/bad-options.rs +++ b/src/test/ui/asm/x86_64/bad-options.rs @@ -1,6 +1,6 @@ // only-x86_64 -#![feature(asm, global_asm)] +use std::arch::{asm, global_asm}; fn main() { let mut foo = 0; diff --git a/src/test/ui/asm/x86_64/bad-reg.rs b/src/test/ui/asm/x86_64/bad-reg.rs index ba4e95db46a..257274b0bc3 100644 --- a/src/test/ui/asm/x86_64/bad-reg.rs +++ b/src/test/ui/asm/x86_64/bad-reg.rs @@ -1,7 +1,9 @@ // only-x86_64 // compile-flags: -C target-feature=+avx2 -#![feature(asm, asm_const, asm_sym)] +#![feature(asm_const, asm_sym)] + +use std::arch::asm; fn main() { let mut foo = 0; diff --git a/src/test/ui/asm/x86_64/bad-reg.stderr b/src/test/ui/asm/x86_64/bad-reg.stderr index 102a17e9815..3a89b2fdb74 100644 --- a/src/test/ui/asm/x86_64/bad-reg.stderr +++ b/src/test/ui/asm/x86_64/bad-reg.stderr @@ -1,17 +1,17 @@ error: invalid register class `foo`: unknown register class - --> $DIR/bad-reg.rs:12:20 + --> $DIR/bad-reg.rs:14:20 | LL | asm!("{}", in(foo) foo); | ^^^^^^^^^^^ error: invalid register `foo`: unknown register - --> $DIR/bad-reg.rs:14:18 + --> $DIR/bad-reg.rs:16:18 | LL | asm!("", in("foo") foo); | ^^^^^^^^^^^^^ error: invalid asm template modifier for this register class - --> $DIR/bad-reg.rs:16:15 + --> $DIR/bad-reg.rs:18:15 | LL | asm!("{:z}", in(reg) foo); | ^^^^ ----------- argument @@ -21,7 +21,7 @@ LL | asm!("{:z}", in(reg) foo); = note: the `reg` register class supports the following template modifiers: `l`, `x`, `e`, `r` error: invalid asm template modifier for this register class - --> $DIR/bad-reg.rs:18:15 + --> $DIR/bad-reg.rs:20:15 | LL | asm!("{:r}", in(xmm_reg) foo); | ^^^^ --------------- argument @@ -31,7 +31,7 @@ LL | asm!("{:r}", in(xmm_reg) foo); = note: the `xmm_reg` register class supports the following template modifiers: `x`, `y`, `z` error: asm template modifiers are not allowed for `const` arguments - --> $DIR/bad-reg.rs:20:15 + --> $DIR/bad-reg.rs:22:15 | LL | asm!("{:a}", const 0); | ^^^^ ------- argument @@ -39,7 +39,7 @@ LL | asm!("{:a}", const 0); | template modifier error: asm template modifiers are not allowed for `sym` arguments - --> $DIR/bad-reg.rs:22:15 + --> $DIR/bad-reg.rs:24:15 | LL | asm!("{:a}", sym main); | ^^^^ -------- argument @@ -47,73 +47,73 @@ LL | asm!("{:a}", sym main); | template modifier error: invalid register `ebp`: the frame pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:24:18 + --> $DIR/bad-reg.rs:26:18 | LL | asm!("", in("ebp") foo); | ^^^^^^^^^^^^^ error: invalid register `rsp`: the stack pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:26:18 + --> $DIR/bad-reg.rs:28:18 | LL | asm!("", in("rsp") foo); | ^^^^^^^^^^^^^ error: invalid register `ip`: the instruction pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:28:18 + --> $DIR/bad-reg.rs:30:18 | LL | asm!("", in("ip") foo); | ^^^^^^^^^^^^ error: invalid register `k0`: the k0 AVX mask register cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:30:18 + --> $DIR/bad-reg.rs:32:18 | LL | asm!("", in("k0") foo); | ^^^^^^^^^^^^ error: invalid register `ah`: high byte registers cannot be used as an operand on x86_64 - --> $DIR/bad-reg.rs:32:18 + --> $DIR/bad-reg.rs:34:18 | LL | asm!("", in("ah") foo); | ^^^^^^^^^^^^ error: register class `x87_reg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:35:18 + --> $DIR/bad-reg.rs:37:18 | LL | asm!("", in("st(2)") foo); | ^^^^^^^^^^^^^^^ error: register class `mmx_reg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:37:18 + --> $DIR/bad-reg.rs:39:18 | LL | asm!("", in("mm0") foo); | ^^^^^^^^^^^^^ error: register class `x87_reg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:41:20 + --> $DIR/bad-reg.rs:43:20 | LL | asm!("{}", in(x87_reg) foo); | ^^^^^^^^^^^^^^^ error: register class `mmx_reg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:43:20 + --> $DIR/bad-reg.rs:45:20 | LL | asm!("{}", in(mmx_reg) foo); | ^^^^^^^^^^^^^^^ error: register class `x87_reg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:45:20 + --> $DIR/bad-reg.rs:47:20 | LL | asm!("{}", out(x87_reg) _); | ^^^^^^^^^^^^^^ error: register class `mmx_reg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:47:20 + --> $DIR/bad-reg.rs:49:20 | LL | asm!("{}", out(mmx_reg) _); | ^^^^^^^^^^^^^^ error: register `al` conflicts with register `ax` - --> $DIR/bad-reg.rs:53:33 + --> $DIR/bad-reg.rs:55:33 | LL | asm!("", in("eax") foo, in("al") bar); | ------------- ^^^^^^^^^^^^ register `al` @@ -121,7 +121,7 @@ LL | asm!("", in("eax") foo, in("al") bar); | register `ax` error: register `ax` conflicts with register `ax` - --> $DIR/bad-reg.rs:55:33 + --> $DIR/bad-reg.rs:57:33 | LL | asm!("", in("rax") foo, out("rax") bar); | ------------- ^^^^^^^^^^^^^^ register `ax` @@ -129,13 +129,13 @@ LL | asm!("", in("rax") foo, out("rax") bar); | register `ax` | help: use `lateout` instead of `out` to avoid conflict - --> $DIR/bad-reg.rs:55:18 + --> $DIR/bad-reg.rs:57:18 | LL | asm!("", in("rax") foo, out("rax") bar); | ^^^^^^^^^^^^^ error: register `ymm0` conflicts with register `xmm0` - --> $DIR/bad-reg.rs:58:34 + --> $DIR/bad-reg.rs:60:34 | LL | asm!("", in("xmm0") foo, in("ymm0") bar); | -------------- ^^^^^^^^^^^^^^ register `ymm0` @@ -143,7 +143,7 @@ LL | asm!("", in("xmm0") foo, in("ymm0") bar); | register `xmm0` error: register `ymm0` conflicts with register `xmm0` - --> $DIR/bad-reg.rs:60:34 + --> $DIR/bad-reg.rs:62:34 | LL | asm!("", in("xmm0") foo, out("ymm0") bar); | -------------- ^^^^^^^^^^^^^^^ register `ymm0` @@ -151,7 +151,7 @@ LL | asm!("", in("xmm0") foo, out("ymm0") bar); | register `xmm0` | help: use `lateout` instead of `out` to avoid conflict - --> $DIR/bad-reg.rs:60:18 + --> $DIR/bad-reg.rs:62:18 | LL | asm!("", in("xmm0") foo, out("ymm0") bar); | ^^^^^^^^^^^^^^ diff --git a/src/test/ui/asm/x86_64/const.rs b/src/test/ui/asm/x86_64/const.rs index c1e4cdbb928..aa4cdf99176 100644 --- a/src/test/ui/asm/x86_64/const.rs +++ b/src/test/ui/asm/x86_64/const.rs @@ -3,7 +3,9 @@ // revisions: mirunsafeck thirunsafeck // [thirunsafeck]compile-flags: -Z thir-unsafeck -#![feature(asm, global_asm, asm_const)] +#![feature(asm_const)] + +use std::arch::{asm, global_asm}; fn const_generic() -> usize { unsafe { diff --git a/src/test/ui/asm/x86_64/duplicate-options.fixed b/src/test/ui/asm/x86_64/duplicate-options.fixed index d4444e9c6cc..c5f14f5f75c 100644 --- a/src/test/ui/asm/x86_64/duplicate-options.fixed +++ b/src/test/ui/asm/x86_64/duplicate-options.fixed @@ -1,7 +1,7 @@ // only-x86_64 // run-rustfix -#![feature(asm, global_asm)] +use std::arch::{asm, global_asm}; fn main() { unsafe { @@ -19,8 +19,8 @@ fn main() { "", options(nomem, noreturn), options(att_syntax, ), //~ ERROR the `noreturn` option was already provided - options( nostack), //~ ERROR the `nomem` option was already provided - options(), //~ ERROR the `noreturn` option was already provided + options( nostack), //~ ERROR the `nomem` option was already provided + options(), //~ ERROR the `noreturn` option was already provided ); } } diff --git a/src/test/ui/asm/x86_64/duplicate-options.rs b/src/test/ui/asm/x86_64/duplicate-options.rs index fd28311984b..a8dce1f8d71 100644 --- a/src/test/ui/asm/x86_64/duplicate-options.rs +++ b/src/test/ui/asm/x86_64/duplicate-options.rs @@ -1,7 +1,7 @@ // only-x86_64 // run-rustfix -#![feature(asm, global_asm)] +use std::arch::{asm, global_asm}; fn main() { unsafe { @@ -19,8 +19,8 @@ fn main() { "", options(nomem, noreturn), options(att_syntax, noreturn), //~ ERROR the `noreturn` option was already provided - options(nomem, nostack), //~ ERROR the `nomem` option was already provided - options(noreturn), //~ ERROR the `noreturn` option was already provided + options(nomem, nostack), //~ ERROR the `nomem` option was already provided + options(noreturn), //~ ERROR the `noreturn` option was already provided ); } } diff --git a/src/test/ui/asm/x86_64/interpolated-idents.rs b/src/test/ui/asm/x86_64/interpolated-idents.rs index f4cb749307d..c05633ae885 100644 --- a/src/test/ui/asm/x86_64/interpolated-idents.rs +++ b/src/test/ui/asm/x86_64/interpolated-idents.rs @@ -1,6 +1,6 @@ // only-x86_64 -#![feature(asm)] +use std::arch::asm; macro_rules! m { ($in:ident $out:ident $lateout:ident $inout:ident $inlateout:ident $const:ident $sym:ident diff --git a/src/test/ui/asm/x86_64/issue-82869.rs b/src/test/ui/asm/x86_64/issue-82869.rs index a8e688cbe1f..3e632eaf88d 100644 --- a/src/test/ui/asm/x86_64/issue-82869.rs +++ b/src/test/ui/asm/x86_64/issue-82869.rs @@ -1,9 +1,10 @@ // only-x86_64 // Make sure rustc doesn't ICE on asm! for a foreign architecture. -#![feature(asm)] #![crate_type = "rlib"] +use std::arch::asm; + pub unsafe fn aarch64(a: f64, b: f64) -> f64 { let c; asm!("add {:d}, {:d}, d0", out(vreg) c, in(vreg) a, in("d0") { diff --git a/src/test/ui/asm/x86_64/issue-82869.stderr b/src/test/ui/asm/x86_64/issue-82869.stderr index d05714ea6f2..42be1b6de72 100644 --- a/src/test/ui/asm/x86_64/issue-82869.stderr +++ b/src/test/ui/asm/x86_64/issue-82869.stderr @@ -1,17 +1,17 @@ error: invalid register class `vreg`: unknown register class - --> $DIR/issue-82869.rs:9:32 + --> $DIR/issue-82869.rs:10:32 | LL | asm!("add {:d}, {:d}, d0", out(vreg) c, in(vreg) a, in("d0") { | ^^^^^^^^^^^ error: invalid register class `vreg`: unknown register class - --> $DIR/issue-82869.rs:9:45 + --> $DIR/issue-82869.rs:10:45 | LL | asm!("add {:d}, {:d}, d0", out(vreg) c, in(vreg) a, in("d0") { | ^^^^^^^^^^ error: invalid register `d0`: unknown register - --> $DIR/issue-82869.rs:9:57 + --> $DIR/issue-82869.rs:10:57 | LL | asm!("add {:d}, {:d}, d0", out(vreg) c, in(vreg) a, in("d0") { | _________________________________________________________^ diff --git a/src/test/ui/asm/x86_64/issue-89875.rs b/src/test/ui/asm/x86_64/issue-89875.rs index 9b2b21bbda6..e4b6687e00b 100644 --- a/src/test/ui/asm/x86_64/issue-89875.rs +++ b/src/test/ui/asm/x86_64/issue-89875.rs @@ -1,7 +1,9 @@ // build-pass // only-x86_64 -#![feature(asm, target_feature_11)] +#![feature(target_feature_11)] + +use std::arch::asm; #[target_feature(enable = "avx")] fn main() { diff --git a/src/test/ui/asm/x86_64/may_unwind.rs b/src/test/ui/asm/x86_64/may_unwind.rs index 5ac4dd9b956..9844d63f0cd 100644 --- a/src/test/ui/asm/x86_64/may_unwind.rs +++ b/src/test/ui/asm/x86_64/may_unwind.rs @@ -3,8 +3,9 @@ // run-pass // needs-asm-support -#![feature(asm, asm_sym, asm_unwind)] +#![feature(asm_sym, asm_unwind)] +use std::arch::asm; use std::panic::{catch_unwind, resume_unwind, AssertUnwindSafe}; struct Foo<'a>(&'a mut bool); diff --git a/src/test/ui/asm/x86_64/multiple-clobber-abi.rs b/src/test/ui/asm/x86_64/multiple-clobber-abi.rs index a573d672d00..513eb270e4f 100644 --- a/src/test/ui/asm/x86_64/multiple-clobber-abi.rs +++ b/src/test/ui/asm/x86_64/multiple-clobber-abi.rs @@ -4,7 +4,9 @@ // Checks that multiple clobber_abi options can be used -#![feature(asm, asm_sym)] +#![feature(asm_sym)] + +use std::arch::asm; extern "sysv64" fn foo(x: i32) -> i32 { x + 16 diff --git a/src/test/ui/asm/x86_64/parse-error.rs b/src/test/ui/asm/x86_64/parse-error.rs index 1d6545f1b5c..f0629f9f51c 100644 --- a/src/test/ui/asm/x86_64/parse-error.rs +++ b/src/test/ui/asm/x86_64/parse-error.rs @@ -1,6 +1,8 @@ // only-x86_64 -#![feature(asm, global_asm, asm_const)] +#![feature(asm_const)] + +use std::arch::{asm, global_asm}; fn main() { let mut foo = 0; diff --git a/src/test/ui/asm/x86_64/parse-error.stderr b/src/test/ui/asm/x86_64/parse-error.stderr index 4f16c15af38..2d0a7a94d56 100644 --- a/src/test/ui/asm/x86_64/parse-error.stderr +++ b/src/test/ui/asm/x86_64/parse-error.stderr @@ -1,89 +1,89 @@ error: requires at least a template string argument - --> $DIR/parse-error.rs:9:9 + --> $DIR/parse-error.rs:11:9 | LL | asm!(); | ^^^^^^ error: asm template must be a string literal - --> $DIR/parse-error.rs:11:14 + --> $DIR/parse-error.rs:13:14 | LL | asm!(foo); | ^^^ error: expected token: `,` - --> $DIR/parse-error.rs:13:19 + --> $DIR/parse-error.rs:15:19 | LL | asm!("{}" foo); | ^^^ expected `,` error: expected operand, clobber_abi, options, or additional template string - --> $DIR/parse-error.rs:15:20 + --> $DIR/parse-error.rs:17:20 | LL | asm!("{}", foo); | ^^^ expected operand, clobber_abi, options, or additional template string error: expected `(`, found `foo` - --> $DIR/parse-error.rs:17:23 + --> $DIR/parse-error.rs:19:23 | LL | asm!("{}", in foo); | ^^^ expected `(` error: expected `)`, found `foo` - --> $DIR/parse-error.rs:19:27 + --> $DIR/parse-error.rs:21:27 | LL | asm!("{}", in(reg foo)); | ^^^ expected `)` error: expected expression, found end of macro arguments - --> $DIR/parse-error.rs:21:27 + --> $DIR/parse-error.rs:23:27 | LL | asm!("{}", in(reg)); | ^ expected expression error: expected register class or explicit register - --> $DIR/parse-error.rs:23:26 + --> $DIR/parse-error.rs:25:26 | LL | asm!("{}", inout(=) foo => bar); | ^ error: expected expression, found end of macro arguments - --> $DIR/parse-error.rs:25:37 + --> $DIR/parse-error.rs:27:37 | LL | asm!("{}", inout(reg) foo =>); | ^ expected expression error: expected one of `!`, `,`, `.`, `::`, `?`, `{`, or an operator, found `=>` - --> $DIR/parse-error.rs:27:32 + --> $DIR/parse-error.rs:29:32 | LL | asm!("{}", in(reg) foo => bar); | ^^ expected one of 7 possible tokens error: argument to `sym` must be a path expression - --> $DIR/parse-error.rs:29:24 + --> $DIR/parse-error.rs:31:24 | LL | asm!("{}", sym foo + bar); | ^^^^^^^^^ error: expected one of `)`, `att_syntax`, `may_unwind`, `nomem`, `noreturn`, `nostack`, `preserves_flags`, `pure`, `raw`, or `readonly`, found `foo` - --> $DIR/parse-error.rs:31:26 + --> $DIR/parse-error.rs:33:26 | LL | asm!("", options(foo)); | ^^^ expected one of 10 possible tokens error: expected one of `)` or `,`, found `foo` - --> $DIR/parse-error.rs:33:32 + --> $DIR/parse-error.rs:35:32 | LL | asm!("", options(nomem foo)); | ^^^ expected one of `)` or `,` error: expected one of `)`, `att_syntax`, `may_unwind`, `nomem`, `noreturn`, `nostack`, `preserves_flags`, `pure`, `raw`, or `readonly`, found `foo` - --> $DIR/parse-error.rs:35:33 + --> $DIR/parse-error.rs:37:33 | LL | asm!("", options(nomem, foo)); | ^^^ expected one of 10 possible tokens error: arguments are not allowed after options - --> $DIR/parse-error.rs:37:31 + --> $DIR/parse-error.rs:39:31 | LL | asm!("{}", options(), const foo); | --------- ^^^^^^^^^ argument @@ -91,31 +91,31 @@ LL | asm!("{}", options(), const foo); | previous options error: at least one abi must be provided as an argument to `clobber_abi` - --> $DIR/parse-error.rs:40:30 + --> $DIR/parse-error.rs:42:30 | LL | asm!("", clobber_abi()); | ^ error: expected string literal - --> $DIR/parse-error.rs:42:30 + --> $DIR/parse-error.rs:44:30 | LL | asm!("", clobber_abi(foo)); | ^^^ not a string literal error: expected one of `)` or `,`, found `foo` - --> $DIR/parse-error.rs:44:34 + --> $DIR/parse-error.rs:46:34 | LL | asm!("", clobber_abi("C" foo)); | ^^^ expected one of `)` or `,` error: expected string literal - --> $DIR/parse-error.rs:46:35 + --> $DIR/parse-error.rs:48:35 | LL | asm!("", clobber_abi("C", foo)); | ^^^ not a string literal error: arguments are not allowed after clobber_abi - --> $DIR/parse-error.rs:48:38 + --> $DIR/parse-error.rs:50:38 | LL | asm!("{}", clobber_abi("C"), const foo); | ---------------- ^^^^^^^^^ argument @@ -123,7 +123,7 @@ LL | asm!("{}", clobber_abi("C"), const foo); | clobber_abi error: clobber_abi is not allowed after options - --> $DIR/parse-error.rs:51:29 + --> $DIR/parse-error.rs:53:29 | LL | asm!("", options(), clobber_abi("C")); | --------- ^^^^^^^^^^^^^^^^ @@ -131,7 +131,7 @@ LL | asm!("", options(), clobber_abi("C")); | options error: clobber_abi is not allowed after options - --> $DIR/parse-error.rs:53:31 + --> $DIR/parse-error.rs:55:31 | LL | asm!("{}", options(), clobber_abi("C"), const foo); | --------- ^^^^^^^^^^^^^^^^ @@ -139,7 +139,7 @@ LL | asm!("{}", options(), clobber_abi("C"), const foo); | options error: duplicate argument named `a` - --> $DIR/parse-error.rs:55:36 + --> $DIR/parse-error.rs:57:36 | LL | asm!("{a}", a = const foo, a = const bar); | ------------- ^^^^^^^^^^^^^ duplicate argument @@ -147,7 +147,7 @@ LL | asm!("{a}", a = const foo, a = const bar); | previously here error: argument never used - --> $DIR/parse-error.rs:55:36 + --> $DIR/parse-error.rs:57:36 | LL | asm!("{a}", a = const foo, a = const bar); | ^^^^^^^^^^^^^ argument never used @@ -155,13 +155,13 @@ LL | asm!("{a}", a = const foo, a = const bar); = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {1} */"` error: explicit register arguments cannot have names - --> $DIR/parse-error.rs:60:18 + --> $DIR/parse-error.rs:62:18 | LL | asm!("", a = in("eax") foo); | ^^^^^^^^^^^^^^^^^ error: named arguments cannot follow explicit register arguments - --> $DIR/parse-error.rs:62:36 + --> $DIR/parse-error.rs:64:36 | LL | asm!("{a}", in("eax") foo, a = const bar); | ------------- ^^^^^^^^^^^^^ named argument @@ -169,7 +169,7 @@ LL | asm!("{a}", in("eax") foo, a = const bar); | explicit register argument error: named arguments cannot follow explicit register arguments - --> $DIR/parse-error.rs:65:36 + --> $DIR/parse-error.rs:67:36 | LL | asm!("{a}", in("eax") foo, a = const bar); | ------------- ^^^^^^^^^^^^^ named argument @@ -177,7 +177,7 @@ LL | asm!("{a}", in("eax") foo, a = const bar); | explicit register argument error: positional arguments cannot follow named arguments or explicit register arguments - --> $DIR/parse-error.rs:68:36 + --> $DIR/parse-error.rs:70:36 | LL | asm!("{1}", in("eax") foo, const bar); | ------------- ^^^^^^^^^ positional argument @@ -185,19 +185,19 @@ LL | asm!("{1}", in("eax") foo, const bar); | explicit register argument error: expected one of `clobber_abi`, `const`, `in`, `inlateout`, `inout`, `lateout`, `options`, `out`, or `sym`, found `""` - --> $DIR/parse-error.rs:71:29 + --> $DIR/parse-error.rs:73:29 | LL | asm!("", options(), ""); | ^^ expected one of 9 possible tokens error: expected one of `clobber_abi`, `const`, `in`, `inlateout`, `inout`, `lateout`, `options`, `out`, or `sym`, found `"{}"` - --> $DIR/parse-error.rs:73:33 + --> $DIR/parse-error.rs:75:33 | LL | asm!("{}", in(reg) foo, "{}", out(reg) foo); | ^^^^ expected one of 9 possible tokens error: asm template must be a string literal - --> $DIR/parse-error.rs:75:14 + --> $DIR/parse-error.rs:77:14 | LL | asm!(format!("{{{}}}", 0), in(reg) foo); | ^^^^^^^^^^^^^^^^^^^^ @@ -205,7 +205,7 @@ LL | asm!(format!("{{{}}}", 0), in(reg) foo); = note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info) error: asm template must be a string literal - --> $DIR/parse-error.rs:77:21 + --> $DIR/parse-error.rs:79:21 | LL | asm!("{1}", format!("{{{}}}", 0), in(reg) foo, out(reg) bar); | ^^^^^^^^^^^^^^^^^^^^ @@ -213,79 +213,79 @@ LL | asm!("{1}", format!("{{{}}}", 0), in(reg) foo, out(reg) bar); = note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info) error: _ cannot be used for input operands - --> $DIR/parse-error.rs:79:28 + --> $DIR/parse-error.rs:81:28 | LL | asm!("{}", in(reg) _); | ^ error: _ cannot be used for input operands - --> $DIR/parse-error.rs:81:31 + --> $DIR/parse-error.rs:83:31 | LL | asm!("{}", inout(reg) _); | ^ error: _ cannot be used for input operands - --> $DIR/parse-error.rs:83:35 + --> $DIR/parse-error.rs:85:35 | LL | asm!("{}", inlateout(reg) _); | ^ error: requires at least a template string argument - --> $DIR/parse-error.rs:90:1 + --> $DIR/parse-error.rs:92:1 | LL | global_asm!(); | ^^^^^^^^^^^^^ error: asm template must be a string literal - --> $DIR/parse-error.rs:92:13 + --> $DIR/parse-error.rs:94:13 | LL | global_asm!(FOO); | ^^^ error: expected token: `,` - --> $DIR/parse-error.rs:94:18 + --> $DIR/parse-error.rs:96:18 | LL | global_asm!("{}" FOO); | ^^^ expected `,` error: expected operand, options, or additional template string - --> $DIR/parse-error.rs:96:19 + --> $DIR/parse-error.rs:98:19 | LL | global_asm!("{}", FOO); | ^^^ expected operand, options, or additional template string error: expected expression, found end of macro arguments - --> $DIR/parse-error.rs:98:24 + --> $DIR/parse-error.rs:100:24 | LL | global_asm!("{}", const); | ^ expected expression error: expected one of `,`, `.`, `?`, or an operator, found `FOO` - --> $DIR/parse-error.rs:100:30 + --> $DIR/parse-error.rs:102:30 | LL | global_asm!("{}", const(reg) FOO); | ^^^ expected one of `,`, `.`, `?`, or an operator error: expected one of `)`, `att_syntax`, `may_unwind`, or `raw`, found `FOO` - --> $DIR/parse-error.rs:102:25 + --> $DIR/parse-error.rs:104:25 | LL | global_asm!("", options(FOO)); | ^^^ expected one of `)`, `att_syntax`, `may_unwind`, or `raw` error: expected one of `)`, `att_syntax`, `may_unwind`, or `raw`, found `nomem` - --> $DIR/parse-error.rs:104:25 + --> $DIR/parse-error.rs:106:25 | LL | global_asm!("", options(nomem FOO)); | ^^^^^ expected one of `)`, `att_syntax`, `may_unwind`, or `raw` error: expected one of `)`, `att_syntax`, `may_unwind`, or `raw`, found `nomem` - --> $DIR/parse-error.rs:106:25 + --> $DIR/parse-error.rs:108:25 | LL | global_asm!("", options(nomem, FOO)); | ^^^^^ expected one of `)`, `att_syntax`, `may_unwind`, or `raw` error: arguments are not allowed after options - --> $DIR/parse-error.rs:108:30 + --> $DIR/parse-error.rs:110:30 | LL | global_asm!("{}", options(), const FOO); | --------- ^^^^^^^^^ argument @@ -293,25 +293,25 @@ LL | global_asm!("{}", options(), const FOO); | previous options error: expected string literal - --> $DIR/parse-error.rs:110:29 + --> $DIR/parse-error.rs:112:29 | LL | global_asm!("", clobber_abi(FOO)); | ^^^ not a string literal error: expected one of `)` or `,`, found `FOO` - --> $DIR/parse-error.rs:112:33 + --> $DIR/parse-error.rs:114:33 | LL | global_asm!("", clobber_abi("C" FOO)); | ^^^ expected one of `)` or `,` error: expected string literal - --> $DIR/parse-error.rs:114:34 + --> $DIR/parse-error.rs:116:34 | LL | global_asm!("", clobber_abi("C", FOO)); | ^^^ not a string literal error: arguments are not allowed after clobber_abi - --> $DIR/parse-error.rs:116:37 + --> $DIR/parse-error.rs:118:37 | LL | global_asm!("{}", clobber_abi("C"), const FOO); | ---------------- ^^^^^^^^^ argument @@ -319,13 +319,13 @@ LL | global_asm!("{}", clobber_abi("C"), const FOO); | clobber_abi error: `clobber_abi` cannot be used with `global_asm!` - --> $DIR/parse-error.rs:116:19 + --> $DIR/parse-error.rs:118:19 | LL | global_asm!("{}", clobber_abi("C"), const FOO); | ^^^^^^^^^^^^^^^^ error: clobber_abi is not allowed after options - --> $DIR/parse-error.rs:119:28 + --> $DIR/parse-error.rs:121:28 | LL | global_asm!("", options(), clobber_abi("C")); | --------- ^^^^^^^^^^^^^^^^ @@ -333,7 +333,7 @@ LL | global_asm!("", options(), clobber_abi("C")); | options error: clobber_abi is not allowed after options - --> $DIR/parse-error.rs:121:30 + --> $DIR/parse-error.rs:123:30 | LL | global_asm!("{}", options(), clobber_abi("C"), const FOO); | --------- ^^^^^^^^^^^^^^^^ @@ -341,13 +341,13 @@ LL | global_asm!("{}", options(), clobber_abi("C"), const FOO); | options error: `clobber_abi` cannot be used with `global_asm!` - --> $DIR/parse-error.rs:123:17 + --> $DIR/parse-error.rs:125:17 | LL | global_asm!("", clobber_abi("C"), clobber_abi("C")); | ^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^ error: duplicate argument named `a` - --> $DIR/parse-error.rs:125:35 + --> $DIR/parse-error.rs:127:35 | LL | global_asm!("{a}", a = const FOO, a = const BAR); | ------------- ^^^^^^^^^^^^^ duplicate argument @@ -355,7 +355,7 @@ LL | global_asm!("{a}", a = const FOO, a = const BAR); | previously here error: argument never used - --> $DIR/parse-error.rs:125:35 + --> $DIR/parse-error.rs:127:35 | LL | global_asm!("{a}", a = const FOO, a = const BAR); | ^^^^^^^^^^^^^ argument never used @@ -363,19 +363,19 @@ LL | global_asm!("{a}", a = const FOO, a = const BAR); = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {1} */"` error: expected one of `clobber_abi`, `const`, or `options`, found `""` - --> $DIR/parse-error.rs:128:28 + --> $DIR/parse-error.rs:130:28 | LL | global_asm!("", options(), ""); | ^^ expected one of `clobber_abi`, `const`, or `options` error: expected one of `clobber_abi`, `const`, or `options`, found `"{}"` - --> $DIR/parse-error.rs:130:30 + --> $DIR/parse-error.rs:132:30 | LL | global_asm!("{}", const FOO, "{}", const FOO); | ^^^^ expected one of `clobber_abi`, `const`, or `options` error: asm template must be a string literal - --> $DIR/parse-error.rs:132:13 + --> $DIR/parse-error.rs:134:13 | LL | global_asm!(format!("{{{}}}", 0), const FOO); | ^^^^^^^^^^^^^^^^^^^^ @@ -383,7 +383,7 @@ LL | global_asm!(format!("{{{}}}", 0), const FOO); = note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info) error: asm template must be a string literal - --> $DIR/parse-error.rs:134:20 + --> $DIR/parse-error.rs:136:20 | LL | global_asm!("{1}", format!("{{{}}}", 0), const FOO, const BAR); | ^^^^^^^^^^^^^^^^^^^^ @@ -391,7 +391,7 @@ LL | global_asm!("{1}", format!("{{{}}}", 0), const FOO, const BAR); = note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0435]: attempt to use a non-constant value in a constant - --> $DIR/parse-error.rs:37:37 + --> $DIR/parse-error.rs:39:37 | LL | let mut foo = 0; | ---------- help: consider using `const` instead of `let`: `const foo` @@ -400,7 +400,7 @@ LL | asm!("{}", options(), const foo); | ^^^ non-constant value error[E0435]: attempt to use a non-constant value in a constant - --> $DIR/parse-error.rs:48:44 + --> $DIR/parse-error.rs:50:44 | LL | let mut foo = 0; | ---------- help: consider using `const` instead of `let`: `const foo` @@ -409,7 +409,7 @@ LL | asm!("{}", clobber_abi("C"), const foo); | ^^^ non-constant value error[E0435]: attempt to use a non-constant value in a constant - --> $DIR/parse-error.rs:55:31 + --> $DIR/parse-error.rs:57:31 | LL | let mut foo = 0; | ---------- help: consider using `const` instead of `let`: `const foo` @@ -418,7 +418,7 @@ LL | asm!("{a}", a = const foo, a = const bar); | ^^^ non-constant value error[E0435]: attempt to use a non-constant value in a constant - --> $DIR/parse-error.rs:55:46 + --> $DIR/parse-error.rs:57:46 | LL | let mut bar = 0; | ---------- help: consider using `const` instead of `let`: `const bar` @@ -427,7 +427,7 @@ LL | asm!("{a}", a = const foo, a = const bar); | ^^^ non-constant value error[E0435]: attempt to use a non-constant value in a constant - --> $DIR/parse-error.rs:62:46 + --> $DIR/parse-error.rs:64:46 | LL | let mut bar = 0; | ---------- help: consider using `const` instead of `let`: `const bar` @@ -436,7 +436,7 @@ LL | asm!("{a}", in("eax") foo, a = const bar); | ^^^ non-constant value error[E0435]: attempt to use a non-constant value in a constant - --> $DIR/parse-error.rs:65:46 + --> $DIR/parse-error.rs:67:46 | LL | let mut bar = 0; | ---------- help: consider using `const` instead of `let`: `const bar` @@ -445,7 +445,7 @@ LL | asm!("{a}", in("eax") foo, a = const bar); | ^^^ non-constant value error[E0435]: attempt to use a non-constant value in a constant - --> $DIR/parse-error.rs:68:42 + --> $DIR/parse-error.rs:70:42 | LL | let mut bar = 0; | ---------- help: consider using `const` instead of `let`: `const bar` diff --git a/src/test/ui/asm/x86_64/srcloc.rs b/src/test/ui/asm/x86_64/srcloc.rs index c4ccfb8016a..8a21d759772 100644 --- a/src/test/ui/asm/x86_64/srcloc.rs +++ b/src/test/ui/asm/x86_64/srcloc.rs @@ -1,7 +1,8 @@ // only-x86_64 // build-fail // compile-flags: -Ccodegen-units=1 -#![feature(asm)] + +use std::arch::asm; // Checks that inline asm errors are mapped to the correct line in the source code. diff --git a/src/test/ui/asm/x86_64/srcloc.stderr b/src/test/ui/asm/x86_64/srcloc.stderr index 77894657292..b62c8948289 100644 --- a/src/test/ui/asm/x86_64/srcloc.stderr +++ b/src/test/ui/asm/x86_64/srcloc.stderr @@ -1,5 +1,5 @@ error: invalid instruction mnemonic 'invalid_instruction' - --> $DIR/srcloc.rs:10:15 + --> $DIR/srcloc.rs:11:15 | LL | asm!("invalid_instruction"); | ^ @@ -11,7 +11,7 @@ LL | invalid_instruction | ^^^^^^^^^^^^^^^^^^^ error: invalid instruction mnemonic 'invalid_instruction' - --> $DIR/srcloc.rs:14:13 + --> $DIR/srcloc.rs:15:13 | LL | invalid_instruction | ^ @@ -23,7 +23,7 @@ LL | invalid_instruction | ^^^^^^^^^^^^^^^^^^^ error: invalid instruction mnemonic 'invalid_instruction' - --> $DIR/srcloc.rs:19:13 + --> $DIR/srcloc.rs:20:13 | LL | invalid_instruction | ^ @@ -35,7 +35,7 @@ LL | invalid_instruction | ^^^^^^^^^^^^^^^^^^^ error: invalid instruction mnemonic 'invalid_instruction' - --> $DIR/srcloc.rs:25:13 + --> $DIR/srcloc.rs:26:13 | LL | invalid_instruction | ^ @@ -47,7 +47,7 @@ LL | invalid_instruction | ^^^^^^^^^^^^^^^^^^^ error: invalid instruction mnemonic 'invalid_instruction' - --> $DIR/srcloc.rs:32:13 + --> $DIR/srcloc.rs:33:13 | LL | invalid_instruction | ^ @@ -59,7 +59,7 @@ LL | invalid_instruction | ^^^^^^^^^^^^^^^^^^^ error: invalid instruction mnemonic 'invalid_instruction' - --> $DIR/srcloc.rs:37:14 + --> $DIR/srcloc.rs:38:14 | LL | asm!(concat!("invalid", "_", "instruction")); | ^ @@ -71,7 +71,7 @@ LL | invalid_instruction | ^^^^^^^^^^^^^^^^^^^ warning: scale factor without index register is ignored - --> $DIR/srcloc.rs:40:15 + --> $DIR/srcloc.rs:41:15 | LL | asm!("movaps %xmm3, (%esi, 2)", options(att_syntax)); | ^ @@ -83,7 +83,7 @@ LL | movaps %xmm3, (%esi, 2) | ^ error: invalid instruction mnemonic 'invalid_instruction' - --> $DIR/srcloc.rs:44:14 + --> $DIR/srcloc.rs:45:14 | LL | "invalid_instruction", | ^ @@ -95,7 +95,7 @@ LL | invalid_instruction | ^^^^^^^^^^^^^^^^^^^ error: invalid instruction mnemonic 'invalid_instruction' - --> $DIR/srcloc.rs:50:14 + --> $DIR/srcloc.rs:51:14 | LL | "invalid_instruction", | ^ @@ -107,7 +107,7 @@ LL | invalid_instruction | ^^^^^^^^^^^^^^^^^^^ error: invalid instruction mnemonic 'invalid_instruction' - --> $DIR/srcloc.rs:57:14 + --> $DIR/srcloc.rs:58:14 | LL | "invalid_instruction", | ^ @@ -119,7 +119,7 @@ LL | invalid_instruction | ^^^^^^^^^^^^^^^^^^^ error: invalid instruction mnemonic 'invalid_instruction' - --> $DIR/srcloc.rs:64:13 + --> $DIR/srcloc.rs:65:13 | LL | concat!("invalid", "_", "instruction"), | ^ @@ -131,7 +131,7 @@ LL | invalid_instruction | ^^^^^^^^^^^^^^^^^^^ error: invalid instruction mnemonic 'invalid_instruction' - --> $DIR/srcloc.rs:71:13 + --> $DIR/srcloc.rs:72:13 | LL | concat!("invalid", "_", "instruction"), | ^ @@ -143,7 +143,7 @@ LL | invalid_instruction | ^^^^^^^^^^^^^^^^^^^ error: invalid instruction mnemonic 'invalid_instruction1' - --> $DIR/srcloc.rs:78:14 + --> $DIR/srcloc.rs:79:14 | LL | "invalid_instruction1", | ^ @@ -155,7 +155,7 @@ LL | invalid_instruction1 | ^^^^^^^^^^^^^^^^^^^^ error: invalid instruction mnemonic 'invalid_instruction2' - --> $DIR/srcloc.rs:79:14 + --> $DIR/srcloc.rs:80:14 | LL | "invalid_instruction2", | ^ @@ -167,7 +167,7 @@ LL | invalid_instruction2 | ^^^^^^^^^^^^^^^^^^^^ error: invalid instruction mnemonic 'invalid_instruction1' - --> $DIR/srcloc.rs:85:13 + --> $DIR/srcloc.rs:86:13 | LL | concat!( | ^ @@ -179,7 +179,7 @@ LL | invalid_instruction1 | ^^^^^^^^^^^^^^^^^^^^ error: invalid instruction mnemonic 'invalid_instruction2' - --> $DIR/srcloc.rs:85:13 + --> $DIR/srcloc.rs:86:13 | LL | concat!( | ^ @@ -191,7 +191,7 @@ LL | invalid_instruction2 | ^^^^^^^^^^^^^^^^^^^^ error: invalid instruction mnemonic 'invalid_instruction1' - --> $DIR/srcloc.rs:94:13 + --> $DIR/srcloc.rs:95:13 | LL | concat!( | ^ @@ -203,7 +203,7 @@ LL | invalid_instruction1 | ^^^^^^^^^^^^^^^^^^^^ error: invalid instruction mnemonic 'invalid_instruction2' - --> $DIR/srcloc.rs:94:13 + --> $DIR/srcloc.rs:95:13 | LL | concat!( | ^ @@ -215,7 +215,7 @@ LL | invalid_instruction2 | ^^^^^^^^^^^^^^^^^^^^ error: invalid instruction mnemonic 'invalid_instruction3' - --> $DIR/srcloc.rs:98:13 + --> $DIR/srcloc.rs:99:13 | LL | concat!( | ^ @@ -227,7 +227,7 @@ LL | invalid_instruction3 | ^^^^^^^^^^^^^^^^^^^^ error: invalid instruction mnemonic 'invalid_instruction4' - --> $DIR/srcloc.rs:98:13 + --> $DIR/srcloc.rs:99:13 | LL | concat!( | ^ @@ -239,7 +239,7 @@ LL | invalid_instruction4 | ^^^^^^^^^^^^^^^^^^^^ error: invalid instruction mnemonic 'invalid_instruction1' - --> $DIR/srcloc.rs:109:13 + --> $DIR/srcloc.rs:110:13 | LL | concat!( | ^ @@ -251,7 +251,7 @@ LL | invalid_instruction1 | ^^^^^^^^^^^^^^^^^^^^ error: invalid instruction mnemonic 'invalid_instruction2' - --> $DIR/srcloc.rs:109:13 + --> $DIR/srcloc.rs:110:13 | LL | concat!( | ^ @@ -263,7 +263,7 @@ LL | invalid_instruction2 | ^^^^^^^^^^^^^^^^^^^^ error: invalid instruction mnemonic 'invalid_instruction3' - --> $DIR/srcloc.rs:113:13 + --> $DIR/srcloc.rs:114:13 | LL | concat!( | ^ @@ -275,7 +275,7 @@ LL | invalid_instruction3 | ^^^^^^^^^^^^^^^^^^^^ error: invalid instruction mnemonic 'invalid_instruction4' - --> $DIR/srcloc.rs:113:13 + --> $DIR/srcloc.rs:114:13 | LL | concat!( | ^ diff --git a/src/test/ui/asm/x86_64/sym.rs b/src/test/ui/asm/x86_64/sym.rs index 958dbbdd376..fcb6c5fbfaf 100644 --- a/src/test/ui/asm/x86_64/sym.rs +++ b/src/test/ui/asm/x86_64/sym.rs @@ -3,7 +3,9 @@ // only-linux // run-pass -#![feature(asm, thread_local, asm_sym)] +#![feature(thread_local, asm_sym)] + +use std::arch::asm; extern "C" fn f1() -> i32 { 111 diff --git a/src/test/ui/asm/x86_64/target-feature-attr.rs b/src/test/ui/asm/x86_64/target-feature-attr.rs index 4f82cd8aab9..14490c3e0f2 100644 --- a/src/test/ui/asm/x86_64/target-feature-attr.rs +++ b/src/test/ui/asm/x86_64/target-feature-attr.rs @@ -1,6 +1,8 @@ // only-x86_64 -#![feature(asm, avx512_target_feature)] +#![feature(avx512_target_feature)] + +use std::arch::asm; #[target_feature(enable = "avx")] unsafe fn foo() { diff --git a/src/test/ui/asm/x86_64/target-feature-attr.stderr b/src/test/ui/asm/x86_64/target-feature-attr.stderr index 295c8a97ed3..c852726ee7f 100644 --- a/src/test/ui/asm/x86_64/target-feature-attr.stderr +++ b/src/test/ui/asm/x86_64/target-feature-attr.stderr @@ -1,23 +1,23 @@ error: register class `ymm_reg` requires the `avx` target feature - --> $DIR/target-feature-attr.rs:16:40 + --> $DIR/target-feature-attr.rs:18:40 | LL | asm!("vaddps {2:y}, {0:y}, {1:y}", in(ymm_reg) x, in(ymm_reg) y, lateout(ymm_reg) x); | ^^^^^^^^^^^^^ error: register class `ymm_reg` requires the `avx` target feature - --> $DIR/target-feature-attr.rs:16:55 + --> $DIR/target-feature-attr.rs:18:55 | LL | asm!("vaddps {2:y}, {0:y}, {1:y}", in(ymm_reg) x, in(ymm_reg) y, lateout(ymm_reg) x); | ^^^^^^^^^^^^^ error: register class `ymm_reg` requires the `avx` target feature - --> $DIR/target-feature-attr.rs:16:70 + --> $DIR/target-feature-attr.rs:18:70 | LL | asm!("vaddps {2:y}, {0:y}, {1:y}", in(ymm_reg) x, in(ymm_reg) y, lateout(ymm_reg) x); | ^^^^^^^^^^^^^^^^^^ error: register class `kreg` requires at least one of the following target features: avx512bw, avx512f - --> $DIR/target-feature-attr.rs:31:23 + --> $DIR/target-feature-attr.rs:33:23 | LL | asm!("/* {0} */", in(kreg) x); | ^^^^^^^^^^ diff --git a/src/test/ui/asm/x86_64/type-check-2.rs b/src/test/ui/asm/x86_64/type-check-2.rs index 94aadcf09f4..f95aebb78b5 100644 --- a/src/test/ui/asm/x86_64/type-check-2.rs +++ b/src/test/ui/asm/x86_64/type-check-2.rs @@ -1,6 +1,8 @@ // only-x86_64 -#![feature(asm, repr_simd, never_type, asm_sym)] +#![feature(repr_simd, never_type, asm_sym)] + +use std::arch::asm; #[repr(simd)] struct SimdNonCopy(f32, f32, f32, f32); diff --git a/src/test/ui/asm/x86_64/type-check-2.stderr b/src/test/ui/asm/x86_64/type-check-2.stderr index 9e73c9a8d6a..cec750fdf9a 100644 --- a/src/test/ui/asm/x86_64/type-check-2.stderr +++ b/src/test/ui/asm/x86_64/type-check-2.stderr @@ -1,13 +1,13 @@ error: arguments for inline assembly must be copyable - --> $DIR/type-check-2.rs:42:32 + --> $DIR/type-check-2.rs:44:32 | LL | asm!("{}", in(xmm_reg) SimdNonCopy(0.0, 0.0, 0.0, 0.0)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `SimdNonCopy` does not implement the Copy trait -error: cannot use value of type `[closure@$DIR/type-check-2.rs:54:28: 54:38]` for inline assembly - --> $DIR/type-check-2.rs:54:28 +error: cannot use value of type `[closure@$DIR/type-check-2.rs:56:28: 56:38]` for inline assembly + --> $DIR/type-check-2.rs:56:28 | LL | asm!("{}", in(reg) |x: i32| x); | ^^^^^^^^^^ @@ -15,7 +15,7 @@ LL | asm!("{}", in(reg) |x: i32| x); = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly error: cannot use value of type `Vec` for inline assembly - --> $DIR/type-check-2.rs:56:28 + --> $DIR/type-check-2.rs:58:28 | LL | asm!("{}", in(reg) vec![0]); | ^^^^^^^ @@ -24,7 +24,7 @@ LL | asm!("{}", in(reg) vec![0]); = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) error: cannot use value of type `(i32, i32, i32)` for inline assembly - --> $DIR/type-check-2.rs:58:28 + --> $DIR/type-check-2.rs:60:28 | LL | asm!("{}", in(reg) (1, 2, 3)); | ^^^^^^^^^ @@ -32,7 +32,7 @@ LL | asm!("{}", in(reg) (1, 2, 3)); = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly error: cannot use value of type `[i32; 3]` for inline assembly - --> $DIR/type-check-2.rs:60:28 + --> $DIR/type-check-2.rs:62:28 | LL | asm!("{}", in(reg) [1, 2, 3]); | ^^^^^^^^^ @@ -40,7 +40,7 @@ LL | asm!("{}", in(reg) [1, 2, 3]); = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly error: cannot use value of type `fn() {main}` for inline assembly - --> $DIR/type-check-2.rs:68:31 + --> $DIR/type-check-2.rs:70:31 | LL | asm!("{}", inout(reg) f); | ^ @@ -48,7 +48,7 @@ LL | asm!("{}", inout(reg) f); = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly error: cannot use value of type `&mut i32` for inline assembly - --> $DIR/type-check-2.rs:71:31 + --> $DIR/type-check-2.rs:73:31 | LL | asm!("{}", inout(reg) r); | ^ @@ -56,31 +56,31 @@ LL | asm!("{}", inout(reg) r); = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly error: asm `sym` operand must point to a fn or static - --> $DIR/type-check-2.rs:35:24 + --> $DIR/type-check-2.rs:37:24 | LL | asm!("{}", sym C); | ^ error: asm `sym` operand must point to a fn or static - --> $DIR/type-check-2.rs:37:24 + --> $DIR/type-check-2.rs:39:24 | LL | asm!("{}", sym x); | ^ error[E0381]: use of possibly-uninitialized variable: `x` - --> $DIR/type-check-2.rs:13:28 + --> $DIR/type-check-2.rs:15:28 | LL | asm!("{}", in(reg) x); | ^ use of possibly-uninitialized `x` error[E0381]: use of possibly-uninitialized variable: `y` - --> $DIR/type-check-2.rs:16:9 + --> $DIR/type-check-2.rs:18:9 | LL | asm!("{}", inout(reg) y); | ^^^^^^^^^^^^^^^^^^^^^^^^ use of possibly-uninitialized `y` error[E0596]: cannot borrow `v` as mutable, as it is not declared as mutable - --> $DIR/type-check-2.rs:24:29 + --> $DIR/type-check-2.rs:26:29 | LL | let v: Vec = vec![0, 1, 2]; | - help: consider changing this to be mutable: `mut v` @@ -89,7 +89,7 @@ LL | asm!("{}", out(reg) v[0]); | ^ cannot borrow as mutable error[E0596]: cannot borrow `v` as mutable, as it is not declared as mutable - --> $DIR/type-check-2.rs:26:31 + --> $DIR/type-check-2.rs:28:31 | LL | let v: Vec = vec![0, 1, 2]; | - help: consider changing this to be mutable: `mut v` diff --git a/src/test/ui/asm/x86_64/type-check-3.rs b/src/test/ui/asm/x86_64/type-check-3.rs index 83674cf8204..595de55fd8b 100644 --- a/src/test/ui/asm/x86_64/type-check-3.rs +++ b/src/test/ui/asm/x86_64/type-check-3.rs @@ -1,7 +1,9 @@ // only-x86_64 // compile-flags: -C target-feature=+avx512f -#![feature(asm, global_asm, asm_const)] +#![feature(asm_const)] + +use std::arch::{asm, global_asm}; use std::arch::x86_64::{_mm256_setzero_ps, _mm_setzero_ps}; diff --git a/src/test/ui/asm/x86_64/type-check-3.stderr b/src/test/ui/asm/x86_64/type-check-3.stderr index 9f6989ca03d..aeb638d6949 100644 --- a/src/test/ui/asm/x86_64/type-check-3.stderr +++ b/src/test/ui/asm/x86_64/type-check-3.stderr @@ -1,5 +1,5 @@ error: type `i128` cannot be used with this register class - --> $DIR/type-check-3.rs:12:28 + --> $DIR/type-check-3.rs:14:28 | LL | asm!("{}", in(reg) 0i128); | ^^^^^ @@ -7,7 +7,7 @@ LL | asm!("{}", in(reg) 0i128); = note: register class `reg` supports these types: i16, i32, i64, f32, f64 error: type `__m128` cannot be used with this register class - --> $DIR/type-check-3.rs:14:28 + --> $DIR/type-check-3.rs:16:28 | LL | asm!("{}", in(reg) _mm_setzero_ps()); | ^^^^^^^^^^^^^^^^ @@ -15,7 +15,7 @@ LL | asm!("{}", in(reg) _mm_setzero_ps()); = note: register class `reg` supports these types: i16, i32, i64, f32, f64 error: type `__m256` cannot be used with this register class - --> $DIR/type-check-3.rs:16:28 + --> $DIR/type-check-3.rs:18:28 | LL | asm!("{}", in(reg) _mm256_setzero_ps()); | ^^^^^^^^^^^^^^^^^^^ @@ -23,7 +23,7 @@ LL | asm!("{}", in(reg) _mm256_setzero_ps()); = note: register class `reg` supports these types: i16, i32, i64, f32, f64 error: type `u8` cannot be used with this register class - --> $DIR/type-check-3.rs:18:32 + --> $DIR/type-check-3.rs:20:32 | LL | asm!("{}", in(xmm_reg) 0u8); | ^^^ @@ -31,7 +31,7 @@ LL | asm!("{}", in(xmm_reg) 0u8); = note: register class `xmm_reg` supports these types: i32, i64, f32, f64, i8x16, i16x8, i32x4, i64x2, f32x4, f64x2 error: `avx512bw` target feature is not enabled - --> $DIR/type-check-3.rs:27:29 + --> $DIR/type-check-3.rs:29:29 | LL | asm!("{}", in(kreg) 0u64); | ^^^^ @@ -39,7 +39,7 @@ LL | asm!("{}", in(kreg) 0u64); = note: this is required to use type `u64` with register class `kreg` warning: formatting may not be suitable for sub-register argument - --> $DIR/type-check-3.rs:32:15 + --> $DIR/type-check-3.rs:34:15 | LL | asm!("{0} {0}", in(reg) 0i16); | ^^^ ^^^ ---- for this argument @@ -49,7 +49,7 @@ LL | asm!("{0} {0}", in(reg) 0i16); = help: or use the `r` modifier to keep the default formatting of `rax` warning: formatting may not be suitable for sub-register argument - --> $DIR/type-check-3.rs:34:15 + --> $DIR/type-check-3.rs:36:15 | LL | asm!("{0} {0:x}", in(reg) 0i16); | ^^^ ---- for this argument @@ -58,7 +58,7 @@ LL | asm!("{0} {0:x}", in(reg) 0i16); = help: or use the `r` modifier to keep the default formatting of `rax` warning: formatting may not be suitable for sub-register argument - --> $DIR/type-check-3.rs:36:15 + --> $DIR/type-check-3.rs:38:15 | LL | asm!("{}", in(reg) 0i32); | ^^ ---- for this argument @@ -67,7 +67,7 @@ LL | asm!("{}", in(reg) 0i32); = help: or use the `r` modifier to keep the default formatting of `rax` warning: formatting may not be suitable for sub-register argument - --> $DIR/type-check-3.rs:39:15 + --> $DIR/type-check-3.rs:41:15 | LL | asm!("{}", in(ymm_reg) 0i64); | ^^ ---- for this argument @@ -76,7 +76,7 @@ LL | asm!("{}", in(ymm_reg) 0i64); = help: or use the `y` modifier to keep the default formatting of `ymm0` error: type `i8` cannot be used with this register class - --> $DIR/type-check-3.rs:50:28 + --> $DIR/type-check-3.rs:52:28 | LL | asm!("{}", in(reg) 0i8); | ^^^ @@ -85,7 +85,7 @@ LL | asm!("{}", in(reg) 0i8); = help: consider using the `reg_byte` register class instead error: incompatible types for asm inout argument - --> $DIR/type-check-3.rs:62:33 + --> $DIR/type-check-3.rs:64:33 | LL | asm!("{:r}", inout(reg) 0u32 => val_f32); | ^^^^ ^^^^^^^ type `f32` @@ -95,7 +95,7 @@ LL | asm!("{:r}", inout(reg) 0u32 => val_f32); = note: asm inout arguments must have the same type, unless they are both pointers or integers of the same size error: incompatible types for asm inout argument - --> $DIR/type-check-3.rs:64:33 + --> $DIR/type-check-3.rs:66:33 | LL | asm!("{:r}", inout(reg) 0u32 => val_ptr); | ^^^^ ^^^^^^^ type `*mut u8` @@ -105,7 +105,7 @@ LL | asm!("{:r}", inout(reg) 0u32 => val_ptr); = note: asm inout arguments must have the same type, unless they are both pointers or integers of the same size error: incompatible types for asm inout argument - --> $DIR/type-check-3.rs:66:33 + --> $DIR/type-check-3.rs:68:33 | LL | asm!("{:r}", inout(reg) main => val_u32); | ^^^^ ^^^^^^^ type `u32` @@ -115,7 +115,7 @@ LL | asm!("{:r}", inout(reg) main => val_u32); = note: asm inout arguments must have the same type, unless they are both pointers or integers of the same size error[E0013]: constants cannot refer to statics - --> $DIR/type-check-3.rs:82:25 + --> $DIR/type-check-3.rs:84:25 | LL | global_asm!("{}", const S); | ^ @@ -123,7 +123,7 @@ LL | global_asm!("{}", const S); = help: consider extracting the value of the `static` to a `const`, and referring to that error[E0013]: constants cannot refer to statics - --> $DIR/type-check-3.rs:85:35 + --> $DIR/type-check-3.rs:87:35 | LL | global_asm!("{}", const const_foo(S)); | ^ @@ -131,7 +131,7 @@ LL | global_asm!("{}", const const_foo(S)); = help: consider extracting the value of the `static` to a `const`, and referring to that error[E0013]: constants cannot refer to statics - --> $DIR/type-check-3.rs:88:35 + --> $DIR/type-check-3.rs:90:35 | LL | global_asm!("{}", const const_bar(S)); | ^ diff --git a/src/test/ui/consts/inline_asm.rs b/src/test/ui/consts/inline_asm.rs index b46ca6ba6df..4cd7e2717fe 100644 --- a/src/test/ui/consts/inline_asm.rs +++ b/src/test/ui/consts/inline_asm.rs @@ -1,6 +1,6 @@ // needs-asm-support -#![feature(asm)] +use std::arch::asm; const _: () = unsafe { asm!("nop") }; //~^ ERROR inline assembly diff --git a/src/test/ui/consts/miri_unleashed/inline_asm.rs b/src/test/ui/consts/miri_unleashed/inline_asm.rs index b9421330d05..1bb22a1301a 100644 --- a/src/test/ui/consts/miri_unleashed/inline_asm.rs +++ b/src/test/ui/consts/miri_unleashed/inline_asm.rs @@ -1,9 +1,11 @@ // compile-flags: -Zunleash-the-miri-inside-of-you // only-x86_64 -#![feature(asm,llvm_asm)] +#![feature(llvm_asm)] #![allow(const_err)] #![allow(deprecated)] // llvm_asm! +use std::arch::asm; + fn main() {} // Make sure we catch executing inline assembly. diff --git a/src/test/ui/consts/miri_unleashed/inline_asm.stderr b/src/test/ui/consts/miri_unleashed/inline_asm.stderr index ac9191a340c..34ac808ed17 100644 --- a/src/test/ui/consts/miri_unleashed/inline_asm.stderr +++ b/src/test/ui/consts/miri_unleashed/inline_asm.stderr @@ -1,5 +1,5 @@ error[E0080]: could not evaluate static initializer - --> $DIR/inline_asm.rs:11:14 + --> $DIR/inline_asm.rs:13:14 | LL | unsafe { llvm_asm!("xor %eax, %eax" ::: "eax"); } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ inline assembly is not supported @@ -7,7 +7,7 @@ LL | unsafe { llvm_asm!("xor %eax, %eax" ::: "eax"); } = note: this error originates in the macro `llvm_asm` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0080]: could not evaluate static initializer - --> $DIR/inline_asm.rs:20:14 + --> $DIR/inline_asm.rs:22:14 | LL | unsafe { asm!("nop"); } | ^^^^^^^^^^^ inline assembly is not supported @@ -15,12 +15,12 @@ LL | unsafe { asm!("nop"); } warning: skipping const checks | help: skipping check that does not even have a feature gate - --> $DIR/inline_asm.rs:11:14 + --> $DIR/inline_asm.rs:13:14 | LL | unsafe { llvm_asm!("xor %eax, %eax" ::: "eax"); } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/inline_asm.rs:20:14 + --> $DIR/inline_asm.rs:22:14 | LL | unsafe { asm!("nop"); } | ^^^^^^^^^^^ diff --git a/src/test/ui/empty_global_asm.rs b/src/test/ui/empty_global_asm.rs index efbe2b2eb67..bff5c203b91 100644 --- a/src/test/ui/empty_global_asm.rs +++ b/src/test/ui/empty_global_asm.rs @@ -1,6 +1,6 @@ // run-pass -#![feature(global_asm)] +use std::arch::global_asm; #[cfg(target_arch = "x86")] global_asm!(""); diff --git a/src/test/ui/feature-gates/feature-gate-asm.rs b/src/test/ui/feature-gates/feature-gate-asm.rs index b4dca7216b1..556219b98a9 100644 --- a/src/test/ui/feature-gates/feature-gate-asm.rs +++ b/src/test/ui/feature-gates/feature-gate-asm.rs @@ -4,8 +4,6 @@ fn main() { unsafe { - asm!(""); - //~^ ERROR inline assembly is not stable enough llvm_asm!(""); //~^ ERROR prefer using the new asm! syntax instead } diff --git a/src/test/ui/feature-gates/feature-gate-asm.stderr b/src/test/ui/feature-gates/feature-gate-asm.stderr index 144a4258184..72ba70d0d91 100644 --- a/src/test/ui/feature-gates/feature-gate-asm.stderr +++ b/src/test/ui/feature-gates/feature-gate-asm.stderr @@ -1,14 +1,5 @@ -error[E0658]: use of unstable library feature 'asm': inline assembly is not stable enough for use and is subject to change - --> $DIR/feature-gate-asm.rs:7:9 - | -LL | asm!(""); - | ^^^ - | - = note: see issue #72016 for more information - = help: add `#![feature(asm)]` to the crate attributes to enable - error[E0658]: use of unstable library feature 'llvm_asm': prefer using the new asm! syntax instead - --> $DIR/feature-gate-asm.rs:9:9 + --> $DIR/feature-gate-asm.rs:7:9 | LL | llvm_asm!(""); | ^^^^^^^^ @@ -16,6 +7,6 @@ LL | llvm_asm!(""); = note: see issue #70173 for more information = help: add `#![feature(llvm_asm)]` to the crate attributes to enable -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gates/feature-gate-asm2.rs b/src/test/ui/feature-gates/feature-gate-asm2.rs index 9044f2cb6af..712e3a56fd8 100644 --- a/src/test/ui/feature-gates/feature-gate-asm2.rs +++ b/src/test/ui/feature-gates/feature-gate-asm2.rs @@ -4,8 +4,6 @@ fn main() { unsafe { - println!("{:?}", asm!("")); - //~^ ERROR inline assembly is not stable enough println!("{:?}", llvm_asm!("")); //~^ ERROR prefer using the new asm! syntax instead } diff --git a/src/test/ui/feature-gates/feature-gate-asm2.stderr b/src/test/ui/feature-gates/feature-gate-asm2.stderr index 0b0c8a64d22..0297fec16dd 100644 --- a/src/test/ui/feature-gates/feature-gate-asm2.stderr +++ b/src/test/ui/feature-gates/feature-gate-asm2.stderr @@ -1,14 +1,5 @@ -error[E0658]: use of unstable library feature 'asm': inline assembly is not stable enough for use and is subject to change - --> $DIR/feature-gate-asm2.rs:7:26 - | -LL | println!("{:?}", asm!("")); - | ^^^ - | - = note: see issue #72016 for more information - = help: add `#![feature(asm)]` to the crate attributes to enable - error[E0658]: use of unstable library feature 'llvm_asm': prefer using the new asm! syntax instead - --> $DIR/feature-gate-asm2.rs:9:26 + --> $DIR/feature-gate-asm2.rs:7:26 | LL | println!("{:?}", llvm_asm!("")); | ^^^^^^^^ @@ -16,6 +7,6 @@ LL | println!("{:?}", llvm_asm!("")); = note: see issue #70173 for more information = help: add `#![feature(llvm_asm)]` to the crate attributes to enable -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gates/feature-gate-asm_const.rs b/src/test/ui/feature-gates/feature-gate-asm_const.rs index c152b54c669..d41d7b258aa 100644 --- a/src/test/ui/feature-gates/feature-gate-asm_const.rs +++ b/src/test/ui/feature-gates/feature-gate-asm_const.rs @@ -1,6 +1,6 @@ // only-x86_64 -#![feature(asm)] +use std::arch::asm; fn main() { unsafe { diff --git a/src/test/ui/feature-gates/feature-gate-asm_sym.rs b/src/test/ui/feature-gates/feature-gate-asm_sym.rs index d89c7dd0ef4..e4d781c6859 100644 --- a/src/test/ui/feature-gates/feature-gate-asm_sym.rs +++ b/src/test/ui/feature-gates/feature-gate-asm_sym.rs @@ -1,6 +1,6 @@ // only-x86_64 -#![feature(asm)] +use std::arch::asm; fn main() { unsafe { diff --git a/src/test/ui/feature-gates/feature-gate-asm_unwind.rs b/src/test/ui/feature-gates/feature-gate-asm_unwind.rs index c9957ff91d5..df161b60081 100644 --- a/src/test/ui/feature-gates/feature-gate-asm_unwind.rs +++ b/src/test/ui/feature-gates/feature-gate-asm_unwind.rs @@ -1,6 +1,6 @@ // only-x86_64 -#![feature(asm)] +use std::arch::asm; fn main() { unsafe { diff --git a/src/test/ui/feature-gates/feature-gate-global_asm.rs b/src/test/ui/feature-gates/feature-gate-global_asm.rs deleted file mode 100644 index 1420eef299b..00000000000 --- a/src/test/ui/feature-gates/feature-gate-global_asm.rs +++ /dev/null @@ -1,5 +0,0 @@ -// needs-asm-support - -global_asm!(""); //~ ERROR `global_asm!` is not stable - -fn main() {} diff --git a/src/test/ui/feature-gates/feature-gate-global_asm.stderr b/src/test/ui/feature-gates/feature-gate-global_asm.stderr deleted file mode 100644 index 7c4d3e3e6e5..00000000000 --- a/src/test/ui/feature-gates/feature-gate-global_asm.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0658]: use of unstable library feature 'global_asm': `global_asm!` is not stable enough for use and is subject to change - --> $DIR/feature-gate-global_asm.rs:3:1 - | -LL | global_asm!(""); - | ^^^^^^^^^^ - | - = note: see issue #35119 for more information - = help: add `#![feature(global_asm)]` to the crate attributes to enable - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gates/feature-gate-naked_functions.rs b/src/test/ui/feature-gates/feature-gate-naked_functions.rs index 71ca5b9373a..8e93b194174 100644 --- a/src/test/ui/feature-gates/feature-gate-naked_functions.rs +++ b/src/test/ui/feature-gates/feature-gate-naked_functions.rs @@ -1,5 +1,6 @@ // needs-asm-support -#![feature(asm)] + +use std::arch::asm; #[naked] //~^ the `#[naked]` attribute is an experimental feature diff --git a/src/test/ui/feature-gates/feature-gate-naked_functions.stderr b/src/test/ui/feature-gates/feature-gate-naked_functions.stderr index 653d7b738da..4378fb36367 100644 --- a/src/test/ui/feature-gates/feature-gate-naked_functions.stderr +++ b/src/test/ui/feature-gates/feature-gate-naked_functions.stderr @@ -1,5 +1,5 @@ error[E0658]: the `#[naked]` attribute is an experimental feature - --> $DIR/feature-gate-naked_functions.rs:4:1 + --> $DIR/feature-gate-naked_functions.rs:5:1 | LL | #[naked] | ^^^^^^^^ @@ -8,7 +8,7 @@ LL | #[naked] = help: add `#![feature(naked_functions)]` to the crate attributes to enable error[E0658]: the `#[naked]` attribute is an experimental feature - --> $DIR/feature-gate-naked_functions.rs:10:1 + --> $DIR/feature-gate-naked_functions.rs:11:1 | LL | #[naked] | ^^^^^^^^ diff --git a/src/test/ui/liveness/liveness-asm.rs b/src/test/ui/liveness/liveness-asm.rs index b51da0e0d8c..ea5f033cb86 100644 --- a/src/test/ui/liveness/liveness-asm.rs +++ b/src/test/ui/liveness/liveness-asm.rs @@ -3,11 +3,12 @@ // only-x86_64 // check-pass -#![feature(asm)] #![allow(dead_code)] #![warn(unused_assignments)] #![warn(unused_variables)] +use std::arch::asm; + // Test the single inout case unsafe fn f1(mut src: *const u8) { asm!("/*{0}*/", inout(reg) src); //~ WARN value assigned to `src` is never read diff --git a/src/test/ui/liveness/liveness-asm.stderr b/src/test/ui/liveness/liveness-asm.stderr index f385d7a8065..d052aca338c 100644 --- a/src/test/ui/liveness/liveness-asm.stderr +++ b/src/test/ui/liveness/liveness-asm.stderr @@ -1,18 +1,18 @@ warning: value assigned to `src` is never read - --> $DIR/liveness-asm.rs:13:32 + --> $DIR/liveness-asm.rs:14:32 | LL | asm!("/*{0}*/", inout(reg) src); | ^^^ | note: the lint level is defined here - --> $DIR/liveness-asm.rs:8:9 + --> $DIR/liveness-asm.rs:7:9 | LL | #![warn(unused_assignments)] | ^^^^^^^^^^^^^^^^^^ = help: maybe it is overwritten before being read? warning: value assigned to `src` is never read - --> $DIR/liveness-asm.rs:23:39 + --> $DIR/liveness-asm.rs:24:39 | LL | asm!("/*{0}*/", inout(reg) src => src); | ^^^ diff --git a/src/test/ui/macros/global-asm.rs b/src/test/ui/macros/global-asm.rs index b8903e07cfd..26e90edce0b 100644 --- a/src/test/ui/macros/global-asm.rs +++ b/src/test/ui/macros/global-asm.rs @@ -1,7 +1,7 @@ -#![feature(global_asm)] +use std::arch::global_asm; fn main() { - global_asm!(); //~ ERROR requires at least a template string argument + global_asm!(); //~ ERROR requires at least a template string argument global_asm!(struct); //~ ERROR expected expression global_asm!(123); //~ ERROR asm template must be a string literal } diff --git a/src/test/ui/macros/macro-expanded-include/foo/mod.rs b/src/test/ui/macros/macro-expanded-include/foo/mod.rs index a8bfa0299f6..cff110470f2 100644 --- a/src/test/ui/macros/macro-expanded-include/foo/mod.rs +++ b/src/test/ui/macros/macro-expanded-include/foo/mod.rs @@ -5,5 +5,5 @@ macro_rules! m { } macro_rules! n { - () => { unsafe { asm!(include_str!("file.txt")); } } + () => { unsafe { core::arch::asm!(include_str!("file.txt")); } } } diff --git a/src/test/ui/macros/macro-expanded-include/test.rs b/src/test/ui/macros/macro-expanded-include/test.rs index 6a2b5ef7241..20da58a7e8e 100644 --- a/src/test/ui/macros/macro-expanded-include/test.rs +++ b/src/test/ui/macros/macro-expanded-include/test.rs @@ -1,13 +1,13 @@ // needs-asm-support // build-pass (FIXME(62277): could be check-pass?) -#![feature(asm)] #![allow(unused)] #[macro_use] mod foo; m!(); -fn f() { n!(); } - +fn f() { + n!(); +} fn main() {} diff --git a/src/test/ui/macros/macros-nonfatal-errors.rs b/src/test/ui/macros/macros-nonfatal-errors.rs index 24adc0fb407..66e6a2fb783 100644 --- a/src/test/ui/macros/macros-nonfatal-errors.rs +++ b/src/test/ui/macros/macros-nonfatal-errors.rs @@ -3,7 +3,7 @@ // test that errors in a (selection) of macros don't kill compilation // immediately, so that we get more errors listed at a time. -#![feature(asm, llvm_asm)] +#![feature(llvm_asm)] #![feature(trace_macros, concat_idents)] #![feature(stmt_expr_attributes, arbitrary_enum_discriminant)] #![feature(derive_default_enum)] diff --git a/src/test/ui/macros/macros-nonfatal-errors.stderr b/src/test/ui/macros/macros-nonfatal-errors.stderr index 64065cd272a..56e4a07843d 100644 --- a/src/test/ui/macros/macros-nonfatal-errors.stderr +++ b/src/test/ui/macros/macros-nonfatal-errors.stderr @@ -126,12 +126,6 @@ LL | Foo, | = help: consider a manual implementation of `Default` -error: asm template must be a string literal - --> $DIR/macros-nonfatal-errors.rs:99:10 - | -LL | asm!(invalid); - | ^^^^^^^ - error: inline assembly must be a string literal --> $DIR/macros-nonfatal-errors.rs:100:15 | @@ -221,5 +215,14 @@ error: trace_macros! accepts only `true` or `false` LL | trace_macros!(invalid); | ^^^^^^^^^^^^^^^^^^^^^^ +error: cannot find macro `asm` in this scope + --> $DIR/macros-nonfatal-errors.rs:99:5 + | +LL | asm!(invalid); + | ^^^ + | + = note: consider importing this macro: + std::arch::asm + error: aborting due to 27 previous errors diff --git a/src/test/ui/rfc-2091-track-caller/error-with-naked.rs b/src/test/ui/rfc-2091-track-caller/error-with-naked.rs index 9464ffe8722..0045d608133 100644 --- a/src/test/ui/rfc-2091-track-caller/error-with-naked.rs +++ b/src/test/ui/rfc-2091-track-caller/error-with-naked.rs @@ -1,5 +1,7 @@ // needs-asm-support -#![feature(asm, naked_functions)] +#![feature(naked_functions)] + +use std::arch::asm; #[track_caller] //~ ERROR cannot use `#[track_caller]` with `#[naked]` #[naked] diff --git a/src/test/ui/rfc-2091-track-caller/error-with-naked.stderr b/src/test/ui/rfc-2091-track-caller/error-with-naked.stderr index 5f17d6b2b51..d33aecc0f97 100644 --- a/src/test/ui/rfc-2091-track-caller/error-with-naked.stderr +++ b/src/test/ui/rfc-2091-track-caller/error-with-naked.stderr @@ -1,11 +1,11 @@ error[E0736]: cannot use `#[track_caller]` with `#[naked]` - --> $DIR/error-with-naked.rs:4:1 + --> $DIR/error-with-naked.rs:6:1 | LL | #[track_caller] | ^^^^^^^^^^^^^^^ error[E0736]: cannot use `#[track_caller]` with `#[naked]` - --> $DIR/error-with-naked.rs:13:5 + --> $DIR/error-with-naked.rs:15:5 | LL | #[track_caller] | ^^^^^^^^^^^^^^^ diff --git a/src/test/ui/simple_global_asm.rs b/src/test/ui/simple_global_asm.rs index 75b4788b56f..3c69379ff14 100644 --- a/src/test/ui/simple_global_asm.rs +++ b/src/test/ui/simple_global_asm.rs @@ -1,11 +1,10 @@ // run-pass -#![feature(global_asm)] #![feature(naked_functions)] #![allow(dead_code)] #[cfg(any(target_arch = "x86_64", target_arch = "x86"))] -global_asm!( +core::arch::global_asm!( r#" .global foo .global _foo diff --git a/src/test/ui/unsafe/inline_asm.mir.stderr b/src/test/ui/unsafe/inline_asm.mir.stderr index 865d5cc61ca..fee93dc070d 100644 --- a/src/test/ui/unsafe/inline_asm.mir.stderr +++ b/src/test/ui/unsafe/inline_asm.mir.stderr @@ -1,5 +1,5 @@ error[E0133]: use of inline assembly is unsafe and requires unsafe function or block - --> $DIR/inline_asm.rs:10:5 + --> $DIR/inline_asm.rs:11:5 | LL | asm!("nop"); | ^^^^^^^^^^^ use of inline assembly @@ -7,7 +7,7 @@ LL | asm!("nop"); = note: inline assembly is entirely unchecked and can cause undefined behavior error[E0133]: use of inline assembly is unsafe and requires unsafe function or block - --> $DIR/inline_asm.rs:11:5 + --> $DIR/inline_asm.rs:12:5 | LL | llvm_asm!("nop"); | ^^^^^^^^^^^^^^^^ use of inline assembly diff --git a/src/test/ui/unsafe/inline_asm.rs b/src/test/ui/unsafe/inline_asm.rs index 8e1325bc0a8..7c1f86ac0e0 100644 --- a/src/test/ui/unsafe/inline_asm.rs +++ b/src/test/ui/unsafe/inline_asm.rs @@ -3,9 +3,10 @@ // needs-asm-support #![feature(llvm_asm)] -#![feature(asm)] #![allow(deprecated)] // llvm_asm! +use std::arch::asm; + fn main() { asm!("nop"); //~ ERROR use of inline assembly is unsafe and requires unsafe function or block llvm_asm!("nop"); //~ ERROR use of inline assembly is unsafe and requires unsafe function or block diff --git a/src/test/ui/unsafe/inline_asm.thir.stderr b/src/test/ui/unsafe/inline_asm.thir.stderr index 865d5cc61ca..fee93dc070d 100644 --- a/src/test/ui/unsafe/inline_asm.thir.stderr +++ b/src/test/ui/unsafe/inline_asm.thir.stderr @@ -1,5 +1,5 @@ error[E0133]: use of inline assembly is unsafe and requires unsafe function or block - --> $DIR/inline_asm.rs:10:5 + --> $DIR/inline_asm.rs:11:5 | LL | asm!("nop"); | ^^^^^^^^^^^ use of inline assembly @@ -7,7 +7,7 @@ LL | asm!("nop"); = note: inline assembly is entirely unchecked and can cause undefined behavior error[E0133]: use of inline assembly is unsafe and requires unsafe function or block - --> $DIR/inline_asm.rs:11:5 + --> $DIR/inline_asm.rs:12:5 | LL | llvm_asm!("nop"); | ^^^^^^^^^^^^^^^^ use of inline assembly