]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_codegen_gcc/tests/run/asm.rs
Merge commit '1411a98352ba6bee8ba3b0131c9243e5db1e6a2e' into sync_cg_clif-2021-12-31
[rust.git] / compiler / rustc_codegen_gcc / tests / run / asm.rs
1 // Compiler:
2 //
3 // Run-time:
4 //   status: 0
5
6 #![feature(asm_const, asm_sym)]
7
8 use std::arch::{asm, global_asm};
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
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
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
77     // check inout(reg_class) x
78     let mut x: u64 = 42;
79     unsafe {
80         asm!("add {0}, {0}",
81             inout(reg) x
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",
90             inout("r11") x
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
113     // check const
114     let mut x: u64 = 42;
115     unsafe {
116         asm!("add {}, {}",
117             inout(reg) x,
118             const 1
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);
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);
172 }