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
@@ -296,10 +296,18 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
296
296
}
297
297
}
298
298
299
- InlineAsmOperandRef :: Const { ref string } => {
299
+ InlineAsmOperandRef :: Interpolate { ref string } => {
300
300
constants_len += string. len ( ) + att_dialect as usize ;
301
301
}
302
302
303
+ InlineAsmOperandRef :: Const { value } => {
304
+ inputs. push ( AsmInOperand {
305
+ constraint : Cow :: Borrowed ( "i" ) ,
306
+ rust_idx,
307
+ val : value. immediate ( ) ,
308
+ } ) ;
309
+ }
310
+
303
311
InlineAsmOperandRef :: SymFn { instance } => {
304
312
// TODO(@Amanieu): Additional mangling is needed on
305
313
// some targets to add a leading underscore (Mach-O)
@@ -411,6 +419,10 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
411
419
} ) ;
412
420
}
413
421
422
+ InlineAsmOperandRef :: Interpolate { .. } => {
423
+ // processed in the previous pass
424
+ }
425
+
414
426
InlineAsmOperandRef :: Const { .. } => {
415
427
// processed in the previous pass
416
428
}
@@ -488,6 +500,15 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
488
500
push_to_template ( modifier, gcc_index) ;
489
501
}
490
502
503
+ InlineAsmOperandRef :: Const { .. } => {
504
+ let in_gcc_index = inputs
505
+ . iter ( )
506
+ . position ( |op| operand_idx == op. rust_idx )
507
+ . expect ( "wrong rust index" ) ;
508
+ let gcc_index = in_gcc_index + outputs. len ( ) ;
509
+ push_to_template ( None , gcc_index) ;
510
+ }
511
+
491
512
InlineAsmOperandRef :: SymFn { instance } => {
492
513
// TODO(@Amanieu): Additional mangling is needed on
493
514
// some targets to add a leading underscore (Mach-O)
@@ -504,7 +525,7 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
504
525
template_str. push_str ( name) ;
505
526
}
506
527
507
- InlineAsmOperandRef :: Const { ref string } => {
528
+ InlineAsmOperandRef :: Interpolate { ref string } => {
508
529
template_str. push_str ( string) ;
509
530
}
510
531
@@ -837,13 +858,110 @@ impl<'gcc, 'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
837
858
operands : & [ GlobalAsmOperandRef < ' tcx > ] ,
838
859
options : InlineAsmOptions ,
839
860
_line_spans : & [ Span ] ,
861
+ instance : Instance < ' tcx > ,
840
862
) {
841
863
let asm_arch = self . tcx . sess . asm_arch . unwrap ( ) ;
842
864
843
865
// Default to Intel syntax on x86
844
866
let att_dialect = matches ! ( asm_arch, InlineAsmArch :: X86 | InlineAsmArch :: X86_64 )
845
867
&& options. contains ( InlineAsmOptions :: ATT_SYNTAX ) ;
846
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
+ mir:: interpret:: GlobalAlloc :: TypeId { .. } => {
913
+ // This is not an actual allocation, just return the offset.
914
+ return format ! ( "{}" , offset. bytes( ) ) ;
915
+ }
916
+ } ;
917
+
918
+ // For ZSTs directly codegen an aligned pointer.
919
+ if alloc. inner ( ) . len ( ) == 0 {
920
+ assert_eq ! ( offset. bytes( ) , 0 ) ;
921
+ return format ! ( "{}" , alloc. inner( ) . align. bytes( ) ) ;
922
+ }
923
+
924
+ let asm_name = self . tcx . symbol_name ( instance) ;
925
+ let sym_name = format ! ( "{asm_name}.{operand_idx}" ) ;
926
+
927
+ let init = crate :: consts:: const_alloc_to_gcc_uncached ( self , alloc) ;
928
+ let alloc = alloc. inner ( ) ;
929
+ let typ = self . val_ty ( init) . get_aligned ( alloc. align . bytes ( ) ) ;
930
+
931
+ let global = self . declare_global_with_linkage (
932
+ & sym_name,
933
+ typ,
934
+ GlobalKind :: Exported ,
935
+ ) ;
936
+ global. global_set_initializer_rvalue ( init) ;
937
+ // TODO(nbdd0121): set unnamed address.
938
+ // TODO(nbdd0121): set the global variable as used.
939
+
940
+ sym_name
941
+ } ;
942
+
943
+ let offset = offset. bytes ( ) ;
944
+ if offset != 0 { format ! ( "{symbol}+{offset}" ) } else { symbol }
945
+ }
946
+ GlobalAsmOperandRef :: SymFn { instance } => {
947
+ let function = get_fn ( self , instance) ;
948
+ self . add_used_function ( function) ;
949
+ // TODO(@Amanieu): Additional mangling is needed on
950
+ // some targets to add a leading underscore (Mach-O)
951
+ // or byte count suffixes (x86 Windows).
952
+ self . tcx . symbol_name ( instance) . name . to_owned ( )
953
+ }
954
+ GlobalAsmOperandRef :: SymStatic { def_id } => {
955
+ // TODO(antoyo): set the global variable as used.
956
+ // TODO(@Amanieu): Additional mangling is needed on
957
+ // some targets to add a leading underscore (Mach-O).
958
+ let instance = Instance :: mono ( self . tcx , def_id) ;
959
+ self . tcx . symbol_name ( instance) . name . to_owned ( )
960
+ }
961
+ }
962
+ } )
963
+ . collect :: < Vec < _ > > ( ) ;
964
+
847
965
// Build the template string
848
966
let mut template_str = ".pushsection .text\n " . to_owned ( ) ;
849
967
if att_dialect {
@@ -867,33 +985,7 @@ impl<'gcc, 'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
867
985
}
868
986
}
869
987
InlineAsmTemplatePiece :: Placeholder { operand_idx, modifier : _, span : _ } => {
870
- match operands[ operand_idx] {
871
- GlobalAsmOperandRef :: Const { ref string } => {
872
- // Const operands get injected directly into the
873
- // template. Note that we don't need to escape %
874
- // here unlike normal inline assembly.
875
- template_str. push_str ( string) ;
876
- }
877
-
878
- GlobalAsmOperandRef :: SymFn { instance } => {
879
- let function = get_fn ( self , instance) ;
880
- self . add_used_function ( function) ;
881
- // TODO(@Amanieu): Additional mangling is needed on
882
- // some targets to add a leading underscore (Mach-O)
883
- // or byte count suffixes (x86 Windows).
884
- let name = self . tcx . symbol_name ( instance) . name ;
885
- template_str. push_str ( name) ;
886
- }
887
-
888
- GlobalAsmOperandRef :: SymStatic { def_id } => {
889
- // TODO(antoyo): set the global variable as used.
890
- // TODO(@Amanieu): Additional mangling is needed on
891
- // some targets to add a leading underscore (Mach-O).
892
- let instance = Instance :: mono ( self . tcx , def_id) ;
893
- let name = self . tcx . symbol_name ( instance) . name ;
894
- template_str. push_str ( name) ;
895
- }
896
- }
988
+ template_str. push_str ( & converted_operands[ operand_idx] ) ;
897
989
}
898
990
}
899
991
}
0 commit comments