2
2
3
3
use std:: borrow:: Cow ;
4
4
5
- use gccjit:: { LValue , RValue , ToRValue , Type } ;
5
+ use gccjit:: { GlobalKind , LValue , RValue , ToRValue , Type } ;
6
6
use rustc_ast:: ast:: { InlineAsmOptions , InlineAsmTemplatePiece } ;
7
7
use rustc_codegen_ssa:: mir:: operand:: OperandValue ;
8
8
use rustc_codegen_ssa:: mir:: place:: PlaceRef ;
9
9
use rustc_codegen_ssa:: traits:: {
10
10
AsmBuilderMethods , AsmCodegenMethods , BaseTypeCodegenMethods , BuilderMethods ,
11
11
GlobalAsmOperandRef , InlineAsmOperandRef ,
12
12
} ;
13
- use rustc_middle:: bug;
14
13
use rustc_middle:: ty:: Instance ;
14
+ use rustc_middle:: { bug, mir} ;
15
15
use rustc_span:: Span ;
16
16
use rustc_target:: asm:: * ;
17
17
@@ -858,13 +858,106 @@ impl<'gcc, 'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
858
858
operands : & [ GlobalAsmOperandRef < ' tcx > ] ,
859
859
options : InlineAsmOptions ,
860
860
_line_spans : & [ Span ] ,
861
+ instance : Instance < ' tcx > ,
861
862
) {
862
863
let asm_arch = self . tcx . sess . asm_arch . unwrap ( ) ;
863
864
864
865
// Default to Intel syntax on x86
865
866
let att_dialect = matches ! ( asm_arch, InlineAsmArch :: X86 | InlineAsmArch :: X86_64 )
866
867
&& options. contains ( InlineAsmOptions :: ATT_SYNTAX ) ;
867
868
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
+
868
961
// Build the template string
869
962
let mut template_str = ".pushsection .text\n " . to_owned ( ) ;
870
963
if att_dialect {
@@ -888,33 +981,7 @@ impl<'gcc, 'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
888
981
}
889
982
}
890
983
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] ) ;
918
985
}
919
986
}
920
987
}
0 commit comments