@@ -8,7 +8,6 @@ use rustc_span::sym;
88use rustc_target:: asm:: * ;
99use target_lexicon:: BinaryFormat ;
1010
11- use crate :: global_asm:: asm_supported;
1211use crate :: prelude:: * ;
1312
1413enum CInlineAsmOperand < ' tcx > {
@@ -53,205 +52,6 @@ pub(crate) fn codegen_inline_asm<'tcx>(
5352 return ;
5453 }
5554
56- if !asm_supported ( fx. tcx ) {
57- if template. is_empty ( ) {
58- let destination_block = fx. get_block ( destination. unwrap ( ) ) ;
59- fx. bcx . ins ( ) . jump ( destination_block, & [ ] ) ;
60- return ;
61- }
62-
63- // Used by stdarch
64- if template[ 0 ] == InlineAsmTemplatePiece :: String ( "mov " . to_string ( ) )
65- && matches ! (
66- template[ 1 ] ,
67- InlineAsmTemplatePiece :: Placeholder {
68- operand_idx: 0 ,
69- modifier: Some ( 'r' ) ,
70- span: _
71- }
72- )
73- && template[ 2 ] == InlineAsmTemplatePiece :: String ( ", rbx" . to_string ( ) )
74- && template[ 3 ] == InlineAsmTemplatePiece :: String ( "\n " . to_string ( ) )
75- && template[ 4 ] == InlineAsmTemplatePiece :: String ( "cpuid" . to_string ( ) )
76- && template[ 5 ] == InlineAsmTemplatePiece :: String ( "\n " . to_string ( ) )
77- && template[ 6 ] == InlineAsmTemplatePiece :: String ( "xchg " . to_string ( ) )
78- && matches ! (
79- template[ 7 ] ,
80- InlineAsmTemplatePiece :: Placeholder {
81- operand_idx: 0 ,
82- modifier: Some ( 'r' ) ,
83- span: _
84- }
85- )
86- && template[ 8 ] == InlineAsmTemplatePiece :: String ( ", rbx" . to_string ( ) )
87- {
88- assert_eq ! ( operands. len( ) , 4 ) ;
89- let ( leaf, eax_place) = match operands[ 1 ] {
90- InlineAsmOperand :: InOut {
91- reg : InlineAsmRegOrRegClass :: Reg ( InlineAsmReg :: X86 ( X86InlineAsmReg :: ax) ) ,
92- late : _,
93- ref in_value,
94- out_place : Some ( out_place) ,
95- } => (
96- crate :: base:: codegen_operand ( fx, in_value) . load_scalar ( fx) ,
97- crate :: base:: codegen_place ( fx, out_place) ,
98- ) ,
99- _ => unreachable ! ( ) ,
100- } ;
101- let ebx_place = match operands[ 0 ] {
102- InlineAsmOperand :: Out {
103- reg :
104- InlineAsmRegOrRegClass :: RegClass ( InlineAsmRegClass :: X86 (
105- X86InlineAsmRegClass :: reg,
106- ) ) ,
107- late : _,
108- place : Some ( place) ,
109- } => crate :: base:: codegen_place ( fx, place) ,
110- _ => unreachable ! ( ) ,
111- } ;
112- let ( sub_leaf, ecx_place) = match operands[ 2 ] {
113- InlineAsmOperand :: InOut {
114- reg : InlineAsmRegOrRegClass :: Reg ( InlineAsmReg :: X86 ( X86InlineAsmReg :: cx) ) ,
115- late : _,
116- ref in_value,
117- out_place : Some ( out_place) ,
118- } => (
119- crate :: base:: codegen_operand ( fx, in_value) . load_scalar ( fx) ,
120- crate :: base:: codegen_place ( fx, out_place) ,
121- ) ,
122- _ => unreachable ! ( ) ,
123- } ;
124- let edx_place = match operands[ 3 ] {
125- InlineAsmOperand :: Out {
126- reg : InlineAsmRegOrRegClass :: Reg ( InlineAsmReg :: X86 ( X86InlineAsmReg :: dx) ) ,
127- late : _,
128- place : Some ( place) ,
129- } => crate :: base:: codegen_place ( fx, place) ,
130- _ => unreachable ! ( ) ,
131- } ;
132-
133- let ( eax, ebx, ecx, edx) = crate :: intrinsics:: codegen_cpuid_call ( fx, leaf, sub_leaf) ;
134-
135- eax_place. write_cvalue ( fx, CValue :: by_val ( eax, fx. layout_of ( fx. tcx . types . u32 ) ) ) ;
136- ebx_place. write_cvalue ( fx, CValue :: by_val ( ebx, fx. layout_of ( fx. tcx . types . u32 ) ) ) ;
137- ecx_place. write_cvalue ( fx, CValue :: by_val ( ecx, fx. layout_of ( fx. tcx . types . u32 ) ) ) ;
138- edx_place. write_cvalue ( fx, CValue :: by_val ( edx, fx. layout_of ( fx. tcx . types . u32 ) ) ) ;
139- let destination_block = fx. get_block ( destination. unwrap ( ) ) ;
140- fx. bcx . ins ( ) . jump ( destination_block, & [ ] ) ;
141- return ;
142- }
143-
144- // Used by compiler-builtins
145- if fx. tcx . symbol_name ( fx. instance ) . name . starts_with ( "___chkstk" ) {
146- // ___chkstk, ___chkstk_ms and __alloca are only used on Windows
147- crate :: trap:: trap_unimplemented ( fx, "Stack probes are not supported" ) ;
148- return ;
149- } else if fx. tcx . symbol_name ( fx. instance ) . name == "__alloca" {
150- crate :: trap:: trap_unimplemented ( fx, "Alloca is not supported" ) ;
151- return ;
152- }
153-
154- // Used by core::hint::spin_loop()
155- if template[ 0 ]
156- == InlineAsmTemplatePiece :: String ( ".insn i 0x0F, 0, x0, x0, 0x010" . to_string ( ) )
157- && template. len ( ) == 1
158- {
159- let destination_block = fx. get_block ( destination. unwrap ( ) ) ;
160- fx. bcx . ins ( ) . jump ( destination_block, & [ ] ) ;
161- return ;
162- }
163-
164- // Used by measureme
165- if template[ 0 ] == InlineAsmTemplatePiece :: String ( "xor %eax, %eax" . to_string ( ) )
166- && template[ 1 ] == InlineAsmTemplatePiece :: String ( "\n " . to_string ( ) )
167- && template[ 2 ] == InlineAsmTemplatePiece :: String ( "mov %rbx, " . to_string ( ) )
168- && matches ! (
169- template[ 3 ] ,
170- InlineAsmTemplatePiece :: Placeholder {
171- operand_idx: 0 ,
172- modifier: Some ( 'r' ) ,
173- span: _
174- }
175- )
176- && template[ 4 ] == InlineAsmTemplatePiece :: String ( "\n " . to_string ( ) )
177- && template[ 5 ] == InlineAsmTemplatePiece :: String ( "cpuid" . to_string ( ) )
178- && template[ 6 ] == InlineAsmTemplatePiece :: String ( "\n " . to_string ( ) )
179- && template[ 7 ] == InlineAsmTemplatePiece :: String ( "mov " . to_string ( ) )
180- && matches ! (
181- template[ 8 ] ,
182- InlineAsmTemplatePiece :: Placeholder {
183- operand_idx: 0 ,
184- modifier: Some ( 'r' ) ,
185- span: _
186- }
187- )
188- && template[ 9 ] == InlineAsmTemplatePiece :: String ( ", %rbx" . to_string ( ) )
189- {
190- let destination_block = fx. get_block ( destination. unwrap ( ) ) ;
191- fx. bcx . ins ( ) . jump ( destination_block, & [ ] ) ;
192- return ;
193- } else if template[ 0 ] == InlineAsmTemplatePiece :: String ( "rdpmc" . to_string ( ) ) {
194- // Return zero dummy values for all performance counters
195- match operands[ 0 ] {
196- InlineAsmOperand :: In {
197- reg : InlineAsmRegOrRegClass :: Reg ( InlineAsmReg :: X86 ( X86InlineAsmReg :: cx) ) ,
198- value : _,
199- } => { }
200- _ => unreachable ! ( ) ,
201- } ;
202- let lo = match operands[ 1 ] {
203- InlineAsmOperand :: Out {
204- reg : InlineAsmRegOrRegClass :: Reg ( InlineAsmReg :: X86 ( X86InlineAsmReg :: ax) ) ,
205- late : true ,
206- place : Some ( place) ,
207- } => crate :: base:: codegen_place ( fx, place) ,
208- _ => unreachable ! ( ) ,
209- } ;
210- let hi = match operands[ 2 ] {
211- InlineAsmOperand :: Out {
212- reg : InlineAsmRegOrRegClass :: Reg ( InlineAsmReg :: X86 ( X86InlineAsmReg :: dx) ) ,
213- late : true ,
214- place : Some ( place) ,
215- } => crate :: base:: codegen_place ( fx, place) ,
216- _ => unreachable ! ( ) ,
217- } ;
218-
219- let u32_layout = fx. layout_of ( fx. tcx . types . u32 ) ;
220- let zero = fx. bcx . ins ( ) . iconst ( types:: I32 , 0 ) ;
221- lo. write_cvalue ( fx, CValue :: by_val ( zero, u32_layout) ) ;
222- hi. write_cvalue ( fx, CValue :: by_val ( zero, u32_layout) ) ;
223-
224- let destination_block = fx. get_block ( destination. unwrap ( ) ) ;
225- fx. bcx . ins ( ) . jump ( destination_block, & [ ] ) ;
226- return ;
227- } else if template[ 0 ] == InlineAsmTemplatePiece :: String ( "lock xadd " . to_string ( ) )
228- && matches ! (
229- template[ 1 ] ,
230- InlineAsmTemplatePiece :: Placeholder { operand_idx: 1 , modifier: None , span: _ }
231- )
232- && template[ 2 ] == InlineAsmTemplatePiece :: String ( ", (" . to_string ( ) )
233- && matches ! (
234- template[ 3 ] ,
235- InlineAsmTemplatePiece :: Placeholder { operand_idx: 0 , modifier: None , span: _ }
236- )
237- && template[ 4 ] == InlineAsmTemplatePiece :: String ( ")" . to_string ( ) )
238- {
239- let destination_block = fx. get_block ( destination. unwrap ( ) ) ;
240- fx. bcx . ins ( ) . jump ( destination_block, & [ ] ) ;
241- return ;
242- }
243-
244- if cfg ! ( not( feature = "inline_asm" ) ) {
245- fx. tcx . sess . span_err (
246- span,
247- "asm! and global_asm! support is disabled while compiling rustc_codegen_cranelift" ,
248- ) ;
249- } else {
250- fx. tcx . sess . span_err ( span, "asm! and global_asm! are not yet supported on Windows" ) ;
251- }
252- return ;
253- }
254-
25555 let operands = operands
25656 . into_iter ( )
25757 . map ( |operand| match * operand {
@@ -282,6 +82,12 @@ pub(crate) fn codegen_inline_asm<'tcx>(
28282 CInlineAsmOperand :: Const { value }
28383 }
28484 InlineAsmOperand :: SymFn { ref value } => {
85+ if cfg ! ( not( feature = "inline_asm_sym" ) ) {
86+ fx. tcx
87+ . sess
88+ . span_err ( span, "asm! and global_asm! sym operands are not yet supported" ) ;
89+ }
90+
28591 let const_ = fx. monomorphize ( value. const_ ) ;
28692 if let ty:: FnDef ( def_id, args) = * const_. ty ( ) . kind ( ) {
28793 let instance = ty:: Instance :: resolve_for_fn_ptr (
0 commit comments