1
- # ` asm `
1
+ # ` llvm_asm `
2
2
3
- The tracking issue for this feature is: [ #29722 ]
3
+ The tracking issue for this feature is: [ #70173 ]
4
4
5
- [ #29722 ] : https://github.com/rust-lang/rust/issues/29722
5
+ [ #70173 ] : https://github.com/rust-lang/rust/issues/70173
6
6
7
7
------------------------
8
8
9
9
For extremely low-level manipulations and performance reasons, one
10
10
might wish to control the CPU directly. Rust supports using inline
11
- assembly to do this via the ` asm !` macro.
11
+ assembly to do this via the ` llvm_asm !` macro.
12
12
13
13
``` rust,ignore
14
- asm !(assembly template
14
+ llvm_asm !(assembly template
15
15
: output operands
16
16
: input operands
17
17
: clobbers
18
18
: options
19
19
);
20
20
```
21
21
22
- Any use of ` asm ` is feature gated (requires ` #![feature(asm )] ` on the
22
+ Any use of ` llvm_asm ` is feature gated (requires ` #![feature(llvm_asm )] ` on the
23
23
crate to allow) and of course requires an ` unsafe ` block.
24
24
25
25
> ** Note** : the examples here are given in x86/x86-64 assembly, but
@@ -31,12 +31,12 @@ The `assembly template` is the only required parameter and must be a
31
31
literal string (i.e. ` "" ` )
32
32
33
33
``` rust
34
- #![feature(asm )]
34
+ #![feature(llvm_asm )]
35
35
36
36
#[cfg(any(target_arch = " x86" , target_arch = " x86_64" ))]
37
37
fn foo () {
38
38
unsafe {
39
- asm ! (" NOP" );
39
+ llvm_asm ! (" NOP" );
40
40
}
41
41
}
42
42
@@ -51,16 +51,16 @@ fn main() {
51
51
}
52
52
```
53
53
54
- (The ` feature(asm ) ` and ` #[cfg] ` s are omitted from now on.)
54
+ (The ` feature(llvm_asm ) ` and ` #[cfg] ` s are omitted from now on.)
55
55
56
56
Output operands, input operands, clobbers and options are all optional
57
57
but you must add the right number of ` : ` if you skip them:
58
58
59
59
``` rust
60
- # #![feature(asm )]
60
+ # #![feature(llvm_asm )]
61
61
# #[cfg(any(target_arch = " x86" , target_arch = " x86_64" ))]
62
62
# fn main () { unsafe {
63
- asm ! (" xor %eax, %eax"
63
+ llvm_asm ! (" xor %eax, %eax"
64
64
:
65
65
:
66
66
: " eax"
@@ -73,10 +73,10 @@ asm!("xor %eax, %eax"
73
73
Whitespace also doesn't matter:
74
74
75
75
``` rust
76
- # #![feature(asm )]
76
+ # #![feature(llvm_asm )]
77
77
# #[cfg(any(target_arch = " x86" , target_arch = " x86_64" ))]
78
78
# fn main () { unsafe {
79
- asm ! (" xor %eax, %eax" :: : " eax" );
79
+ llvm_asm ! (" xor %eax, %eax" :: : " eax" );
80
80
# } }
81
81
# #[cfg(not(any(target_arch = " x86" , target_arch = " x86_64" )))]
82
82
# fn main () {}
@@ -89,12 +89,12 @@ Input and output operands follow the same format: `:
89
89
expressions must be mutable lvalues, or not yet assigned:
90
90
91
91
``` rust
92
- # #![feature(asm )]
92
+ # #![feature(llvm_asm )]
93
93
# #[cfg(any(target_arch = " x86" , target_arch = " x86_64" ))]
94
94
fn add (a : i32 , b : i32 ) -> i32 {
95
95
let c : i32 ;
96
96
unsafe {
97
- asm ! (" add $2, $0"
97
+ llvm_asm ! (" add $2, $0"
98
98
: " =r" (c )
99
99
: " 0" (a ), " r" (b )
100
100
);
@@ -116,11 +116,11 @@ operand. This is useful for very low level programming, where
116
116
which register you use is important:
117
117
118
118
``` rust
119
- # #![feature(asm )]
119
+ # #![feature(llvm_asm )]
120
120
# #[cfg(any(target_arch = " x86" , target_arch = " x86_64" ))]
121
121
# unsafe fn read_byte_in (port : u16 ) -> u8 {
122
122
let result : u8 ;
123
- asm ! (" in %dx, %al" : " ={al}" (result ) : " {dx}" (port ));
123
+ llvm_asm ! (" in %dx, %al" : " ={al}" (result ) : " {dx}" (port ));
124
124
result
125
125
# }
126
126
```
@@ -133,11 +133,11 @@ compiler not to assume any values loaded into those registers will
133
133
stay valid.
134
134
135
135
``` rust
136
- # #![feature(asm )]
136
+ # #![feature(llvm_asm )]
137
137
# #[cfg(any(target_arch = " x86" , target_arch = " x86_64" ))]
138
138
# fn main () { unsafe {
139
139
// Put the value 0x200 in eax:
140
- asm ! (" mov $$0x200, %eax" : /* no outputs */ : /* no inputs */ : " eax" );
140
+ llvm_asm ! (" mov $$0x200, %eax" : /* no outputs */ : /* no inputs */ : " eax" );
141
141
# } }
142
142
# #[cfg(not(any(target_arch = " x86" , target_arch = " x86_64" )))]
143
143
# fn main () {}
@@ -167,12 +167,12 @@ Current valid options are:
167
167
3 . * intel* - use intel syntax instead of the default AT&T.
168
168
169
169
``` rust
170
- # #![feature(asm )]
170
+ # #![feature(llvm_asm )]
171
171
# #[cfg(any(target_arch = " x86" , target_arch = " x86_64" ))]
172
172
# fn main () {
173
173
let result : i32 ;
174
174
unsafe {
175
- asm ! (" mov eax, 2" : " ={eax}" (result ) : : : " intel" )
175
+ llvm_asm ! (" mov eax, 2" : " ={eax}" (result ) : : : " intel" )
176
176
}
177
177
println! (" eax is currently {}" , result );
178
178
# }
@@ -182,12 +182,12 @@ println!("eax is currently {}", result);
182
182
183
183
## More Information
184
184
185
- The current implementation of the ` asm !` macro is a direct binding to [ LLVM's
185
+ The current implementation of the ` llvm_asm !` macro is a direct binding to [ LLVM's
186
186
inline assembler expressions] [ llvm-docs ] , so be sure to check out [ their
187
187
documentation as well] [ llvm-docs ] for more information about clobbers,
188
188
constraints, etc.
189
189
190
190
[ llvm-docs ] : http://llvm.org/docs/LangRef.html#inline-assembler-expressions
191
191
192
192
If you need more power and don't mind losing some of the niceties of
193
- ` asm !` , check out [ global_asm] ( global-asm.md ) .
193
+ ` llvm_asm !` , check out [ global_asm] ( global-asm.md ) .
0 commit comments