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