Skip to content

Commit 6d218d0

Browse files
committed
Add inline asm! tests for aarch64
Enable tests which are largely architecture-independent on all supported platforms
1 parent 900cf5e commit 6d218d0

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+2570
-76
lines changed

Diff for: src/test/ui/asm/aarch64/bad-options.rs

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// only-aarch64
2+
3+
#![feature(asm, global_asm)]
4+
5+
fn main() {
6+
let mut foo = 0;
7+
unsafe {
8+
asm!("", options(nomem, readonly));
9+
//~^ ERROR the `nomem` and `readonly` options are mutually exclusive
10+
asm!("", options(pure, nomem, noreturn));
11+
//~^ ERROR the `pure` and `noreturn` options are mutually exclusive
12+
//~^^ ERROR asm with the `pure` option must have at least one output
13+
asm!("{}", in(reg) foo, options(pure, nomem));
14+
//~^ ERROR asm with the `pure` option must have at least one output
15+
asm!("{}", out(reg) foo, options(noreturn));
16+
//~^ ERROR asm outputs are not allowed with the `noreturn` option
17+
}
18+
19+
unsafe {
20+
asm!("", clobber_abi("foo"));
21+
//~^ ERROR invalid ABI for `clobber_abi`
22+
asm!("{}", out(reg) foo, clobber_abi("C"));
23+
//~^ ERROR asm with `clobber_abi` must specify explicit registers for outputs
24+
asm!("", out("x0") foo, clobber_abi("C"));
25+
}
26+
}
27+
28+
global_asm!("", options(nomem));
29+
//~^ ERROR expected one of
30+
global_asm!("", options(readonly));
31+
//~^ ERROR expected one of
32+
global_asm!("", options(noreturn));
33+
//~^ ERROR expected one of
34+
global_asm!("", options(pure));
35+
//~^ ERROR expected one of
36+
global_asm!("", options(nostack));
37+
//~^ ERROR expected one of
38+
global_asm!("", options(preserves_flags));
39+
//~^ ERROR expected one of

Diff for: src/test/ui/asm/aarch64/bad-options.stderr

+84
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
error: the `nomem` and `readonly` options are mutually exclusive
2+
--> $DIR/bad-options.rs:8:18
3+
|
4+
LL | asm!("", options(nomem, readonly));
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^
6+
7+
error: the `pure` and `noreturn` options are mutually exclusive
8+
--> $DIR/bad-options.rs:10:18
9+
|
10+
LL | asm!("", options(pure, nomem, noreturn));
11+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
12+
13+
error: asm with the `pure` option must have at least one output
14+
--> $DIR/bad-options.rs:10:18
15+
|
16+
LL | asm!("", options(pure, nomem, noreturn));
17+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
18+
19+
error: asm with the `pure` option must have at least one output
20+
--> $DIR/bad-options.rs:13:33
21+
|
22+
LL | asm!("{}", in(reg) foo, options(pure, nomem));
23+
| ^^^^^^^^^^^^^^^^^^^^
24+
25+
error: asm outputs are not allowed with the `noreturn` option
26+
--> $DIR/bad-options.rs:15:20
27+
|
28+
LL | asm!("{}", out(reg) foo, options(noreturn));
29+
| ^^^^^^^^^^^^
30+
31+
error: asm with `clobber_abi` must specify explicit registers for outputs
32+
--> $DIR/bad-options.rs:22:20
33+
|
34+
LL | asm!("{}", out(reg) foo, clobber_abi("C"));
35+
| ^^^^^^^^^^^^ ---------------- clobber_abi
36+
| |
37+
| generic outputs
38+
39+
error: expected one of `)`, `att_syntax`, or `raw`, found `nomem`
40+
--> $DIR/bad-options.rs:28:25
41+
|
42+
LL | global_asm!("", options(nomem));
43+
| ^^^^^ expected one of `)`, `att_syntax`, or `raw`
44+
45+
error: expected one of `)`, `att_syntax`, or `raw`, found `readonly`
46+
--> $DIR/bad-options.rs:30:25
47+
|
48+
LL | global_asm!("", options(readonly));
49+
| ^^^^^^^^ expected one of `)`, `att_syntax`, or `raw`
50+
51+
error: expected one of `)`, `att_syntax`, or `raw`, found `noreturn`
52+
--> $DIR/bad-options.rs:32:25
53+
|
54+
LL | global_asm!("", options(noreturn));
55+
| ^^^^^^^^ expected one of `)`, `att_syntax`, or `raw`
56+
57+
error: expected one of `)`, `att_syntax`, or `raw`, found `pure`
58+
--> $DIR/bad-options.rs:34:25
59+
|
60+
LL | global_asm!("", options(pure));
61+
| ^^^^ expected one of `)`, `att_syntax`, or `raw`
62+
63+
error: expected one of `)`, `att_syntax`, or `raw`, found `nostack`
64+
--> $DIR/bad-options.rs:36:25
65+
|
66+
LL | global_asm!("", options(nostack));
67+
| ^^^^^^^ expected one of `)`, `att_syntax`, or `raw`
68+
69+
error: expected one of `)`, `att_syntax`, or `raw`, found `preserves_flags`
70+
--> $DIR/bad-options.rs:38:25
71+
|
72+
LL | global_asm!("", options(preserves_flags));
73+
| ^^^^^^^^^^^^^^^ expected one of `)`, `att_syntax`, or `raw`
74+
75+
error: invalid ABI for `clobber_abi`
76+
--> $DIR/bad-options.rs:20:18
77+
|
78+
LL | asm!("", clobber_abi("foo"));
79+
| ^^^^^^^^^^^^^^^^^^
80+
|
81+
= note: the following ABIs are supported on this target: `C`, `system`, `efiapi`
82+
83+
error: aborting due to 13 previous errors
84+

Diff for: src/test/ui/asm/aarch64/bad-reg.rs

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// only-aarch64
2+
// compile-flags: -C target-feature=+fp
3+
4+
#![feature(asm)]
5+
6+
fn main() {
7+
let mut foo = 0;
8+
let mut bar = 0;
9+
unsafe {
10+
// Bad register/register class
11+
12+
asm!("{}", in(foo) foo);
13+
//~^ ERROR invalid register class `foo`: unknown register class
14+
asm!("", in("foo") foo);
15+
//~^ ERROR invalid register `foo`: unknown register
16+
asm!("{:z}", in(reg) foo);
17+
//~^ ERROR invalid asm template modifier for this register class
18+
asm!("{:r}", in(vreg) foo);
19+
//~^ ERROR invalid asm template modifier for this register class
20+
asm!("{:r}", in(vreg_low16) foo);
21+
//~^ ERROR invalid asm template modifier for this register class
22+
asm!("{:a}", const 0);
23+
//~^ ERROR asm template modifiers are not allowed for `const` arguments
24+
asm!("{:a}", sym main);
25+
//~^ ERROR asm template modifiers are not allowed for `sym` arguments
26+
asm!("", in("x29") foo);
27+
//~^ ERROR invalid register `x29`: the frame pointer cannot be used as an operand
28+
asm!("", in("sp") foo);
29+
//~^ ERROR invalid register `sp`: the stack pointer cannot be used as an operand
30+
asm!("", in("xzr") foo);
31+
//~^ ERROR invalid register `xzr`: the zero register cannot be used as an operand
32+
asm!("", in("x18") foo);
33+
//~^ ERROR invalid register `x18`: x18 is used as a reserved register on some targets and cannot be used as an operand for inline asm
34+
asm!("", in("x19") foo);
35+
//~^ ERROR invalid register `x19`: x19 is used internally by LLVM and cannot be used as an operand for inline asm
36+
37+
asm!("", in("p0") foo);
38+
//~^ ERROR register class `preg` can only be used as a clobber, not as an input or output
39+
asm!("", out("p0") _);
40+
asm!("{}", in(preg) foo);
41+
//~^ ERROR register class `preg` can only be used as a clobber, not as an input or output
42+
asm!("{}", out(preg) _);
43+
//~^ ERROR register class `preg` can only be used as a clobber, not as an input or output
44+
45+
// Explicit register conflicts
46+
// (except in/lateout which don't conflict)
47+
48+
asm!("", in("x0") foo, in("w0") bar);
49+
//~^ ERROR register `x0` conflicts with register `x0`
50+
asm!("", in("x0") foo, out("x0") bar);
51+
//~^ ERROR register `x0` conflicts with register `x0`
52+
asm!("", in("w0") foo, lateout("w0") bar);
53+
asm!("", in("v0") foo, in("q0") bar);
54+
//~^ ERROR register `v0` conflicts with register `v0`
55+
asm!("", in("v0") foo, out("q0") bar);
56+
//~^ ERROR register `v0` conflicts with register `v0`
57+
asm!("", in("v0") foo, lateout("q0") bar);
58+
}
59+
}

Diff for: src/test/ui/asm/aarch64/bad-reg.stderr

+152
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
error: invalid register class `foo`: unknown register class
2+
--> $DIR/bad-reg.rs:12:20
3+
|
4+
LL | asm!("{}", in(foo) foo);
5+
| ^^^^^^^^^^^
6+
7+
error: invalid register `foo`: unknown register
8+
--> $DIR/bad-reg.rs:14:18
9+
|
10+
LL | asm!("", in("foo") foo);
11+
| ^^^^^^^^^^^^^
12+
13+
error: invalid asm template modifier for this register class
14+
--> $DIR/bad-reg.rs:16:15
15+
|
16+
LL | asm!("{:z}", in(reg) foo);
17+
| ^^^^ ----------- argument
18+
| |
19+
| template modifier
20+
|
21+
= note: the `reg` register class supports the following template modifiers: `w`, `x`
22+
23+
error: invalid asm template modifier for this register class
24+
--> $DIR/bad-reg.rs:18:15
25+
|
26+
LL | asm!("{:r}", in(vreg) foo);
27+
| ^^^^ ------------ argument
28+
| |
29+
| template modifier
30+
|
31+
= note: the `vreg` register class supports the following template modifiers: `b`, `h`, `s`, `d`, `q`, `v`
32+
33+
error: invalid asm template modifier for this register class
34+
--> $DIR/bad-reg.rs:20:15
35+
|
36+
LL | asm!("{:r}", in(vreg_low16) foo);
37+
| ^^^^ ------------------ argument
38+
| |
39+
| template modifier
40+
|
41+
= note: the `vreg_low16` register class supports the following template modifiers: `b`, `h`, `s`, `d`, `q`, `v`
42+
43+
error: asm template modifiers are not allowed for `const` arguments
44+
--> $DIR/bad-reg.rs:22:15
45+
|
46+
LL | asm!("{:a}", const 0);
47+
| ^^^^ ------- argument
48+
| |
49+
| template modifier
50+
51+
error: asm template modifiers are not allowed for `sym` arguments
52+
--> $DIR/bad-reg.rs:24:15
53+
|
54+
LL | asm!("{:a}", sym main);
55+
| ^^^^ -------- argument
56+
| |
57+
| template modifier
58+
59+
error: invalid register `x29`: the frame pointer cannot be used as an operand for inline asm
60+
--> $DIR/bad-reg.rs:26:18
61+
|
62+
LL | asm!("", in("x29") foo);
63+
| ^^^^^^^^^^^^^
64+
65+
error: invalid register `sp`: the stack pointer cannot be used as an operand for inline asm
66+
--> $DIR/bad-reg.rs:28:18
67+
|
68+
LL | asm!("", in("sp") foo);
69+
| ^^^^^^^^^^^^
70+
71+
error: invalid register `xzr`: the zero register cannot be used as an operand for inline asm
72+
--> $DIR/bad-reg.rs:30:18
73+
|
74+
LL | asm!("", in("xzr") foo);
75+
| ^^^^^^^^^^^^^
76+
77+
error: invalid register `x18`: x18 is used as a reserved register on some targets and cannot be used as an operand for inline asm
78+
--> $DIR/bad-reg.rs:32:18
79+
|
80+
LL | asm!("", in("x18") foo);
81+
| ^^^^^^^^^^^^^
82+
83+
error: invalid register `x19`: x19 is used internally by LLVM and cannot be used as an operand for inline asm
84+
--> $DIR/bad-reg.rs:34:18
85+
|
86+
LL | asm!("", in("x19") foo);
87+
| ^^^^^^^^^^^^^
88+
89+
error: register class `preg` can only be used as a clobber, not as an input or output
90+
--> $DIR/bad-reg.rs:37:18
91+
|
92+
LL | asm!("", in("p0") foo);
93+
| ^^^^^^^^^^^^
94+
95+
error: register class `preg` can only be used as a clobber, not as an input or output
96+
--> $DIR/bad-reg.rs:40:20
97+
|
98+
LL | asm!("{}", in(preg) foo);
99+
| ^^^^^^^^^^^^
100+
101+
error: register class `preg` can only be used as a clobber, not as an input or output
102+
--> $DIR/bad-reg.rs:42:20
103+
|
104+
LL | asm!("{}", out(preg) _);
105+
| ^^^^^^^^^^^
106+
107+
error: register `x0` conflicts with register `x0`
108+
--> $DIR/bad-reg.rs:48:32
109+
|
110+
LL | asm!("", in("x0") foo, in("w0") bar);
111+
| ------------ ^^^^^^^^^^^^ register `x0`
112+
| |
113+
| register `x0`
114+
115+
error: register `x0` conflicts with register `x0`
116+
--> $DIR/bad-reg.rs:50:32
117+
|
118+
LL | asm!("", in("x0") foo, out("x0") bar);
119+
| ------------ ^^^^^^^^^^^^^ register `x0`
120+
| |
121+
| register `x0`
122+
|
123+
help: use `lateout` instead of `out` to avoid conflict
124+
--> $DIR/bad-reg.rs:50:18
125+
|
126+
LL | asm!("", in("x0") foo, out("x0") bar);
127+
| ^^^^^^^^^^^^
128+
129+
error: register `v0` conflicts with register `v0`
130+
--> $DIR/bad-reg.rs:53:32
131+
|
132+
LL | asm!("", in("v0") foo, in("q0") bar);
133+
| ------------ ^^^^^^^^^^^^ register `v0`
134+
| |
135+
| register `v0`
136+
137+
error: register `v0` conflicts with register `v0`
138+
--> $DIR/bad-reg.rs:55:32
139+
|
140+
LL | asm!("", in("v0") foo, out("q0") bar);
141+
| ------------ ^^^^^^^^^^^^^ register `v0`
142+
| |
143+
| register `v0`
144+
|
145+
help: use `lateout` instead of `out` to avoid conflict
146+
--> $DIR/bad-reg.rs:55:18
147+
|
148+
LL | asm!("", in("v0") foo, out("q0") bar);
149+
| ^^^^^^^^^^^^
150+
151+
error: aborting due to 19 previous errors
152+

Diff for: src/test/ui/asm/aarch64/const.rs

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// min-llvm-version: 10.0.1
2+
// only-aarch64
3+
// run-pass
4+
// revisions: mirunsafeck thirunsafeck
5+
// [thirunsafeck]compile-flags: -Z thir-unsafeck
6+
7+
#![feature(asm, global_asm)]
8+
9+
fn const_generic<const X: usize>() -> usize {
10+
unsafe {
11+
let a: usize;
12+
asm!("mov {}, {}", out(reg) a, const X);
13+
a
14+
}
15+
}
16+
17+
const fn constfn(x: usize) -> usize {
18+
x
19+
}
20+
21+
fn main() {
22+
unsafe {
23+
let a: usize;
24+
asm!("mov {}, {}", out(reg) a, const 5);
25+
assert_eq!(a, 5);
26+
27+
let b: usize;
28+
asm!("mov {}, {}", out(reg) b, const constfn(5));
29+
assert_eq!(b, 5);
30+
31+
let c: usize;
32+
asm!("mov {}, {}", out(reg) c, const constfn(5) + constfn(5));
33+
assert_eq!(c, 10);
34+
}
35+
36+
let d = const_generic::<5>();
37+
assert_eq!(d, 5);
38+
}
39+
40+
global_asm!("mov x0, {}", const 5);
41+
global_asm!("mov x0, {}", const constfn(5));
42+
global_asm!("mov x0, {}", const constfn(5) + constfn(5));

0 commit comments

Comments
 (0)