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