1
1
use std:: borrow:: Cow ;
2
2
3
- use gccjit:: { LValue , RValue , ToRValue , Type } ;
3
+ use gccjit:: { GlobalKind , LValue , RValue , ToRValue , Type } ;
4
4
use rustc_ast:: ast:: { InlineAsmOptions , InlineAsmTemplatePiece } ;
5
5
use rustc_codegen_ssa:: mir:: operand:: OperandValue ;
6
6
use rustc_codegen_ssa:: mir:: place:: PlaceRef ;
7
7
use rustc_codegen_ssa:: traits:: {
8
8
AsmBuilderMethods , AsmCodegenMethods , BaseTypeCodegenMethods , BuilderMethods ,
9
9
GlobalAsmOperandRef , InlineAsmOperandRef ,
10
10
} ;
11
- use rustc_middle:: bug;
12
11
use rustc_middle:: ty:: Instance ;
12
+ use rustc_middle:: { bug, mir} ;
13
13
use rustc_span:: Span ;
14
14
use rustc_target:: asm:: * ;
15
15
@@ -827,6 +827,98 @@ impl<'gcc, 'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
827
827
let att_dialect = matches ! ( asm_arch, InlineAsmArch :: X86 | InlineAsmArch :: X86_64 )
828
828
&& options. contains ( InlineAsmOptions :: ATT_SYNTAX ) ;
829
829
830
+ // Convert all operands to string interpolations
831
+ let converted_operands = operands
832
+ . iter ( )
833
+ . enumerate ( )
834
+ . map ( |( operand_idx, operand) | {
835
+ match * operand {
836
+ GlobalAsmOperandRef :: Interpolate { ref string } => {
837
+ // Const operands get injected directly into the
838
+ // template. Note that we don't need to escape $
839
+ // here unlike normal inline assembly.
840
+ string. to_owned ( )
841
+ }
842
+ GlobalAsmOperandRef :: ConstPointer { value, instance } => {
843
+ let ( prov, offset) = value. into_parts ( ) ;
844
+ let global_alloc = self . tcx . global_alloc ( prov. alloc_id ( ) ) ;
845
+ let symbol = ' sym: {
846
+ let alloc = match global_alloc {
847
+ mir:: interpret:: GlobalAlloc :: Function { instance } => {
848
+ let function = get_fn ( self , instance) ;
849
+ self . add_used_function ( function) ;
850
+ // TODO(@Amanieu): Additional mangling is needed on
851
+ // some targets to add a leading underscore (Mach-O)
852
+ // or byte count suffixes (x86 Windows).
853
+ break ' sym self . tcx . symbol_name ( instance) . name . to_owned ( ) ;
854
+ }
855
+ mir:: interpret:: GlobalAlloc :: VTable ( ty, dyn_ty) => self
856
+ . tcx
857
+ . global_alloc ( self . tcx . vtable_allocation ( (
858
+ ty,
859
+ dyn_ty. principal ( ) . map ( |principal| {
860
+ self . tcx
861
+ . instantiate_bound_regions_with_erased ( principal)
862
+ } ) ,
863
+ ) ) )
864
+ . unwrap_memory ( ) ,
865
+ mir:: interpret:: GlobalAlloc :: Static ( def_id) => {
866
+ // TODO(antoyo): set the global variable as used.
867
+ // TODO(@Amanieu): Additional mangling is needed on
868
+ // some targets to add a leading underscore (Mach-O).
869
+ let instance = Instance :: mono ( self . tcx , def_id) ;
870
+ break ' sym self . tcx . symbol_name ( instance) . name . to_owned ( ) ;
871
+ }
872
+ mir:: interpret:: GlobalAlloc :: Memory ( alloc) => alloc,
873
+ } ;
874
+
875
+ // For ZSTs directly codegen an aligned pointer.
876
+ if alloc. inner ( ) . len ( ) == 0 {
877
+ assert_eq ! ( offset. bytes( ) , 0 ) ;
878
+ return format ! ( "{}" , alloc. inner( ) . align. bytes( ) ) ;
879
+ }
880
+
881
+ let asm_name = self . tcx . symbol_name ( instance) ;
882
+ let sym_name = format ! ( "{asm_name}.{operand_idx}" ) ;
883
+
884
+ let init = crate :: consts:: const_alloc_to_gcc ( self , alloc) ;
885
+ let alloc = alloc. inner ( ) ;
886
+ let typ = self . val_ty ( init) . get_aligned ( alloc. align . bytes ( ) ) ;
887
+
888
+ let global = self . declare_global_with_linkage (
889
+ & sym_name,
890
+ typ,
891
+ GlobalKind :: Exported ,
892
+ ) ;
893
+ global. global_set_initializer_rvalue ( init) ;
894
+ // TODO(nbdd0121): set unnamed address.
895
+ // TODO(nbdd0121): set the global variable as used.
896
+
897
+ sym_name
898
+ } ;
899
+
900
+ let offset = offset. bytes ( ) ;
901
+ if offset != 0 { format ! ( "{symbol}+{offset}" ) } else { symbol }
902
+ }
903
+ GlobalAsmOperandRef :: SymFn { instance } => {
904
+ let function = get_fn ( self , instance) ;
905
+ self . add_used_function ( function) ;
906
+ // TODO(@Amanieu): Additional mangling is needed on
907
+ // some targets to add a leading underscore (Mach-O)
908
+ // or byte count suffixes (x86 Windows).
909
+ self . tcx . symbol_name ( instance) . name . to_owned ( )
910
+ }
911
+ GlobalAsmOperandRef :: SymStatic { def_id } => {
912
+ // TODO(antoyo): set the global variable as used.
913
+ // TODO(@Amanieu): Additional mangling is needed on
914
+ // some targets to add a leading underscore (Mach-O).
915
+ let instance = Instance :: mono ( self . tcx , def_id) ;
916
+ self . tcx . symbol_name ( instance) . name . to_owned ( )
917
+ }
918
+ }
919
+ } )
920
+ . collect :: < Vec < _ > > ( ) ;
921
+
830
922
// Build the template string
831
923
let mut template_str = ".pushsection .text\n " . to_owned ( ) ;
832
924
if att_dialect {
@@ -850,33 +942,7 @@ impl<'gcc, 'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
850
942
}
851
943
}
852
944
InlineAsmTemplatePiece :: Placeholder { operand_idx, modifier : _, span : _ } => {
853
- match operands[ operand_idx] {
854
- GlobalAsmOperandRef :: Interpolate { ref string } => {
855
- // Const operands get injected directly into the
856
- // template. Note that we don't need to escape %
857
- // here unlike normal inline assembly.
858
- template_str. push_str ( string) ;
859
- }
860
-
861
- GlobalAsmOperandRef :: SymFn { instance } => {
862
- let function = get_fn ( self , instance) ;
863
- self . add_used_function ( function) ;
864
- // TODO(@Amanieu): Additional mangling is needed on
865
- // some targets to add a leading underscore (Mach-O)
866
- // or byte count suffixes (x86 Windows).
867
- let name = self . tcx . symbol_name ( instance) . name ;
868
- template_str. push_str ( name) ;
869
- }
870
-
871
- GlobalAsmOperandRef :: SymStatic { def_id } => {
872
- // TODO(antoyo): set the global variable as used.
873
- // TODO(@Amanieu): Additional mangling is needed on
874
- // some targets to add a leading underscore (Mach-O).
875
- let instance = Instance :: mono ( self . tcx , def_id) ;
876
- let name = self . tcx . symbol_name ( instance) . name ;
877
- template_str. push_str ( name) ;
878
- }
879
- }
945
+ template_str. push_str ( & converted_operands[ operand_idx] ) ;
880
946
}
881
947
}
882
948
}
0 commit comments