22
33use  std:: borrow:: Cow ; 
44
5- use  gccjit:: { LValue ,  RValue ,  ToRValue ,  Type } ; 
5+ use  gccjit:: { GlobalKind ,   LValue ,  RValue ,  ToRValue ,  Type } ; 
66use  rustc_ast:: ast:: { InlineAsmOptions ,  InlineAsmTemplatePiece } ; 
77use  rustc_codegen_ssa:: mir:: operand:: OperandValue ; 
88use  rustc_codegen_ssa:: mir:: place:: PlaceRef ; 
99use  rustc_codegen_ssa:: traits:: { 
1010    AsmBuilderMethods ,  AsmCodegenMethods ,  BaseTypeCodegenMethods ,  BuilderMethods , 
1111    GlobalAsmOperandRef ,  InlineAsmOperandRef , 
1212} ; 
13- use  rustc_middle:: bug; 
1413use  rustc_middle:: ty:: Instance ; 
14+ use  rustc_middle:: { bug,  mir} ; 
1515use  rustc_span:: Span ; 
1616use  rustc_target:: asm:: * ; 
1717
@@ -296,10 +296,18 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
296296                    } 
297297                } 
298298
299-                 InlineAsmOperandRef :: Const  {  ref  string }  => { 
299+                 InlineAsmOperandRef :: Interpolate  {  ref  string }  => { 
300300                    constants_len += string. len ( )  + att_dialect as  usize ; 
301301                } 
302302
303+                 InlineAsmOperandRef :: Const  {  value }  => { 
304+                     inputs. push ( AsmInOperand  { 
305+                         constraint :  Cow :: Borrowed ( "i" ) , 
306+                         rust_idx, 
307+                         val :  value. immediate ( ) , 
308+                     } ) ; 
309+                 } 
310+ 
303311                InlineAsmOperandRef :: SymFn  {  instance }  => { 
304312                    // TODO(@Amanieu): Additional mangling is needed on 
305313                    // some targets to add a leading underscore (Mach-O) 
@@ -411,6 +419,10 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
411419                    } ) ; 
412420                } 
413421
422+                 InlineAsmOperandRef :: Interpolate  {  .. }  => { 
423+                     // processed in the previous pass 
424+                 } 
425+ 
414426                InlineAsmOperandRef :: Const  {  .. }  => { 
415427                    // processed in the previous pass 
416428                } 
@@ -488,6 +500,15 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
488500                            push_to_template ( modifier,  gcc_index) ; 
489501                        } 
490502
503+                         InlineAsmOperandRef :: Const  {  .. }  => { 
504+                             let  in_gcc_index = inputs
505+                                 . iter ( ) 
506+                                 . position ( |op| operand_idx == op. rust_idx ) 
507+                                 . expect ( "wrong rust index" ) ; 
508+                             let  gcc_index = in_gcc_index + outputs. len ( ) ; 
509+                             push_to_template ( None ,  gcc_index) ; 
510+                         } 
511+ 
491512                        InlineAsmOperandRef :: SymFn  {  instance }  => { 
492513                            // TODO(@Amanieu): Additional mangling is needed on 
493514                            // some targets to add a leading underscore (Mach-O) 
@@ -504,7 +525,7 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
504525                            template_str. push_str ( name) ; 
505526                        } 
506527
507-                         InlineAsmOperandRef :: Const  {  ref  string }  => { 
528+                         InlineAsmOperandRef :: Interpolate  {  ref  string }  => { 
508529                            template_str. push_str ( string) ; 
509530                        } 
510531
@@ -837,13 +858,110 @@ impl<'gcc, 'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
837858        operands :  & [ GlobalAsmOperandRef < ' tcx > ] , 
838859        options :  InlineAsmOptions , 
839860        _line_spans :  & [ Span ] , 
861+         instance :  Instance < ' tcx > , 
840862    )  { 
841863        let  asm_arch = self . tcx . sess . asm_arch . unwrap ( ) ; 
842864
843865        // Default to Intel syntax on x86 
844866        let  att_dialect = matches ! ( asm_arch,  InlineAsmArch :: X86  | InlineAsmArch :: X86_64 ) 
845867            && options. contains ( InlineAsmOptions :: ATT_SYNTAX ) ; 
846868
869+         // Convert all operands to string interpolations 
870+         let  converted_operands = operands
871+             . iter ( ) 
872+             . enumerate ( ) 
873+             . map ( |( operand_idx,  operand) | { 
874+                 match  * operand { 
875+                     GlobalAsmOperandRef :: Interpolate  {  ref  string }  => { 
876+                         // Const operands get injected directly into the 
877+                         // template. Note that we don't need to escape $ 
878+                         // here unlike normal inline assembly. 
879+                         string. to_owned ( ) 
880+                     } 
881+                     GlobalAsmOperandRef :: ConstPointer  {  value }  => { 
882+                         let  ( prov,  offset)  = value. prov_and_relative_offset ( ) ; 
883+                         let  global_alloc = self . tcx . global_alloc ( prov. alloc_id ( ) ) ; 
884+                         let  symbol = ' sym:  { 
885+                             let  alloc = match  global_alloc { 
886+                                 mir:: interpret:: GlobalAlloc :: Function  {  instance }  => { 
887+                                     let  function = get_fn ( self ,  instance) ; 
888+                                     self . add_used_function ( function) ; 
889+                                     // TODO(@Amanieu): Additional mangling is needed on 
890+                                     // some targets to add a leading underscore (Mach-O) 
891+                                     // or byte count suffixes (x86 Windows). 
892+                                     break  ' sym self . tcx . symbol_name ( instance) . name . to_owned ( ) ; 
893+                                 } 
894+                                 mir:: interpret:: GlobalAlloc :: VTable ( ty,  dyn_ty)  => self 
895+                                     . tcx 
896+                                     . global_alloc ( self . tcx . vtable_allocation ( ( 
897+                                         ty, 
898+                                         dyn_ty. principal ( ) . map ( |principal| { 
899+                                             self . tcx 
900+                                                 . instantiate_bound_regions_with_erased ( principal) 
901+                                         } ) , 
902+                                     ) ) ) 
903+                                     . unwrap_memory ( ) , 
904+                                 mir:: interpret:: GlobalAlloc :: Static ( def_id)  => { 
905+                                     // TODO(antoyo): set the global variable as used. 
906+                                     // TODO(@Amanieu): Additional mangling is needed on 
907+                                     // some targets to add a leading underscore (Mach-O). 
908+                                     let  instance = Instance :: mono ( self . tcx ,  def_id) ; 
909+                                     break  ' sym self . tcx . symbol_name ( instance) . name . to_owned ( ) ; 
910+                                 } 
911+                                 mir:: interpret:: GlobalAlloc :: Memory ( alloc)  => alloc, 
912+                                 mir:: interpret:: GlobalAlloc :: TypeId  {  .. }  => { 
913+                                     // This is not an actual allocation, just return the offset. 
914+                                     return  format ! ( "{}" ,  offset. bytes( ) ) ; 
915+                                 } 
916+                             } ; 
917+ 
918+                             // For ZSTs directly codegen an aligned pointer. 
919+                             if  alloc. inner ( ) . len ( )  == 0  { 
920+                                 assert_eq ! ( offset. bytes( ) ,  0 ) ; 
921+                                 return  format ! ( "{}" ,  alloc. inner( ) . align. bytes( ) ) ; 
922+                             } 
923+ 
924+                             let  asm_name = self . tcx . symbol_name ( instance) ; 
925+                             let  sym_name = format ! ( "{asm_name}.{operand_idx}" ) ; 
926+ 
927+                             let  init = crate :: consts:: const_alloc_to_gcc_uncached ( self ,  alloc) ; 
928+                             let  alloc = alloc. inner ( ) ; 
929+                             let  typ = self . val_ty ( init) . get_aligned ( alloc. align . bytes ( ) ) ; 
930+ 
931+                             let  global = self . declare_global_with_linkage ( 
932+                                 & sym_name, 
933+                                 typ, 
934+                                 GlobalKind :: Exported , 
935+                             ) ; 
936+                             global. global_set_initializer_rvalue ( init) ; 
937+                             // TODO(nbdd0121): set unnamed address. 
938+                             // TODO(nbdd0121): set the global variable as used. 
939+ 
940+                             sym_name
941+                         } ; 
942+ 
943+                         let  offset = offset. bytes ( ) ; 
944+                         if  offset != 0  {  format ! ( "{symbol}+{offset}" )  }  else  {  symbol } 
945+                     } 
946+                     GlobalAsmOperandRef :: SymFn  {  instance }  => { 
947+                         let  function = get_fn ( self ,  instance) ; 
948+                         self . add_used_function ( function) ; 
949+                         // TODO(@Amanieu): Additional mangling is needed on 
950+                         // some targets to add a leading underscore (Mach-O) 
951+                         // or byte count suffixes (x86 Windows). 
952+                         self . tcx . symbol_name ( instance) . name . to_owned ( ) 
953+                     } 
954+                     GlobalAsmOperandRef :: SymStatic  {  def_id }  => { 
955+                         // TODO(antoyo): set the global variable as used. 
956+                         // TODO(@Amanieu): Additional mangling is needed on 
957+                         // some targets to add a leading underscore (Mach-O). 
958+                         let  instance = Instance :: mono ( self . tcx ,  def_id) ; 
959+                         self . tcx . symbol_name ( instance) . name . to_owned ( ) 
960+                     } 
961+                 } 
962+             } ) 
963+             . collect :: < Vec < _ > > ( ) ; 
964+ 
847965        // Build the template string 
848966        let  mut  template_str = ".pushsection .text\n " . to_owned ( ) ; 
849967        if  att_dialect { 
@@ -867,33 +985,7 @@ impl<'gcc, 'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
867985                    } 
868986                } 
869987                InlineAsmTemplatePiece :: Placeholder  {  operand_idx,  modifier :  _,  span :  _ }  => { 
870-                     match  operands[ operand_idx]  { 
871-                         GlobalAsmOperandRef :: Const  {  ref  string }  => { 
872-                             // Const operands get injected directly into the 
873-                             // template. Note that we don't need to escape % 
874-                             // here unlike normal inline assembly. 
875-                             template_str. push_str ( string) ; 
876-                         } 
877- 
878-                         GlobalAsmOperandRef :: SymFn  {  instance }  => { 
879-                             let  function = get_fn ( self ,  instance) ; 
880-                             self . add_used_function ( function) ; 
881-                             // TODO(@Amanieu): Additional mangling is needed on 
882-                             // some targets to add a leading underscore (Mach-O) 
883-                             // or byte count suffixes (x86 Windows). 
884-                             let  name = self . tcx . symbol_name ( instance) . name ; 
885-                             template_str. push_str ( name) ; 
886-                         } 
887- 
888-                         GlobalAsmOperandRef :: SymStatic  {  def_id }  => { 
889-                             // TODO(antoyo): set the global variable as used. 
890-                             // TODO(@Amanieu): Additional mangling is needed on 
891-                             // some targets to add a leading underscore (Mach-O). 
892-                             let  instance = Instance :: mono ( self . tcx ,  def_id) ; 
893-                             let  name = self . tcx . symbol_name ( instance) . name ; 
894-                             template_str. push_str ( name) ; 
895-                         } 
896-                     } 
988+                     template_str. push_str ( & converted_operands[ operand_idx] ) ; 
897989                } 
898990            } 
899991        } 
0 commit comments