Skip to content

Commit 24e8d36

Browse files
committed
Unify handling of asm const and sym fn using CTFE
This gives the asm-const code the basic ability to deal wiht pointer and provenances, which lays the ground work for asm_const_ptr. Note that `SymStatic` is not removed, as it supports `#[thread_local]` statics where CTFE does not.
1 parent 88f7ac0 commit 24e8d36

File tree

9 files changed

+263
-128
lines changed

9 files changed

+263
-128
lines changed

compiler/rustc_codegen_cranelift/src/global_asm.rs

Lines changed: 39 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use std::sync::Arc;
88

99
use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
1010
use rustc_codegen_ssa::traits::{AsmCodegenMethods, GlobalAsmOperandRef};
11+
use rustc_middle::mir::interpret::{GlobalAlloc, Scalar as ConstScalar};
1112
use rustc_middle::ty::TyCtxt;
1213
use rustc_middle::ty::layout::{
1314
FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasTyCtxt, HasTypingEnv, LayoutError, LayoutOfHelpers,
@@ -108,26 +109,45 @@ fn codegen_global_asm_inner<'tcx>(
108109
InlineAsmTemplatePiece::Placeholder { operand_idx, modifier: _, span } => {
109110
match operands[operand_idx] {
110111
GlobalAsmOperandRef::Const { value, ty } => {
111-
let string = rustc_codegen_ssa::common::asm_const_to_str(
112-
tcx,
113-
span,
114-
value,
115-
FullyMonomorphizedLayoutCx(tcx).layout_of(ty),
116-
);
117-
global_asm.push_str(&string);
118-
}
119-
GlobalAsmOperandRef::SymFn { instance } => {
120-
if cfg!(not(feature = "inline_asm_sym")) {
121-
tcx.dcx().span_err(
122-
span,
123-
"asm! and global_asm! sym operands are not yet supported",
124-
);
125-
}
112+
match value {
113+
ConstScalar::Int(int) => {
114+
let string = rustc_codegen_ssa::common::asm_const_to_str(
115+
tcx,
116+
span,
117+
int,
118+
FullyMonomorphizedLayoutCx(tcx).layout_of(ty),
119+
);
120+
global_asm.push_str(&string);
121+
}
126122

127-
let symbol = tcx.symbol_name(instance);
128-
// FIXME handle the case where the function was made private to the
129-
// current codegen unit
130-
global_asm.push_str(symbol.name);
123+
ConstScalar::Ptr(ptr, _) => {
124+
let (prov, offset) = ptr.prov_and_relative_offset();
125+
assert_eq!(offset.bytes(), 0);
126+
let global_alloc = tcx.global_alloc(prov.alloc_id());
127+
let symbol_name = match global_alloc {
128+
GlobalAlloc::Function { instance } => {
129+
if cfg!(not(feature = "inline_asm_sym")) {
130+
tcx.dcx().span_err(
131+
span,
132+
"asm! and global_asm! sym operands are not yet supported",
133+
);
134+
}
135+
136+
// FIXME handle the case where the function was made private to the
137+
// current codegen unit
138+
tcx.symbol_name(instance)
139+
}
140+
GlobalAlloc::Static(def_id) => {
141+
let instance = Instance::mono(tcx, def_id);
142+
tcx.symbol_name(instance)
143+
}
144+
GlobalAlloc::Memory(_)
145+
| GlobalAlloc::VTable(..)
146+
| GlobalAlloc::TypeId { .. } => unreachable!(),
147+
};
148+
global_asm.push_str(symbol_name.name);
149+
}
150+
}
131151
}
132152
GlobalAsmOperandRef::SymStatic { def_id } => {
133153
if cfg!(not(feature = "inline_asm_sym")) {
@@ -136,7 +156,6 @@ fn codegen_global_asm_inner<'tcx>(
136156
"asm! and global_asm! sym operands are not yet supported",
137157
);
138158
}
139-
140159
let instance = Instance::mono(tcx, def_id);
141160
let symbol = tcx.symbol_name(instance);
142161
global_asm.push_str(symbol.name);

compiler/rustc_codegen_cranelift/src/inline_asm.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ pub(crate) fn codegen_inline_asm_terminator<'tcx>(
105105
let value = rustc_codegen_ssa::common::asm_const_to_str(
106106
fx.tcx,
107107
span,
108-
scalar,
108+
scalar.assert_scalar_int(),
109109
fx.layout_of(ty),
110110
);
111111
CInlineAsmOperand::Const { value }

compiler/rustc_codegen_gcc/src/asm.rs

Lines changed: 102 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use rustc_codegen_ssa::traits::{
1111
GlobalAsmOperandRef, InlineAsmOperandRef,
1212
};
1313
use rustc_middle::bug;
14+
use rustc_middle::mir::interpret::{GlobalAlloc, Scalar};
1415
use rustc_middle::ty::Instance;
1516
use rustc_middle::ty::layout::LayoutOf;
1617
use rustc_span::Span;
@@ -309,12 +310,6 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
309310
constants_len += 20;
310311
}
311312

312-
InlineAsmOperandRef::SymFn { instance } => {
313-
// TODO(@Amanieu): Additional mangling is needed on
314-
// some targets to add a leading underscore (Mach-O)
315-
// or byte count suffixes (x86 Windows).
316-
constants_len += self.tcx.symbol_name(instance).name.len();
317-
}
318313
InlineAsmOperandRef::SymStatic { def_id } => {
319314
// TODO(@Amanieu): Additional mangling is needed on
320315
// some targets to add a leading underscore (Mach-O).
@@ -404,24 +399,32 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
404399
// processed in the previous pass
405400
}
406401

407-
InlineAsmOperandRef::SymFn { instance } => {
408-
inputs.push(AsmInOperand {
409-
constraint: "X".into(),
410-
rust_idx,
411-
val: get_fn(self.cx, instance).get_address(None),
412-
});
413-
}
402+
InlineAsmOperandRef::Const { value, ty: _ } => match value {
403+
Scalar::Int(_) => (),
404+
Scalar::Ptr(ptr, _) => {
405+
let (prov, offset) = ptr.prov_and_relative_offset();
406+
assert_eq!(offset.bytes(), 0);
407+
let global_alloc = self.tcx.global_alloc(prov.alloc_id());
408+
let val = match global_alloc {
409+
GlobalAlloc::Function { instance } => {
410+
get_fn(self.cx, instance).get_address(None)
411+
}
412+
GlobalAlloc::Static(def_id) => {
413+
self.cx.get_static(def_id).get_address(None)
414+
}
415+
GlobalAlloc::Memory(_)
416+
| GlobalAlloc::VTable(..)
417+
| GlobalAlloc::TypeId { .. } => unreachable!(),
418+
};
419+
inputs.push(AsmInOperand { constraint: "X".into(), rust_idx, val });
420+
}
421+
},
414422

415423
InlineAsmOperandRef::SymStatic { def_id } => {
416-
inputs.push(AsmInOperand {
417-
constraint: "X".into(),
418-
rust_idx,
419-
val: self.cx.get_static(def_id).get_address(None),
420-
});
421-
}
422-
423-
InlineAsmOperandRef::Const { .. } => {
424-
// processed in the previous pass
424+
// TODO(@Amanieu): Additional mangling is needed on
425+
// some targets to add a leading underscore (MachO).
426+
constants_len +=
427+
self.tcx.symbol_name(Instance::mono(self.tcx, def_id)).name.len();
425428
}
426429

427430
InlineAsmOperandRef::Label { .. } => {
@@ -497,12 +500,43 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
497500
push_to_template(modifier, gcc_index);
498501
}
499502

500-
InlineAsmOperandRef::SymFn { instance } => {
501-
// TODO(@Amanieu): Additional mangling is needed on
502-
// some targets to add a leading underscore (Mach-O)
503-
// or byte count suffixes (x86 Windows).
504-
let name = self.tcx.symbol_name(instance).name;
505-
template_str.push_str(name);
503+
InlineAsmOperandRef::Const { value, ty } => {
504+
match value {
505+
Scalar::Int(int) => {
506+
// Const operands get injected directly into the template
507+
let string = rustc_codegen_ssa::common::asm_const_to_str(
508+
self.tcx,
509+
span,
510+
int,
511+
self.layout_of(ty),
512+
);
513+
template_str.push_str(&string);
514+
}
515+
516+
Scalar::Ptr(ptr, _) => {
517+
let (prov, offset) = ptr.prov_and_relative_offset();
518+
assert_eq!(offset.bytes(), 0);
519+
let global_alloc = self.tcx.global_alloc(prov.alloc_id());
520+
let symbol_name = match global_alloc {
521+
GlobalAlloc::Function { instance } => {
522+
// TODO(@Amanieu): Additional mangling is needed on
523+
// some targets to add a leading underscore (Mach-O)
524+
// or byte count suffixes (x86 Windows).
525+
self.tcx.symbol_name(instance)
526+
}
527+
GlobalAlloc::Static(def_id) => {
528+
// TODO(@Amanieu): Additional mangling is needed on
529+
// some targets to add a leading underscore (Mach-O).
530+
let instance = Instance::mono(self.tcx, def_id);
531+
self.tcx.symbol_name(instance)
532+
}
533+
GlobalAlloc::Memory(_)
534+
| GlobalAlloc::VTable(..)
535+
| GlobalAlloc::TypeId { .. } => unreachable!(),
536+
};
537+
template_str.push_str(symbol_name.name);
538+
}
539+
}
506540
}
507541

508542
InlineAsmOperandRef::SymStatic { def_id } => {
@@ -513,17 +547,6 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
513547
template_str.push_str(name);
514548
}
515549

516-
InlineAsmOperandRef::Const { value, ty } => {
517-
// Const operands get injected directly into the template
518-
let string = rustc_codegen_ssa::common::asm_const_to_str(
519-
self.tcx,
520-
span,
521-
value,
522-
self.layout_of(ty),
523-
);
524-
template_str.push_str(&string);
525-
}
526-
527550
InlineAsmOperandRef::Label { label } => {
528551
let label_gcc_index =
529552
labels.iter().position(|&l| l == label).expect("wrong rust index");
@@ -903,28 +926,48 @@ impl<'gcc, 'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
903926
InlineAsmTemplatePiece::Placeholder { operand_idx, modifier: _, span } => {
904927
match operands[operand_idx] {
905928
GlobalAsmOperandRef::Const { value, ty } => {
906-
// Const operands get injected directly into the
907-
// template. Note that we don't need to escape %
908-
// here unlike normal inline assembly.
909-
let string = rustc_codegen_ssa::common::asm_const_to_str(
910-
self.tcx,
911-
span,
912-
value,
913-
self.layout_of(ty),
914-
);
915-
template_str.push_str(&string);
916-
}
929+
match value {
930+
Scalar::Int(int) => {
931+
// Const operands get injected directly into the
932+
// template. Note that we don't need to escape %
933+
// here unlike normal inline assembly.
934+
let string = rustc_codegen_ssa::common::asm_const_to_str(
935+
self.tcx,
936+
span,
937+
int,
938+
self.layout_of(ty),
939+
);
940+
template_str.push_str(&string);
941+
}
917942

918-
GlobalAsmOperandRef::SymFn { instance } => {
919-
let function = get_fn(self, instance);
920-
self.add_used_function(function);
921-
// TODO(@Amanieu): Additional mangling is needed on
922-
// some targets to add a leading underscore (Mach-O)
923-
// or byte count suffixes (x86 Windows).
924-
let name = self.tcx.symbol_name(instance).name;
925-
template_str.push_str(name);
943+
Scalar::Ptr(ptr, _) => {
944+
let (prov, offset) = ptr.prov_and_relative_offset();
945+
assert_eq!(offset.bytes(), 0);
946+
let global_alloc = self.tcx.global_alloc(prov.alloc_id());
947+
let symbol_name = match global_alloc {
948+
GlobalAlloc::Function { instance } => {
949+
let function = get_fn(self, instance);
950+
self.add_used_function(function);
951+
// TODO(@Amanieu): Additional mangling is needed on
952+
// some targets to add a leading underscore (Mach-O)
953+
// or byte count suffixes (x86 Windows).
954+
self.tcx.symbol_name(instance)
955+
}
956+
GlobalAlloc::Static(def_id) => {
957+
// TODO(antoyo): set the global variable as used.
958+
// TODO(@Amanieu): Additional mangling is needed on
959+
// some targets to add a leading underscore (Mach-O).
960+
let instance = Instance::mono(self.tcx, def_id);
961+
self.tcx.symbol_name(instance)
962+
}
963+
GlobalAlloc::Memory(_)
964+
| GlobalAlloc::VTable(..)
965+
| GlobalAlloc::TypeId { .. } => unreachable!(),
966+
};
967+
template_str.push_str(symbol_name.name);
968+
}
969+
}
926970
}
927-
928971
GlobalAsmOperandRef::SymStatic { def_id } => {
929972
// TODO(antoyo): set the global variable as used.
930973
// TODO(@Amanieu): Additional mangling is needed on

0 commit comments

Comments
 (0)