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
@@ -890,6 +890,100 @@ impl<'gcc, 'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
890890 let att_dialect = matches ! ( asm_arch, InlineAsmArch :: X86 | InlineAsmArch :: X86_64 )
891891 && options. contains ( InlineAsmOptions :: ATT_SYNTAX ) ;
892892
893+ // Convert all operands to string interpolations
894+ let converted_operands = operands
895+ . iter ( )
896+ . map ( |operand| {
897+ match * operand {
898+ GlobalAsmOperandRef :: Interpolate { ref string } => {
899+ // Const operands get injected directly into the
900+ // template. Note that we don't need to escape $
901+ // here unlike normal inline assembly.
902+ string. to_owned ( )
903+ }
904+ GlobalAsmOperandRef :: ConstPointer { value, instance } => {
905+ let ( prov, offset) = value. prov_and_relative_offset ( ) ;
906+ let global_alloc = self . tcx . global_alloc ( prov. alloc_id ( ) ) ;
907+ let symbol = ' sym: {
908+ let alloc = match global_alloc {
909+ mir:: interpret:: GlobalAlloc :: Function { instance } => {
910+ let function = get_fn ( self , instance) ;
911+ self . add_used_function ( function) ;
912+ // TODO(@Amanieu): Additional mangling is needed on
913+ // some targets to add a leading underscore (Mach-O)
914+ // or byte count suffixes (x86 Windows).
915+ break ' sym self . tcx . symbol_name ( instance) . name . to_owned ( ) ;
916+ }
917+ mir:: interpret:: GlobalAlloc :: VTable ( ty, dyn_ty) => self
918+ . tcx
919+ . global_alloc ( self . tcx . vtable_allocation ( (
920+ ty,
921+ dyn_ty. principal ( ) . map ( |principal| {
922+ self . tcx
923+ . instantiate_bound_regions_with_erased ( principal)
924+ } ) ,
925+ ) ) )
926+ . unwrap_memory ( ) ,
927+ mir:: interpret:: GlobalAlloc :: Static ( def_id) => {
928+ // TODO(antoyo): set the global variable as used.
929+ // TODO(@Amanieu): Additional mangling is needed on
930+ // some targets to add a leading underscore (Mach-O).
931+ let instance = Instance :: mono ( self . tcx , def_id) ;
932+ break ' sym self . tcx . symbol_name ( instance) . name . to_owned ( ) ;
933+ }
934+ mir:: interpret:: GlobalAlloc :: Memory ( alloc) => alloc,
935+ mir:: interpret:: GlobalAlloc :: TypeId { .. } => {
936+ // This is not an actual allocation, just return the offset.
937+ return format ! ( "{}" , offset. bytes( ) ) ;
938+ }
939+ } ;
940+
941+ // For ZSTs directly codegen an aligned pointer.
942+ if alloc. inner ( ) . len ( ) == 0 {
943+ assert_eq ! ( offset. bytes( ) , 0 ) ;
944+ return format ! ( "{}" , alloc. inner( ) . align. bytes( ) ) ;
945+ }
946+
947+ let sym_name = self . tcx . symbol_name ( instance) . to_string ( ) ;
948+
949+ let init = crate :: consts:: const_alloc_to_gcc_uncached ( self , alloc) ;
950+ let alloc = alloc. inner ( ) ;
951+ let typ = self . val_ty ( init) . get_aligned ( alloc. align . bytes ( ) ) ;
952+
953+ let global = self . declare_global_with_linkage (
954+ & sym_name,
955+ typ,
956+ GlobalKind :: Exported ,
957+ ) ;
958+ global. global_set_initializer_rvalue ( init) ;
959+ // TODO(nbdd0121): set unnamed address.
960+ // TODO(nbdd0121): set the global variable as used.
961+
962+ sym_name
963+ } ;
964+
965+ let offset = offset. bytes ( ) ;
966+ if offset != 0 { format ! ( "{symbol}+{offset}" ) } else { symbol }
967+ }
968+ GlobalAsmOperandRef :: SymFn { instance } => {
969+ let function = get_fn ( self , instance) ;
970+ self . add_used_function ( function) ;
971+ // TODO(@Amanieu): Additional mangling is needed on
972+ // some targets to add a leading underscore (Mach-O)
973+ // or byte count suffixes (x86 Windows).
974+ self . tcx . symbol_name ( instance) . name . to_owned ( )
975+ }
976+ GlobalAsmOperandRef :: SymStatic { def_id } => {
977+ // TODO(antoyo): set the global variable as used.
978+ // TODO(@Amanieu): Additional mangling is needed on
979+ // some targets to add a leading underscore (Mach-O).
980+ let instance = Instance :: mono ( self . tcx , def_id) ;
981+ self . tcx . symbol_name ( instance) . name . to_owned ( )
982+ }
983+ }
984+ } )
985+ . collect :: < Vec < _ > > ( ) ;
986+
893987 // Build the template string
894988 let mut template_str = ".pushsection .text\n " . to_owned ( ) ;
895989 if att_dialect {
@@ -913,33 +1007,7 @@ impl<'gcc, 'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
9131007 }
9141008 }
9151009 InlineAsmTemplatePiece :: Placeholder { operand_idx, modifier : _, span : _ } => {
916- match operands[ operand_idx] {
917- GlobalAsmOperandRef :: Interpolate { ref string } => {
918- // Const operands get injected directly into the
919- // template. Note that we don't need to escape %
920- // here unlike normal inline assembly.
921- template_str. push_str ( string) ;
922- }
923-
924- GlobalAsmOperandRef :: SymFn { instance } => {
925- let function = get_fn ( self , instance) ;
926- self . add_used_function ( function) ;
927- // TODO(@Amanieu): Additional mangling is needed on
928- // some targets to add a leading underscore (Mach-O)
929- // or byte count suffixes (x86 Windows).
930- let name = self . tcx . symbol_name ( instance) . name ;
931- template_str. push_str ( name) ;
932- }
933-
934- GlobalAsmOperandRef :: SymStatic { def_id } => {
935- // TODO(antoyo): set the global variable as used.
936- // TODO(@Amanieu): Additional mangling is needed on
937- // some targets to add a leading underscore (Mach-O).
938- let instance = Instance :: mono ( self . tcx , def_id) ;
939- let name = self . tcx . symbol_name ( instance) . name ;
940- template_str. push_str ( name) ;
941- }
942- }
1010+ template_str. push_str ( & converted_operands[ operand_idx] ) ;
9431011 }
9441012 }
9451013 }
0 commit comments