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
@@ -855,13 +855,106 @@ impl<'gcc, 'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
855
855
operands : & [ GlobalAsmOperandRef < ' tcx > ] ,
856
856
options : InlineAsmOptions ,
857
857
_line_spans : & [ Span ] ,
858
+ instance : Instance < ' tcx > ,
858
859
) {
859
860
let asm_arch = self . tcx . sess . asm_arch . unwrap ( ) ;
860
861
861
862
// Default to Intel syntax on x86
862
863
let att_dialect = matches ! ( asm_arch, InlineAsmArch :: X86 | InlineAsmArch :: X86_64 )
863
864
&& options. contains ( InlineAsmOptions :: ATT_SYNTAX ) ;
864
865
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
+
865
958
// Build the template string
866
959
let mut template_str = ".pushsection .text\n " . to_owned ( ) ;
867
960
if att_dialect {
@@ -885,33 +978,7 @@ impl<'gcc, 'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
885
978
}
886
979
}
887
980
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] ) ;
915
982
}
916
983
}
917
984
}
0 commit comments