@@ -46,6 +46,13 @@ pub(crate) fn codegen_global_asm_item(tcx: TyCtxt<'_>, global_asm: &mut String,
46
46
global_asm. push_str ( & string) ;
47
47
}
48
48
InlineAsmOperand :: SymFn { anon_const } => {
49
+ if cfg ! ( not( feature = "inline_asm_sym" ) ) {
50
+ tcx. sess . span_err (
51
+ item. span ,
52
+ "asm! and global_asm! sym operands are not yet supported" ,
53
+ ) ;
54
+ }
55
+
49
56
let ty = tcx. typeck_body ( anon_const. body ) . node_type ( anon_const. hir_id ) ;
50
57
let instance = match ty. kind ( ) {
51
58
& ty:: FnDef ( def_id, args) => Instance :: new ( def_id, args) ,
@@ -57,6 +64,13 @@ pub(crate) fn codegen_global_asm_item(tcx: TyCtxt<'_>, global_asm: &mut String,
57
64
global_asm. push_str ( symbol. name ) ;
58
65
}
59
66
InlineAsmOperand :: SymStatic { path : _, def_id } => {
67
+ if cfg ! ( not( feature = "inline_asm_sym" ) ) {
68
+ tcx. sess . span_err (
69
+ item. span ,
70
+ "asm! and global_asm! sym operands are not yet supported" ,
71
+ ) ;
72
+ }
73
+
60
74
let instance = Instance :: mono ( tcx, def_id) . polymorphize ( tcx) ;
61
75
let symbol = tcx. symbol_name ( instance) ;
62
76
global_asm. push_str ( symbol. name ) ;
@@ -81,22 +95,23 @@ pub(crate) fn codegen_global_asm_item(tcx: TyCtxt<'_>, global_asm: &mut String,
81
95
}
82
96
}
83
97
84
- pub ( crate ) fn asm_supported ( tcx : TyCtxt < ' _ > ) -> bool {
85
- cfg ! ( feature = "inline_asm" ) && !tcx. sess . target . is_like_windows
86
- }
87
-
88
98
#[ derive( Debug ) ]
89
99
pub ( crate ) struct GlobalAsmConfig {
90
- asm_enabled : bool ,
91
100
assembler : PathBuf ,
101
+ target : String ,
92
102
pub ( crate ) output_filenames : Arc < OutputFilenames > ,
93
103
}
94
104
95
105
impl GlobalAsmConfig {
96
106
pub ( crate ) fn new ( tcx : TyCtxt < ' _ > ) -> Self {
97
107
GlobalAsmConfig {
98
- asm_enabled : asm_supported ( tcx) ,
99
108
assembler : crate :: toolchain:: get_toolchain_binary ( tcx. sess , "as" ) ,
109
+ target : match & tcx. sess . opts . target_triple {
110
+ rustc_target:: spec:: TargetTriple :: TargetTriple ( triple) => triple. clone ( ) ,
111
+ rustc_target:: spec:: TargetTriple :: TargetJson { path_for_rustdoc, .. } => {
112
+ path_for_rustdoc. to_str ( ) . unwrap ( ) . to_owned ( )
113
+ }
114
+ } ,
100
115
output_filenames : tcx. output_filenames ( ( ) ) . clone ( ) ,
101
116
}
102
117
}
@@ -111,21 +126,6 @@ pub(crate) fn compile_global_asm(
111
126
return Ok ( None ) ;
112
127
}
113
128
114
- if !config. asm_enabled {
115
- if global_asm. contains ( "__rust_probestack" ) {
116
- return Ok ( None ) ;
117
- }
118
-
119
- if cfg ! ( not( feature = "inline_asm" ) ) {
120
- return Err (
121
- "asm! and global_asm! support is disabled while compiling rustc_codegen_cranelift"
122
- . to_owned ( ) ,
123
- ) ;
124
- } else {
125
- return Err ( "asm! and global_asm! are not yet supported on Windows" . to_owned ( ) ) ;
126
- }
127
- }
128
-
129
129
// Remove all LLVM style comments
130
130
let mut global_asm = global_asm
131
131
. lines ( )
@@ -134,20 +134,67 @@ pub(crate) fn compile_global_asm(
134
134
. join ( "\n " ) ;
135
135
global_asm. push ( '\n' ) ;
136
136
137
- let output_object_file = config. output_filenames . temp_path ( OutputType :: Object , Some ( cgu_name) ) ;
137
+ let global_asm_object_file = add_file_stem_postfix (
138
+ config. output_filenames . temp_path ( OutputType :: Object , Some ( cgu_name) ) ,
139
+ ".asm" ,
140
+ ) ;
138
141
139
142
// Assemble `global_asm`
140
- let global_asm_object_file = add_file_stem_postfix ( output_object_file, ".asm" ) ;
141
- let mut child = Command :: new ( & config. assembler )
142
- . arg ( "-o" )
143
- . arg ( & global_asm_object_file)
144
- . stdin ( Stdio :: piped ( ) )
145
- . spawn ( )
146
- . expect ( "Failed to spawn `as`." ) ;
147
- child. stdin . take ( ) . unwrap ( ) . write_all ( global_asm. as_bytes ( ) ) . unwrap ( ) ;
148
- let status = child. wait ( ) . expect ( "Failed to wait for `as`." ) ;
149
- if !status. success ( ) {
150
- return Err ( format ! ( "Failed to assemble `{}`" , global_asm) ) ;
143
+ if option_env ! ( "CG_CLIF_FORCE_GNU_AS" ) . is_some ( ) {
144
+ let mut child = Command :: new ( & config. assembler )
145
+ . arg ( "-o" )
146
+ . arg ( & global_asm_object_file)
147
+ . stdin ( Stdio :: piped ( ) )
148
+ . spawn ( )
149
+ . expect ( "Failed to spawn `as`." ) ;
150
+ child. stdin . take ( ) . unwrap ( ) . write_all ( global_asm. as_bytes ( ) ) . unwrap ( ) ;
151
+ let status = child. wait ( ) . expect ( "Failed to wait for `as`." ) ;
152
+ if !status. success ( ) {
153
+ return Err ( format ! ( "Failed to assemble `{}`" , global_asm) ) ;
154
+ }
155
+ } else {
156
+ let mut child = Command :: new ( std:: env:: current_exe ( ) . unwrap ( ) )
157
+ . arg ( "--target" )
158
+ . arg ( & config. target )
159
+ . arg ( "--crate-type" )
160
+ . arg ( "staticlib" )
161
+ . arg ( "--emit" )
162
+ . arg ( "obj" )
163
+ . arg ( "-o" )
164
+ . arg ( & global_asm_object_file)
165
+ . arg ( "-" )
166
+ . arg ( "-Abad_asm_style" )
167
+ . arg ( "-Zcodegen-backend=llvm" )
168
+ . stdin ( Stdio :: piped ( ) )
169
+ . spawn ( )
170
+ . expect ( "Failed to spawn `as`." ) ;
171
+ let mut stdin = child. stdin . take ( ) . unwrap ( ) ;
172
+ stdin
173
+ . write_all (
174
+ br####"
175
+ #![feature(decl_macro, no_core, rustc_attrs)]
176
+ #![allow(internal_features)]
177
+ #![no_core]
178
+ #[rustc_builtin_macro]
179
+ #[rustc_macro_transparency = "semitransparent"]
180
+ macro global_asm() { /* compiler built-in */ }
181
+ global_asm!(r###"
182
+ "#### ,
183
+ )
184
+ . unwrap ( ) ;
185
+ stdin. write_all ( global_asm. as_bytes ( ) ) . unwrap ( ) ;
186
+ stdin
187
+ . write_all (
188
+ br####"
189
+ "###);
190
+ "#### ,
191
+ )
192
+ . unwrap ( ) ;
193
+ std:: mem:: drop ( stdin) ;
194
+ let status = child. wait ( ) . expect ( "Failed to wait for `as`." ) ;
195
+ if !status. success ( ) {
196
+ return Err ( format ! ( "Failed to assemble `{}`" , global_asm) ) ;
197
+ }
151
198
}
152
199
153
200
Ok ( Some ( global_asm_object_file) )
0 commit comments