@@ -10,19 +10,21 @@ use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
1010use rustc_data_structures:: profiling:: { get_resident_set_size, print_time_passes_entry} ;
1111use rustc_data_structures:: sync:: par_map;
1212use rustc_data_structures:: unord:: UnordMap ;
13+ use rustc_hir:: ItemId ;
1314use rustc_hir:: def_id:: { DefId , LOCAL_CRATE } ;
1415use rustc_hir:: lang_items:: LangItem ;
1516use rustc_metadata:: EncodedMetadata ;
16- use rustc_middle:: bug;
1717use rustc_middle:: middle:: codegen_fn_attrs:: CodegenFnAttrs ;
1818use rustc_middle:: middle:: debugger_visualizer:: { DebuggerVisualizerFile , DebuggerVisualizerType } ;
1919use rustc_middle:: middle:: exported_symbols:: SymbolExportKind ;
2020use rustc_middle:: middle:: { exported_symbols, lang_items} ;
2121use rustc_middle:: mir:: BinOp ;
22+ use rustc_middle:: mir:: interpret:: ErrorHandled ;
2223use rustc_middle:: mir:: mono:: { CodegenUnit , CodegenUnitNameBuilder , MonoItem , MonoItemPartitions } ;
2324use rustc_middle:: query:: Providers ;
2425use rustc_middle:: ty:: layout:: { HasTyCtxt , HasTypingEnv , LayoutOf , TyAndLayout } ;
2526use rustc_middle:: ty:: { self , Instance , Ty , TyCtxt } ;
27+ use rustc_middle:: { bug, span_bug} ;
2628use rustc_session:: Session ;
2729use rustc_session:: config:: { self , CrateType , EntryFnType , OptLevel , OutputType } ;
2830use rustc_span:: { DUMMY_SP , Symbol , sym} ;
@@ -421,6 +423,69 @@ pub(crate) fn codegen_instance<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>(
421423 mir:: codegen_mir :: < Bx > ( cx, instance) ;
422424}
423425
426+ pub fn codegen_global_asm < ' tcx , Cx > ( cx : & mut Cx , item_id : ItemId )
427+ where
428+ Cx : LayoutOf < ' tcx , LayoutOfResult = TyAndLayout < ' tcx > > + AsmCodegenMethods < ' tcx > ,
429+ {
430+ let item = cx. tcx ( ) . hir ( ) . item ( item_id) ;
431+ if let rustc_hir:: ItemKind :: GlobalAsm ( asm) = item. kind {
432+ let operands: Vec < _ > = asm
433+ . operands
434+ . iter ( )
435+ . map ( |( op, op_sp) | match * op {
436+ rustc_hir:: InlineAsmOperand :: Const { ref anon_const } => {
437+ match cx. tcx ( ) . const_eval_poly ( anon_const. def_id . to_def_id ( ) ) {
438+ Ok ( const_value) => {
439+ let ty =
440+ cx. tcx ( ) . typeck_body ( anon_const. body ) . node_type ( anon_const. hir_id ) ;
441+ let string = common:: asm_const_to_str (
442+ cx. tcx ( ) ,
443+ * op_sp,
444+ const_value,
445+ cx. layout_of ( ty) ,
446+ ) ;
447+ GlobalAsmOperandRef :: Const { string }
448+ }
449+ Err ( ErrorHandled :: Reported { .. } ) => {
450+ // An error has already been reported and
451+ // compilation is guaranteed to fail if execution
452+ // hits this path. So an empty string instead of
453+ // a stringified constant value will suffice.
454+ GlobalAsmOperandRef :: Const { string : String :: new ( ) }
455+ }
456+ Err ( ErrorHandled :: TooGeneric ( _) ) => {
457+ span_bug ! ( * op_sp, "asm const cannot be resolved; too generic" )
458+ }
459+ }
460+ }
461+ rustc_hir:: InlineAsmOperand :: SymFn { ref anon_const } => {
462+ let ty = cx. tcx ( ) . typeck_body ( anon_const. body ) . node_type ( anon_const. hir_id ) ;
463+ let instance = match ty. kind ( ) {
464+ & ty:: FnDef ( def_id, args) => Instance :: new ( def_id, args) ,
465+ _ => span_bug ! ( * op_sp, "asm sym is not a function" ) ,
466+ } ;
467+
468+ GlobalAsmOperandRef :: SymFn { instance }
469+ }
470+ rustc_hir:: InlineAsmOperand :: SymStatic { path : _, def_id } => {
471+ GlobalAsmOperandRef :: SymStatic { def_id }
472+ }
473+ rustc_hir:: InlineAsmOperand :: In { .. }
474+ | rustc_hir:: InlineAsmOperand :: Out { .. }
475+ | rustc_hir:: InlineAsmOperand :: InOut { .. }
476+ | rustc_hir:: InlineAsmOperand :: SplitInOut { .. }
477+ | rustc_hir:: InlineAsmOperand :: Label { .. } => {
478+ span_bug ! ( * op_sp, "invalid operand type for global_asm!" )
479+ }
480+ } )
481+ . collect ( ) ;
482+
483+ cx. codegen_global_asm ( asm. template , & operands, asm. options , asm. line_spans ) ;
484+ } else {
485+ span_bug ! ( item. span, "Mismatch between hir::Item type and MonoItem type" )
486+ }
487+ }
488+
424489/// Creates the `main` function which will initialize the rust runtime and call
425490/// users main function.
426491pub fn maybe_create_entry_wrapper < ' a , ' tcx , Bx : BuilderMethods < ' a , ' tcx > > (
0 commit comments