]>
Commit | Line | Data |
---|---|---|
c295e0f8 XL |
1 | // Compiler: |
2 | // | |
3 | // Run-time: | |
4 | // status: 0 | |
5 | ||
a2a8927a XL |
6 | #![feature(asm_const, asm_sym)] |
7 | ||
8 | use std::arch::{asm, global_asm}; | |
c295e0f8 XL |
9 | |
10 | global_asm!(" | |
11 | .global add_asm | |
12 | add_asm: | |
13 | mov rax, rdi | |
14 | add rax, rsi | |
15 | ret" | |
16 | ); | |
17 | ||
18 | extern "C" { | |
19 | fn add_asm(a: i64, b: i64) -> i64; | |
20 | } | |
21 | ||
a2a8927a XL |
22 | pub unsafe fn mem_cpy(dst: *mut u8, src: *const u8, len: usize) { |
23 | asm!( | |
24 | "rep movsb", | |
25 | inout("rdi") dst => _, | |
26 | inout("rsi") src => _, | |
27 | inout("rcx") len => _, | |
28 | options(preserves_flags, nostack) | |
29 | ); | |
30 | } | |
31 | ||
c295e0f8 XL |
32 | fn main() { |
33 | unsafe { | |
34 | asm!("nop"); | |
35 | } | |
36 | ||
37 | let x: u64; | |
38 | unsafe { | |
39 | asm!("mov $5, {}", | |
40 | out(reg) x, | |
41 | options(att_syntax) | |
42 | ); | |
43 | } | |
44 | assert_eq!(x, 5); | |
45 | ||
46 | let x: u64; | |
47 | let input: u64 = 42; | |
48 | unsafe { | |
49 | asm!("mov {input}, {output}", | |
50 | "add $1, {output}", | |
51 | input = in(reg) input, | |
52 | output = out(reg) x, | |
53 | options(att_syntax) | |
54 | ); | |
55 | } | |
56 | assert_eq!(x, 43); | |
57 | ||
58 | let x: u64; | |
59 | unsafe { | |
60 | asm!("mov {}, 6", | |
61 | out(reg) x, | |
62 | ); | |
63 | } | |
64 | assert_eq!(x, 6); | |
65 | ||
66 | let x: u64; | |
67 | let input: u64 = 42; | |
68 | unsafe { | |
69 | asm!("mov {output}, {input}", | |
70 | "add {output}, 1", | |
71 | input = in(reg) input, | |
72 | output = out(reg) x, | |
73 | ); | |
74 | } | |
75 | assert_eq!(x, 43); | |
76 | ||
a2a8927a | 77 | // check inout(reg_class) x |
c295e0f8 XL |
78 | let mut x: u64 = 42; |
79 | unsafe { | |
80 | asm!("add {0}, {0}", | |
a2a8927a | 81 | inout(reg) x |
c295e0f8 XL |
82 | ); |
83 | } | |
84 | assert_eq!(x, 84); | |
85 | ||
86 | // check inout("reg") x | |
87 | let mut x: u64 = 42; | |
88 | unsafe { | |
89 | asm!("add r11, r11", | |
a2a8927a | 90 | inout("r11") x |
c295e0f8 XL |
91 | ); |
92 | } | |
93 | assert_eq!(x, 84); | |
94 | ||
95 | // check a mix of | |
96 | // in("reg") | |
97 | // inout(class) x => y | |
98 | // inout (class) x | |
99 | let x: u64 = 702; | |
100 | let y: u64 = 100; | |
101 | let res: u64; | |
102 | let mut rem: u64 = 0; | |
103 | unsafe { | |
104 | asm!("div r11", | |
105 | in("r11") y, | |
106 | inout("eax") x => res, | |
107 | inout("edx") rem, | |
108 | ); | |
109 | } | |
110 | assert_eq!(res, 7); | |
111 | assert_eq!(rem, 2); | |
112 | ||
a2a8927a | 113 | // check const |
c295e0f8 XL |
114 | let mut x: u64 = 42; |
115 | unsafe { | |
116 | asm!("add {}, {}", | |
117 | inout(reg) x, | |
a2a8927a | 118 | const 1 |
c295e0f8 XL |
119 | ); |
120 | } | |
121 | assert_eq!(x, 43); | |
122 | ||
123 | // check const (ATT syntax) | |
124 | let mut x: u64 = 42; | |
125 | unsafe { | |
126 | asm!("add {}, {}", | |
127 | const 1, | |
128 | inout(reg) x, | |
129 | options(att_syntax) | |
130 | ); | |
131 | } | |
132 | assert_eq!(x, 43); | |
133 | ||
134 | // check sym fn | |
135 | extern "C" fn foo() -> u64 { 42 } | |
136 | let x: u64; | |
137 | unsafe { | |
138 | asm!("call {}", sym foo, lateout("rax") x); | |
139 | } | |
140 | assert_eq!(x, 42); | |
141 | ||
142 | // check sym fn (ATT syntax) | |
143 | let x: u64; | |
144 | unsafe { | |
145 | asm!("call {}", sym foo, lateout("rax") x, options(att_syntax)); | |
146 | } | |
147 | assert_eq!(x, 42); | |
148 | ||
149 | // check sym static | |
150 | static FOO: u64 = 42; | |
151 | let x: u64; | |
152 | unsafe { | |
153 | asm!("mov {1}, qword ptr [rip + {0}]", sym FOO, lateout(reg) x); | |
154 | } | |
155 | assert_eq!(x, 42); | |
156 | ||
157 | // check sym static (ATT syntax) | |
158 | let x: u64; | |
159 | unsafe { | |
160 | asm!("movq {0}(%rip), {1}", sym FOO, lateout(reg) x, options(att_syntax)); | |
161 | } | |
162 | assert_eq!(x, 42); | |
163 | ||
164 | assert_eq!(unsafe { add_asm(40, 2) }, 42); | |
a2a8927a XL |
165 | |
166 | let array1 = [1u8, 2, 3]; | |
167 | let mut array2 = [0u8, 0, 0]; | |
168 | unsafe { | |
169 | mem_cpy(array2.as_mut_ptr(), array1.as_ptr(), 3); | |
170 | } | |
171 | assert_eq!(array1, array2); | |
c295e0f8 | 172 | } |