diff options
| author | bors <bors@rust-lang.org> | 2021-05-13 22:17:43 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2021-05-13 22:17:43 +0000 |
| commit | 17f30e5451f581d753899d2f628e5be354df33cd (patch) | |
| tree | 58252137260855f9c5791b84bda1dcdb4d90407b /src | |
| parent | 6d395a1c2946c79966490f5b1e6e619d3a713e6b (diff) | |
| parent | a7ed6a5196996f00dd78a391a44af51ee8088058 (diff) | |
| download | rust-17f30e5451f581d753899d2f628e5be354df33cd.tar.gz rust-17f30e5451f581d753899d2f628e5be354df33cd.zip | |
Auto merge of #84107 - Amanieu:global_asm2, r=nagisa
Add support for const operands and options to global_asm! On x86, the default syntax is also switched to Intel to match asm!. Currently `global_asm!` only supports `const` operands and the `att_syntax` option. In the future, `sym` operands will also be supported. However there is no plan to support any of the other operand types or options since they don't make sense in the context of `global_asm!`. r? `@nagisa`
Diffstat (limited to 'src')
24 files changed, 514 insertions, 58 deletions
diff --git a/src/doc/unstable-book/src/library-features/global-asm.md b/src/doc/unstable-book/src/library-features/global-asm.md index ce1155a977c..146d17b4638 100644 --- a/src/doc/unstable-book/src/library-features/global-asm.md +++ b/src/doc/unstable-book/src/library-features/global-asm.md @@ -8,12 +8,9 @@ The tracking issue for this feature is: [#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. The macro is a no-frills -interface to LLVM's concept of [module-level inline assembly]. That is, -all caveats applicable to LLVM's module-level inline assembly apply -to `global_asm!`. - -[module-level inline assembly]: http://llvm.org/docs/LangRef.html#module-level-inline-assembly +`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 @@ -38,11 +35,11 @@ And a more complicated usage looks like this: # mod x86 { pub mod sally { - global_asm!(r#" - .global foo - foo: - jmp baz - "#); + global_asm!( + ".global foo", + "foo:", + "jmp baz", + ); #[no_mangle] pub unsafe extern "C" fn baz() {} @@ -56,11 +53,11 @@ extern "C" { } pub mod harry { - global_asm!(r#" - .global bar - bar: - jmp quux - "#); + global_asm!( + ".global bar", + "bar:", + "jmp quux", + ); #[no_mangle] pub unsafe extern "C" fn quux() {} @@ -69,8 +66,44 @@ pub mod harry { ``` You may use `global_asm!` multiple times, anywhere in your crate, in -whatever way suits you. The effect is as if you concatenated all -usages and placed the larger, single usage in the crate root. +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)] +# #[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)] +# #[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); +# } +``` ------------------------ diff --git a/src/test/assembly/asm/global_asm.rs b/src/test/assembly/asm/global_asm.rs new file mode 100644 index 00000000000..3a7f2fa1efb --- /dev/null +++ b/src/test/assembly/asm/global_asm.rs @@ -0,0 +1,14 @@ +// min-llvm-version: 10.0.1 +// only-x86_64 +// assembly-output: emit-asm +// compile-flags: -C llvm-args=--x86-asm-syntax=intel + +#![feature(asm, global_asm)] +#![crate_type = "rlib"] + +// CHECK: mov eax, eax +global_asm!("mov eax, eax"); +// CHECK: mov ebx, 5 +global_asm!("mov ebx, {}", const 5); +// CHECK: mov ecx, 5 +global_asm!("movl ${}, %ecx", const 5, options(att_syntax)); 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 8e91a8d842c..791dec2ed69 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 @@ -8,7 +8,7 @@ rust_plus_one_global_asm: movl (%rdi), %eax inc %eax retq -"# ); +"#, options(att_syntax)); extern { fn cc_plus_one_c(arg : &u32) -> u32; diff --git a/src/test/ui/asm/bad-arch.rs b/src/test/ui/asm/bad-arch.rs index 763b5fe5cca..3eeb76f3d00 100644 --- a/src/test/ui/asm/bad-arch.rs +++ b/src/test/ui/asm/bad-arch.rs @@ -8,12 +8,19 @@ macro_rules! asm { () => {}; } +#[rustc_builtin_macro] +macro_rules! global_asm { + () => {}; +} #[lang = "sized"] trait Sized {} fn main() { unsafe { asm!(""); - //~^ ERROR asm! is unsupported on this target + //~^ ERROR inline assembly is unsupported on this target } } + +global_asm!(""); +//~^ ERROR inline assembly is unsupported on this target diff --git a/src/test/ui/asm/bad-arch.stderr b/src/test/ui/asm/bad-arch.stderr index cb876f28650..6094643b038 100644 --- a/src/test/ui/asm/bad-arch.stderr +++ b/src/test/ui/asm/bad-arch.stderr @@ -1,8 +1,16 @@ -error[E0472]: asm! is unsupported on this target - --> $DIR/bad-arch.rs:16:9 +error[E0472]: inline assembly is unsupported on this target + --> $DIR/bad-arch.rs:20:9 | LL | asm!(""); | ^^^^^^^^^ -error: aborting due to previous error +error[E0472]: inline assembly is unsupported on this target + --> $DIR/bad-arch.rs:25:1 + | +LL | global_asm!(""); + | ^^^^^^^^^^^^^^^^ + | + = note: this error originates in the macro `global_asm` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 2 previous errors diff --git a/src/test/ui/asm/bad-options.rs b/src/test/ui/asm/bad-options.rs index 755fc2ca238..923d65bfd96 100644 --- a/src/test/ui/asm/bad-options.rs +++ b/src/test/ui/asm/bad-options.rs @@ -1,6 +1,6 @@ // only-x86_64 -#![feature(asm)] +#![feature(asm, global_asm)] fn main() { let mut foo = 0; @@ -16,3 +16,16 @@ fn main() { //~^ ERROR asm outputs are not allowed with the `noreturn` option } } + +global_asm!("", options(nomem)); +//~^ ERROR expected one of +global_asm!("", options(readonly)); +//~^ ERROR expected one of +global_asm!("", options(noreturn)); +//~^ ERROR expected one of +global_asm!("", options(pure)); +//~^ ERROR expected one of +global_asm!("", options(nostack)); +//~^ ERROR expected one of +global_asm!("", options(preserves_flags)); +//~^ ERROR expected one of diff --git a/src/test/ui/asm/bad-options.stderr b/src/test/ui/asm/bad-options.stderr index c5e8e2ccf44..4e27a6e2cb5 100644 --- a/src/test/ui/asm/bad-options.stderr +++ b/src/test/ui/asm/bad-options.stderr @@ -28,5 +28,41 @@ error: asm outputs are not allowed with the `noreturn` option LL | asm!("{}", out(reg) foo, options(noreturn)); | ^^^^^^^^^^^^ -error: aborting due to 5 previous errors +error: expected one of `)` or `att_syntax`, found `nomem` + --> $DIR/bad-options.rs:20:25 + | +LL | global_asm!("", options(nomem)); + | ^^^^^ expected one of `)` or `att_syntax` + +error: expected one of `)` or `att_syntax`, found `readonly` + --> $DIR/bad-options.rs:22:25 + | +LL | global_asm!("", options(readonly)); + | ^^^^^^^^ expected one of `)` or `att_syntax` + +error: expected one of `)` or `att_syntax`, found `noreturn` + --> $DIR/bad-options.rs:24:25 + | +LL | global_asm!("", options(noreturn)); + | ^^^^^^^^ expected one of `)` or `att_syntax` + +error: expected one of `)` or `att_syntax`, found `pure` + --> $DIR/bad-options.rs:26:25 + | +LL | global_asm!("", options(pure)); + | ^^^^ expected one of `)` or `att_syntax` + +error: expected one of `)` or `att_syntax`, found `nostack` + --> $DIR/bad-options.rs:28:25 + | +LL | global_asm!("", options(nostack)); + | ^^^^^^^ expected one of `)` or `att_syntax` + +error: expected one of `)` or `att_syntax`, found `preserves_flags` + --> $DIR/bad-options.rs:30:25 + | +LL | global_asm!("", options(preserves_flags)); + | ^^^^^^^^^^^^^^^ expected one of `)` or `att_syntax` + +error: aborting due to 11 previous errors diff --git a/src/test/ui/asm/bad-template.rs b/src/test/ui/asm/bad-template.rs index 21ce8c6236d..4404be4fa3a 100644 --- a/src/test/ui/asm/bad-template.rs +++ b/src/test/ui/asm/bad-template.rs @@ -1,6 +1,6 @@ // only-x86_64 -#![feature(asm)] +#![feature(asm, global_asm)] fn main() { let mut foo = 0; @@ -26,3 +26,22 @@ fn main() { //~^ ERROR multiple unused asm arguments } } + +const FOO: i32 = 1; +global_asm!("{}"); +//~^ ERROR invalid reference to argument at index 0 +global_asm!("{1}", const FOO); +//~^ ERROR invalid reference to argument at index 1 +//~^^ ERROR argument never used +global_asm!("{a}"); +//~^ ERROR there is no argument named `a` +global_asm!("{}", a = const FOO); +//~^ ERROR invalid reference to argument at index 0 +//~^^ ERROR argument never used +global_asm!("{1}", a = const FOO); +//~^ ERROR invalid reference to argument at index 1 +//~^^ ERROR named argument never used +global_asm!("{:foo}", const FOO); +//~^ ERROR asm template modifier must be a single character +global_asm!("", const FOO, const FOO); +//~^ ERROR multiple unused asm arguments diff --git a/src/test/ui/asm/bad-template.stderr b/src/test/ui/asm/bad-template.stderr index 1aea7467ed0..d95663d2a73 100644 --- a/src/test/ui/asm/bad-template.stderr +++ b/src/test/ui/asm/bad-template.stderr @@ -98,5 +98,90 @@ LL | asm!("", in(reg) 0, in(reg) 1); | = help: if these arguments are intentionally unused, consider using them in an asm comment: `"/* {0} {1} */"` -error: aborting due to 11 previous errors +error: invalid reference to argument at index 0 + --> $DIR/bad-template.rs:31:14 + | +LL | global_asm!("{}"); + | ^^ from here + | + = note: no arguments were given + +error: invalid reference to argument at index 1 + --> $DIR/bad-template.rs:33:14 + | +LL | global_asm!("{1}", const FOO); + | ^^^ from here + | + = note: there is 1 argument + +error: argument never used + --> $DIR/bad-template.rs:33:20 + | +LL | global_asm!("{1}", const FOO); + | ^^^^^^^^^ argument never used + | + = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {0} */"` + +error: there is no argument named `a` + --> $DIR/bad-template.rs:36:14 + | +LL | global_asm!("{a}"); + | ^^^ + +error: invalid reference to argument at index 0 + --> $DIR/bad-template.rs:38:14 + | +LL | global_asm!("{}", a = const FOO); + | ^^ ------------- named argument + | | + | from here + | + = note: no positional arguments were given +note: named arguments cannot be referenced by position + --> $DIR/bad-template.rs:38:19 + | +LL | global_asm!("{}", a = const FOO); + | ^^^^^^^^^^^^^ + +error: named argument never used + --> $DIR/bad-template.rs:38:19 + | +LL | global_asm!("{}", a = const FOO); + | ^^^^^^^^^^^^^ named argument never used + | + = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {a} */"` + +error: invalid reference to argument at index 1 + --> $DIR/bad-template.rs:41:14 + | +LL | global_asm!("{1}", a = const FOO); + | ^^^ from here + | + = note: no positional arguments were given + +error: named argument never used + --> $DIR/bad-template.rs:41:20 + | +LL | global_asm!("{1}", a = const FOO); + | ^^^^^^^^^^^^^ named argument never used + | + = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {a} */"` + +error: asm template modifier must be a single character + --> $DIR/bad-template.rs:44:16 + | +LL | global_asm!("{:foo}", const FOO); + | ^^^ + +error: multiple unused asm arguments + --> $DIR/bad-template.rs:46:17 + | +LL | global_asm!("", const FOO, const FOO); + | ^^^^^^^^^ ^^^^^^^^^ argument never used + | | + | argument never used + | + = help: if these arguments are intentionally unused, consider using them in an asm comment: `"/* {0} {1} */"` + +error: aborting due to 21 previous errors diff --git a/src/test/ui/asm/const.rs b/src/test/ui/asm/const.rs index 0f6a7cd4474..fd940173c42 100644 --- a/src/test/ui/asm/const.rs +++ b/src/test/ui/asm/const.rs @@ -2,7 +2,7 @@ // only-x86_64 // run-pass -#![feature(asm)] +#![feature(asm, global_asm)] fn const_generic<const X: usize>() -> usize { unsafe { @@ -34,3 +34,7 @@ fn main() { let d = const_generic::<5>(); assert_eq!(d, 5); } + +global_asm!("mov eax, {}", const 5); +global_asm!("mov eax, {}", const constfn(5)); +global_asm!("mov eax, {}", const constfn(5) + constfn(5)); diff --git a/src/test/ui/asm/duplicate-options.fixed b/src/test/ui/asm/duplicate-options.fixed index f4672a50fd0..d4444e9c6cc 100644 --- a/src/test/ui/asm/duplicate-options.fixed +++ b/src/test/ui/asm/duplicate-options.fixed @@ -1,7 +1,7 @@ // only-x86_64 // run-rustfix -#![feature(asm)] +#![feature(asm, global_asm)] fn main() { unsafe { @@ -24,3 +24,6 @@ fn main() { ); } } + +global_asm!("", options(att_syntax, )); +//~^ ERROR the `att_syntax` option was already provided diff --git a/src/test/ui/asm/duplicate-options.rs b/src/test/ui/asm/duplicate-options.rs index 80292d7521a..fd28311984b 100644 --- a/src/test/ui/asm/duplicate-options.rs +++ b/src/test/ui/asm/duplicate-options.rs @@ -1,7 +1,7 @@ // only-x86_64 // run-rustfix -#![feature(asm)] +#![feature(asm, global_asm)] fn main() { unsafe { @@ -24,3 +24,6 @@ fn main() { ); } } + +global_asm!("", options(att_syntax, att_syntax)); +//~^ ERROR the `att_syntax` option was already provided diff --git a/src/test/ui/asm/duplicate-options.stderr b/src/test/ui/asm/duplicate-options.stderr index cd8d743e031..53edf8fb91c 100644 --- a/src/test/ui/asm/duplicate-options.stderr +++ b/src/test/ui/asm/duplicate-options.stderr @@ -52,5 +52,11 @@ error: the `noreturn` option was already provided LL | options(noreturn), | ^^^^^^^^ this option was already provided -error: aborting due to 9 previous errors +error: the `att_syntax` option was already provided + --> $DIR/duplicate-options.rs:28:37 + | +LL | global_asm!("", options(att_syntax, att_syntax)); + | ^^^^^^^^^^ this option was already provided + +error: aborting due to 10 previous errors diff --git a/src/test/ui/asm/inline-syntax.arm.stderr b/src/test/ui/asm/inline-syntax.arm.stderr index bcae1d565f1..b1685bd4e02 100644 --- a/src/test/ui/asm/inline-syntax.arm.stderr +++ b/src/test/ui/asm/inline-syntax.arm.stderr @@ -1,5 +1,19 @@ error: unknown directive - --> $DIR/inline-syntax.rs:25:15 +.intel_syntax noprefix +^ +error: unknown directive +.intel_syntax noprefix +^ +error: unknown directive + | +note: instantiated into assembly here + --> <inline asm>:1:1 + | +LL | .intel_syntax noprefix + | ^ + +error: unknown directive + --> $DIR/inline-syntax.rs:29:15 | LL | asm!(".intel_syntax noprefix", "nop"); | ^ @@ -11,7 +25,7 @@ LL | .intel_syntax noprefix | ^ error: unknown directive - --> $DIR/inline-syntax.rs:28:15 + --> $DIR/inline-syntax.rs:32:15 | LL | asm!(".intel_syntax aaa noprefix", "nop"); | ^ @@ -23,7 +37,7 @@ LL | .intel_syntax aaa noprefix | ^ error: unknown directive - --> $DIR/inline-syntax.rs:31:15 + --> $DIR/inline-syntax.rs:35:15 | LL | asm!(".att_syntax noprefix", "nop"); | ^ @@ -35,7 +49,7 @@ LL | .att_syntax noprefix | ^ error: unknown directive - --> $DIR/inline-syntax.rs:34:15 + --> $DIR/inline-syntax.rs:38:15 | LL | asm!(".att_syntax bbb noprefix", "nop"); | ^ @@ -47,7 +61,7 @@ LL | .att_syntax bbb noprefix | ^ error: unknown directive - --> $DIR/inline-syntax.rs:37:15 + --> $DIR/inline-syntax.rs:41:15 | LL | asm!(".intel_syntax noprefix; nop"); | ^ @@ -59,7 +73,7 @@ LL | .intel_syntax noprefix; nop | ^ error: unknown directive - --> $DIR/inline-syntax.rs:43:13 + --> $DIR/inline-syntax.rs:47:13 | LL | .intel_syntax noprefix | ^ @@ -70,5 +84,5 @@ note: instantiated into assembly here LL | .intel_syntax noprefix | ^ -error: aborting due to 6 previous errors +error: aborting due to 7 previous errors diff --git a/src/test/ui/asm/inline-syntax.rs b/src/test/ui/asm/inline-syntax.rs index 13ded19cfea..2d54ef7bd6b 100644 --- a/src/test/ui/asm/inline-syntax.rs +++ b/src/test/ui/asm/inline-syntax.rs @@ -16,6 +16,10 @@ macro_rules! asm { () => {}; } +#[rustc_builtin_macro] +macro_rules! global_asm { + () => {}; +} #[lang = "sized"] trait Sized {} @@ -47,3 +51,7 @@ pub fn main() { //[arm]~^^^^ ERROR unknown directive } } + +global_asm!(".intel_syntax noprefix", "nop"); +//[x86_64]~^ WARN avoid using `.intel_syntax` +// Assembler errors don't have line numbers, so no error on ARM diff --git a/src/test/ui/asm/inline-syntax.x86_64.stderr b/src/test/ui/asm/inline-syntax.x86_64.stderr index 02b29b09013..59c95194322 100644 --- a/src/test/ui/asm/inline-syntax.x86_64.stderr +++ b/src/test/ui/asm/inline-syntax.x86_64.stderr @@ -1,40 +1,46 @@ warning: avoid using `.intel_syntax`, Intel syntax is the default - --> $DIR/inline-syntax.rs:25:15 + --> $DIR/inline-syntax.rs:55:14 | -LL | asm!(".intel_syntax noprefix", "nop"); - | ^^^^^^^^^^^^^^^^^^^^^^ +LL | global_asm!(".intel_syntax noprefix", "nop"); + | ^^^^^^^^^^^^^^^^^^^^^^ | = note: `#[warn(bad_asm_style)]` on by default warning: avoid using `.intel_syntax`, Intel syntax is the default - --> $DIR/inline-syntax.rs:28:15 + --> $DIR/inline-syntax.rs:29:15 + | +LL | asm!(".intel_syntax noprefix", "nop"); + | ^^^^^^^^^^^^^^^^^^^^^^ + +warning: avoid using `.intel_syntax`, Intel syntax is the default + --> $DIR/inline-syntax.rs:32:15 | LL | asm!(".intel_syntax aaa noprefix", "nop"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: avoid using `.att_syntax`, prefer using `options(att_syntax)` instead - --> $DIR/inline-syntax.rs:31:15 + --> $DIR/inline-syntax.rs:35:15 | LL | asm!(".att_syntax noprefix", "nop"); | ^^^^^^^^^^^^^^^^^^^^ warning: avoid using `.att_syntax`, prefer using `options(att_syntax)` instead - --> $DIR/inline-syntax.rs:34:15 + --> $DIR/inline-syntax.rs:38:15 | LL | asm!(".att_syntax bbb noprefix", "nop"); | ^^^^^^^^^^^^^^^^^^^^^^^^ warning: avoid using `.intel_syntax`, Intel syntax is the default - --> $DIR/inline-syntax.rs:37:15 + --> $DIR/inline-syntax.rs:41:15 | LL | asm!(".intel_syntax noprefix; nop"); | ^^^^^^^^^^^^^^^^^^^^^^ warning: avoid using `.intel_syntax`, Intel syntax is the default - --> $DIR/inline-syntax.rs:43:13 + --> $DIR/inline-syntax.rs:47:13 | LL | .intel_syntax noprefix | ^^^^^^^^^^^^^^^^^^^^^^ -warning: 6 warnings emitted +warning: 7 warnings emitted diff --git a/src/test/ui/asm/parse-error.rs b/src/test/ui/asm/parse-error.rs index f2e9d9ca08b..e62e6668415 100644 --- a/src/test/ui/asm/parse-error.rs +++ b/src/test/ui/asm/parse-error.rs @@ -1,6 +1,6 @@ // only-x86_64 -#![feature(asm)] +#![feature(asm, global_asm)] fn main() { let mut foo = 0; @@ -63,3 +63,37 @@ fn main() { //~^ ERROR asm template must be a string literal } } + +const FOO: i32 = 1; +const BAR: i32 = 2; +global_asm!(); +//~^ ERROR requires at least a template string argument +global_asm!(FOO); +//~^ ERROR asm template must be a string literal +global_asm!("{}" FOO); +//~^ ERROR expected token: `,` +global_asm!("{}", FOO); +//~^ ERROR expected operand, options, or additional template string +global_asm!("{}", const); +//~^ ERROR expected expression, found end of macro arguments +global_asm!("{}", const(reg) FOO); +//~^ ERROR expected one of +global_asm!("", options(FOO)); +//~^ ERROR expected one of +global_asm!("", options(nomem FOO)); +//~^ ERROR expected one of +global_asm!("", options(nomem, FOO)); +//~^ ERROR expected one of +global_asm!("{}", options(), const FOO); +//~^ ERROR arguments are not allowed after options +global_asm!("{a}", a = const FOO, a = const BAR); +//~^ ERROR duplicate argument named `a` +//~^^ ERROR argument never used +global_asm!("", options(), ""); +//~^ ERROR expected one of +global_asm!("{}", const FOO, "{}", const FOO); +//~^ ERROR expected one of +global_asm!(format!("{{{}}}", 0), const FOO); +//~^ ERROR asm template must be a string literal +global_asm!("{1}", format!("{{{}}}", 0), const FOO, const BAR); +//~^ ERROR asm template must be a string literal diff --git a/src/test/ui/asm/parse-error.stderr b/src/test/ui/asm/parse-error.stderr index 74918e1c400..afd262b851c 100644 --- a/src/test/ui/asm/parse-error.stderr +++ b/src/test/ui/asm/parse-error.stderr @@ -164,6 +164,112 @@ 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: requires at least a template string argument + --> $DIR/parse-error.rs:69:1 + | +LL | global_asm!(); + | ^^^^^^^^^^^^^^ + +error: asm template must be a string literal + --> $DIR/parse-error.rs:71:13 + | +LL | global_asm!(FOO); + | ^^^ + +error: expected token: `,` + --> $DIR/parse-error.rs:73:18 + | +LL | global_asm!("{}" FOO); + | ^^^ expected `,` + +error: expected operand, options, or additional template string + --> $DIR/parse-error.rs:75:19 + | +LL | global_asm!("{}", FOO); + | ^^^ expected operand, options, or additional template string + +error: expected expression, found end of macro arguments + --> $DIR/parse-error.rs:77:24 + | +LL | global_asm!("{}", const); + | ^ expected expression + +error: expected one of `,`, `.`, `?`, or an operator, found `FOO` + --> $DIR/parse-error.rs:79:30 + | +LL | global_asm!("{}", const(reg) FOO); + | ^^^ expected one of `,`, `.`, `?`, or an operator + +error: expected one of `)` or `att_syntax`, found `FOO` + --> $DIR/parse-error.rs:81:25 + | +LL | global_asm!("", options(FOO)); + | ^^^ expected one of `)` or `att_syntax` + +error: expected one of `)` or `att_syntax`, found `nomem` + --> $DIR/parse-error.rs:83:25 + | +LL | global_asm!("", options(nomem FOO)); + | ^^^^^ expected one of `)` or `att_syntax` + +error: expected one of `)` or `att_syntax`, found `nomem` + --> $DIR/parse-error.rs:85:25 + | +LL | global_asm!("", options(nomem, FOO)); + | ^^^^^ expected one of `)` or `att_syntax` + +error: arguments are not allowed after options + --> $DIR/parse-error.rs:87:30 + | +LL | global_asm!("{}", options(), const FOO); + | --------- ^^^^^^^^^ argument + | | + | previous options + +error: duplicate argument named `a` + --> $DIR/parse-error.rs:89:35 + | +LL | global_asm!("{a}", a = const FOO, a = const BAR); + | ------------- ^^^^^^^^^^^^^ duplicate argument + | | + | previously here + +error: argument never used + --> $DIR/parse-error.rs:89:35 + | +LL | global_asm!("{a}", a = const FOO, a = const BAR); + | ^^^^^^^^^^^^^ argument never used + | + = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {1} */"` + +error: expected one of `const` or `options`, found `""` + --> $DIR/parse-error.rs:92:28 + | +LL | global_asm!("", options(), ""); + | ^^ expected one of `const` or `options` + +error: expected one of `const` or `options`, found `"{}"` + --> $DIR/parse-error.rs:94:30 + | +LL | global_asm!("{}", const FOO, "{}", const FOO); + | ^^^^ expected one of `const` or `options` + +error: asm template must be a string literal + --> $DIR/parse-error.rs:96:13 + | +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:98:20 + | +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 | @@ -218,6 +324,6 @@ LL | let mut bar = 0; LL | asm!("{1}", in("eax") foo, const bar); | ^^^ non-constant value -error: aborting due to 31 previous errors +error: aborting due to 47 previous errors For more information about this error, try `rustc --explain E0435`. diff --git a/src/test/ui/asm/type-check-2.rs b/src/test/ui/asm/type-check-2.rs index 0677167ccfe..060a88fc937 100644 --- a/src/test/ui/asm/type-check-2.rs +++ b/src/test/ui/asm/type-check-2.rs @@ -1,6 +1,6 @@ // only-x86_64 -#![feature(asm, repr_simd, never_type)] +#![feature(asm, global_asm, repr_simd, never_type)] #[repr(simd)] struct SimdNonCopy(f32, f32, f32, f32); @@ -90,3 +90,11 @@ fn main() { asm!("{}", in(reg) u); } } + +// Const operands must be integer or floats, and must be constants. + +global_asm!("{}", const 0); +global_asm!("{}", const 0i32); +global_asm!("{}", const 0f32); +global_asm!("{}", const 0 as *mut u8); +//~^ ERROR asm `const` arguments must be integer or floating-point values diff --git a/src/test/ui/asm/type-check-2.stderr b/src/test/ui/asm/type-check-2.stderr index c152560a64f..f61f690bdb4 100644 --- a/src/test/ui/asm/type-check-2.stderr +++ b/src/test/ui/asm/type-check-2.stderr @@ -61,6 +61,12 @@ 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 `const` arguments must be integer or floating-point values + --> $DIR/type-check-2.rs:99:19 + | +LL | global_asm!("{}", const 0 as *mut u8); + | ^^^^^^^^^^^^^^^^^^ + error: asm `sym` operand must point to a fn or static --> $DIR/type-check-2.rs:47:24 | @@ -103,7 +109,7 @@ LL | let v: Vec<u64> = vec![0, 1, 2]; LL | asm!("{}", inout(reg) v[0]); | ^ cannot borrow as mutable -error: aborting due to 14 previous errors +error: aborting due to 15 previous errors Some errors have detailed explanations: E0381, E0596. For more information about an error, try `rustc --explain E0381`. diff --git a/src/test/ui/asm/type-check-3.rs b/src/test/ui/asm/type-check-3.rs index 6890baead81..c2c1885ff16 100644 --- a/src/test/ui/asm/type-check-3.rs +++ b/src/test/ui/asm/type-check-3.rs @@ -1,7 +1,7 @@ // only-x86_64 // compile-flags: -C target-feature=+avx512f -#![feature(asm)] +#![feature(asm, global_asm)] use std::arch::x86_64::{_mm256_setzero_ps, _mm_setzero_ps}; @@ -69,3 +69,21 @@ fn main() { asm!("{:r}", inout(reg) main => val_u64); } } + +// Constants must be... constant + +static S: i32 = 1; +const fn const_foo(x: i32) -> i32 { + x +} +const fn const_bar<T>(x: T) -> T { + x +} +global_asm!("{}", const S); +//~^ ERROR constants cannot refer to statics +global_asm!("{}", const const_foo(0)); +global_asm!("{}", const const_foo(S)); +//~^ ERROR constants cannot refer to statics +global_asm!("{}", const const_bar(0)); +global_asm!("{}", const const_bar(S)); +//~^ ERROR constants cannot refer to statics diff --git a/src/test/ui/asm/type-check-3.stderr b/src/test/ui/asm/type-check-3.stderr index 42497456ac3..9f6989ca03d 100644 --- a/src/test/ui/asm/type-check-3.stderr +++ b/src/test/ui/asm/type-check-3.stderr @@ -114,5 +114,30 @@ 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: aborting due to 9 previous errors; 4 warnings emitted +error[E0013]: constants cannot refer to statics + --> $DIR/type-check-3.rs:82:25 + | +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 + | +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 + | +LL | global_asm!("{}", const const_bar(S)); + | ^ + | + = help: consider extracting the value of the `static` to a `const`, and referring to that + +error: aborting due to 12 previous errors; 4 warnings emitted +For more information about this error, try `rustc --explain E0013`. diff --git a/src/test/ui/macros/global-asm.rs b/src/test/ui/macros/global-asm.rs index 8402afa5085..b8903e07cfd 100644 --- a/src/test/ui/macros/global-asm.rs +++ b/src/test/ui/macros/global-asm.rs @@ -1,7 +1,7 @@ #![feature(global_asm)] fn main() { - global_asm!(); //~ ERROR requires a string literal as an argument + global_asm!(); //~ ERROR requires at least a template string argument global_asm!(struct); //~ ERROR expected expression - global_asm!(123); //~ ERROR inline assembly must be a string literal + global_asm!(123); //~ ERROR asm template must be a string literal } diff --git a/src/test/ui/macros/global-asm.stderr b/src/test/ui/macros/global-asm.stderr index c43bf83fe19..a8621a0c518 100644 --- a/src/test/ui/macros/global-asm.stderr +++ b/src/test/ui/macros/global-asm.stderr @@ -1,8 +1,8 @@ -error: macro requires a string literal as an argument +error: requires at least a template string argument --> $DIR/global-asm.rs:4:5 | LL | global_asm!(); - | ^^^^^^^^^^^^^^ string literal required + | ^^^^^^^^^^^^^^ error: expected expression, found keyword `struct` --> $DIR/global-asm.rs:5:17 @@ -10,7 +10,7 @@ error: expected expression, found keyword `struct` LL | global_asm!(struct); | ^^^^^^ expected expression -error: inline assembly must be a string literal +error: asm template must be a string literal --> $DIR/global-asm.rs:6:17 | LL | global_asm!(123); |
