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