11use std:: borrow:: Cow ;
22
3- use gccjit:: { LValue , RValue , ToRValue , Type } ;
3+ use gccjit:: { GlobalKind , LValue , RValue , ToRValue , Type } ;
44use rustc_ast:: ast:: { InlineAsmOptions , InlineAsmTemplatePiece } ;
55use rustc_codegen_ssa:: mir:: operand:: OperandValue ;
66use rustc_codegen_ssa:: mir:: place:: PlaceRef ;
77use rustc_codegen_ssa:: traits:: {
88 AsmBuilderMethods , AsmCodegenMethods , BaseTypeCodegenMethods , BuilderMethods ,
99 GlobalAsmOperandRef , InlineAsmOperandRef ,
1010} ;
11- use rustc_middle:: bug;
1211use rustc_middle:: ty:: Instance ;
12+ use rustc_middle:: { bug, mir} ;
1313use rustc_span:: Span ;
1414use rustc_target:: asm:: * ;
1515
@@ -855,13 +855,106 @@ impl<'gcc, 'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
855855 operands : & [ GlobalAsmOperandRef < ' tcx > ] ,
856856 options : InlineAsmOptions ,
857857 _line_spans : & [ Span ] ,
858+ instance : Instance < ' tcx > ,
858859 ) {
859860 let asm_arch = self . tcx . sess . asm_arch . unwrap ( ) ;
860861
861862 // Default to Intel syntax on x86
862863 let att_dialect = matches ! ( asm_arch, InlineAsmArch :: X86 | InlineAsmArch :: X86_64 )
863864 && options. contains ( InlineAsmOptions :: ATT_SYNTAX ) ;
864865
866+ // Convert all operands to string interpolations
867+ let converted_operands = operands
868+ . iter ( )
869+ . enumerate ( )
870+ . map ( |( operand_idx, operand) | {
871+ match * operand {
872+ GlobalAsmOperandRef :: Interpolate { ref string } => {
873+ // Const operands get injected directly into the
874+ // template. Note that we don't need to escape $
875+ // here unlike normal inline assembly.
876+ string. to_owned ( )
877+ }
878+ GlobalAsmOperandRef :: ConstPointer { value } => {
879+ let ( prov, offset) = value. into_parts ( ) ;
880+ let global_alloc = self . tcx . global_alloc ( prov. alloc_id ( ) ) ;
881+ let symbol = ' sym: {
882+ let alloc = match global_alloc {
883+ mir:: interpret:: GlobalAlloc :: Function { instance } => {
884+ let function = get_fn ( self , instance) ;
885+ self . add_used_function ( function) ;
886+ // TODO(@Amanieu): Additional mangling is needed on
887+ // some targets to add a leading underscore (Mach-O)
888+ // or byte count suffixes (x86 Windows).
889+ break ' sym self . tcx . symbol_name ( instance) . name . to_owned ( ) ;
890+ }
891+ mir:: interpret:: GlobalAlloc :: VTable ( ty, dyn_ty) => self
892+ . tcx
893+ . global_alloc ( self . tcx . vtable_allocation ( (
894+ ty,
895+ dyn_ty. principal ( ) . map ( |principal| {
896+ self . tcx
897+ . instantiate_bound_regions_with_erased ( principal)
898+ } ) ,
899+ ) ) )
900+ . unwrap_memory ( ) ,
901+ mir:: interpret:: GlobalAlloc :: Static ( def_id) => {
902+ // TODO(antoyo): set the global variable as used.
903+ // TODO(@Amanieu): Additional mangling is needed on
904+ // some targets to add a leading underscore (Mach-O).
905+ let instance = Instance :: mono ( self . tcx , def_id) ;
906+ break ' sym self . tcx . symbol_name ( instance) . name . to_owned ( ) ;
907+ }
908+ mir:: interpret:: GlobalAlloc :: Memory ( alloc) => alloc,
909+ } ;
910+
911+ // For ZSTs directly codegen an aligned pointer.
912+ if alloc. inner ( ) . len ( ) == 0 {
913+ assert_eq ! ( offset. bytes( ) , 0 ) ;
914+ return format ! ( "{}" , alloc. inner( ) . align. bytes( ) ) ;
915+ }
916+
917+ let asm_name = self . tcx . symbol_name ( instance) ;
918+ let sym_name = format ! ( "{asm_name}.{operand_idx}" ) ;
919+
920+ let init = crate :: consts:: const_alloc_to_gcc ( self , alloc) ;
921+ let alloc = alloc. inner ( ) ;
922+ let typ = self . val_ty ( init) . get_aligned ( alloc. align . bytes ( ) ) ;
923+
924+ let global = self . declare_global_with_linkage (
925+ & sym_name,
926+ typ,
927+ GlobalKind :: Exported ,
928+ ) ;
929+ global. global_set_initializer_rvalue ( init) ;
930+ // TODO(nbdd0121): set unnamed address.
931+ // TODO(nbdd0121): set the global variable as used.
932+
933+ sym_name
934+ } ;
935+
936+ let offset = offset. bytes ( ) ;
937+ if offset != 0 { format ! ( "{symbol}+{offset}" ) } else { symbol }
938+ }
939+ GlobalAsmOperandRef :: SymFn { instance } => {
940+ let function = get_fn ( self , instance) ;
941+ self . add_used_function ( function) ;
942+ // TODO(@Amanieu): Additional mangling is needed on
943+ // some targets to add a leading underscore (Mach-O)
944+ // or byte count suffixes (x86 Windows).
945+ self . tcx . symbol_name ( instance) . name . to_owned ( )
946+ }
947+ GlobalAsmOperandRef :: SymStatic { def_id } => {
948+ // TODO(antoyo): set the global variable as used.
949+ // TODO(@Amanieu): Additional mangling is needed on
950+ // some targets to add a leading underscore (Mach-O).
951+ let instance = Instance :: mono ( self . tcx , def_id) ;
952+ self . tcx . symbol_name ( instance) . name . to_owned ( )
953+ }
954+ }
955+ } )
956+ . collect :: < Vec < _ > > ( ) ;
957+
865958 // Build the template string
866959 let mut template_str = ".pushsection .text\n " . to_owned ( ) ;
867960 if att_dialect {
@@ -885,33 +978,7 @@ impl<'gcc, 'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
885978 }
886979 }
887980 InlineAsmTemplatePiece :: Placeholder { operand_idx, modifier : _, span : _ } => {
888- match operands[ operand_idx] {
889- GlobalAsmOperandRef :: Interpolate { ref string } => {
890- // Const operands get injected directly into the
891- // template. Note that we don't need to escape %
892- // here unlike normal inline assembly.
893- template_str. push_str ( string) ;
894- }
895-
896- GlobalAsmOperandRef :: SymFn { instance } => {
897- let function = get_fn ( self , instance) ;
898- self . add_used_function ( function) ;
899- // TODO(@Amanieu): Additional mangling is needed on
900- // some targets to add a leading underscore (Mach-O)
901- // or byte count suffixes (x86 Windows).
902- let name = self . tcx . symbol_name ( instance) . name ;
903- template_str. push_str ( name) ;
904- }
905-
906- GlobalAsmOperandRef :: SymStatic { def_id } => {
907- // TODO(antoyo): set the global variable as used.
908- // TODO(@Amanieu): Additional mangling is needed on
909- // some targets to add a leading underscore (Mach-O).
910- let instance = Instance :: mono ( self . tcx , def_id) ;
911- let name = self . tcx . symbol_name ( instance) . name ;
912- template_str. push_str ( name) ;
913- }
914- }
981+ template_str. push_str ( & converted_operands[ operand_idx] ) ;
915982 }
916983 }
917984 }
0 commit comments