@@ -46,6 +46,13 @@ pub(crate) fn codegen_global_asm_item(tcx: TyCtxt<'_>, global_asm: &mut String,
4646 global_asm. push_str ( & string) ;
4747 }
4848 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+
4956 let ty = tcx. typeck_body ( anon_const. body ) . node_type ( anon_const. hir_id ) ;
5057 let instance = match ty. kind ( ) {
5158 & 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,
5764 global_asm. push_str ( symbol. name ) ;
5865 }
5966 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+
6074 let instance = Instance :: mono ( tcx, def_id) . polymorphize ( tcx) ;
6175 let symbol = tcx. symbol_name ( instance) ;
6276 global_asm. push_str ( symbol. name ) ;
@@ -81,22 +95,23 @@ pub(crate) fn codegen_global_asm_item(tcx: TyCtxt<'_>, global_asm: &mut String,
8195 }
8296}
8397
84- pub ( crate ) fn asm_supported ( tcx : TyCtxt < ' _ > ) -> bool {
85- cfg ! ( feature = "inline_asm" ) && !tcx. sess . target . is_like_windows
86- }
87-
8898#[ derive( Debug ) ]
8999pub ( crate ) struct GlobalAsmConfig {
90- asm_enabled : bool ,
91100 assembler : PathBuf ,
101+ target : String ,
92102 pub ( crate ) output_filenames : Arc < OutputFilenames > ,
93103}
94104
95105impl GlobalAsmConfig {
96106 pub ( crate ) fn new ( tcx : TyCtxt < ' _ > ) -> Self {
97107 GlobalAsmConfig {
98- asm_enabled : asm_supported ( tcx) ,
99108 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+ } ,
100115 output_filenames : tcx. output_filenames ( ( ) ) . clone ( ) ,
101116 }
102117 }
@@ -111,21 +126,6 @@ pub(crate) fn compile_global_asm(
111126 return Ok ( None ) ;
112127 }
113128
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-
129129 // Remove all LLVM style comments
130130 let mut global_asm = global_asm
131131 . lines ( )
@@ -134,20 +134,67 @@ pub(crate) fn compile_global_asm(
134134 . join ( "\n " ) ;
135135 global_asm. push ( '\n' ) ;
136136
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+ ) ;
138141
139142 // 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+ }
151198 }
152199
153200 Ok ( Some ( global_asm_object_file) )
0 commit comments