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
@@ -858,13 +858,106 @@ impl<'gcc, 'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
858858 operands : & [ GlobalAsmOperandRef < ' tcx > ] ,
859859 options : InlineAsmOptions ,
860860 _line_spans : & [ Span ] ,
861+ instance : Instance < ' tcx > ,
861862 ) {
862863 let asm_arch = self . tcx . sess . asm_arch . unwrap ( ) ;
863864
864865 // Default to Intel syntax on x86
865866 let att_dialect = matches ! ( asm_arch, InlineAsmArch :: X86 | InlineAsmArch :: X86_64 )
866867 && options. contains ( InlineAsmOptions :: ATT_SYNTAX ) ;
867868
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+ } ;
913+
914+ // For ZSTs directly codegen an aligned pointer.
915+ if alloc. inner ( ) . len ( ) == 0 {
916+ assert_eq ! ( offset. bytes( ) , 0 ) ;
917+ return format ! ( "{}" , alloc. inner( ) . align. bytes( ) ) ;
918+ }
919+
920+ let asm_name = self . tcx . symbol_name ( instance) ;
921+ let sym_name = format ! ( "{asm_name}.{operand_idx}" ) ;
922+
923+ let init = crate :: consts:: const_alloc_to_gcc_uncached ( self , alloc) ;
924+ let alloc = alloc. inner ( ) ;
925+ let typ = self . val_ty ( init) . get_aligned ( alloc. align . bytes ( ) ) ;
926+
927+ let global = self . declare_global_with_linkage (
928+ & sym_name,
929+ typ,
930+ GlobalKind :: Exported ,
931+ ) ;
932+ global. global_set_initializer_rvalue ( init) ;
933+ // TODO(nbdd0121): set unnamed address.
934+ // TODO(nbdd0121): set the global variable as used.
935+
936+ sym_name
937+ } ;
938+
939+ let offset = offset. bytes ( ) ;
940+ if offset != 0 { format ! ( "{symbol}+{offset}" ) } else { symbol }
941+ }
942+ GlobalAsmOperandRef :: SymFn { instance } => {
943+ let function = get_fn ( self , instance) ;
944+ self . add_used_function ( function) ;
945+ // TODO(@Amanieu): Additional mangling is needed on
946+ // some targets to add a leading underscore (Mach-O)
947+ // or byte count suffixes (x86 Windows).
948+ self . tcx . symbol_name ( instance) . name . to_owned ( )
949+ }
950+ GlobalAsmOperandRef :: SymStatic { def_id } => {
951+ // TODO(antoyo): set the global variable as used.
952+ // TODO(@Amanieu): Additional mangling is needed on
953+ // some targets to add a leading underscore (Mach-O).
954+ let instance = Instance :: mono ( self . tcx , def_id) ;
955+ self . tcx . symbol_name ( instance) . name . to_owned ( )
956+ }
957+ }
958+ } )
959+ . collect :: < Vec < _ > > ( ) ;
960+
868961 // Build the template string
869962 let mut template_str = ".pushsection .text\n " . to_owned ( ) ;
870963 if att_dialect {
@@ -888,33 +981,7 @@ impl<'gcc, 'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
888981 }
889982 }
890983 InlineAsmTemplatePiece :: Placeholder { operand_idx, modifier : _, span : _ } => {
891- match operands[ operand_idx] {
892- GlobalAsmOperandRef :: Interpolate { ref string } => {
893- // Const operands get injected directly into the
894- // template. Note that we don't need to escape %
895- // here unlike normal inline assembly.
896- template_str. push_str ( string) ;
897- }
898-
899- GlobalAsmOperandRef :: SymFn { instance } => {
900- let function = get_fn ( self , instance) ;
901- self . add_used_function ( function) ;
902- // TODO(@Amanieu): Additional mangling is needed on
903- // some targets to add a leading underscore (Mach-O)
904- // or byte count suffixes (x86 Windows).
905- let name = self . tcx . symbol_name ( instance) . name ;
906- template_str. push_str ( name) ;
907- }
908-
909- GlobalAsmOperandRef :: SymStatic { def_id } => {
910- // TODO(antoyo): set the global variable as used.
911- // TODO(@Amanieu): Additional mangling is needed on
912- // some targets to add a leading underscore (Mach-O).
913- let instance = Instance :: mono ( self . tcx , def_id) ;
914- let name = self . tcx . symbol_name ( instance) . name ;
915- template_str. push_str ( name) ;
916- }
917- }
984+ template_str. push_str ( & converted_operands[ operand_idx] ) ;
918985 }
919986 }
920987 }
0 commit comments