diff options
| author | bors <bors@rust-lang.org> | 2022-04-16 04:46:01 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2022-04-16 04:46:01 +0000 |
| commit | 080d5452e1bb6e18e12a073d4d0283fd9b6dac0b (patch) | |
| tree | b7cd51a92bf8665a809ae013ba1d0c0aee2b902f /compiler/rustc_codegen_ssa/src | |
| parent | 27490eb4232ceebc4f5e1e11b529b55994cf0333 (diff) | |
| parent | bdba89733e719e12b8fdd362d4c1e397f7c51436 (diff) | |
| download | rust-080d5452e1bb6e18e12a073d4d0283fd9b6dac0b.tar.gz rust-080d5452e1bb6e18e12a073d4d0283fd9b6dac0b.zip | |
Auto merge of #94468 - Amanieu:global_asm_sym, r=nagisa
Implement sym operands for global_asm! Tracking issue: #93333 This PR is pretty much a complete rewrite of `sym` operand support for inline assembly so that the same implementation can be shared by `asm!` and `global_asm!`. The main changes are: - At the AST level, `sym` is represented as a special `InlineAsmSym` AST node containing a path instead of an `Expr`. - At the HIR level, `sym` is split into `SymStatic` and `SymFn` depending on whether the path resolves to a static during AST lowering (defaults to `SynFn` if `get_early_res` fails). - `SymFn` is just an `AnonConst`. It runs through typeck and we just collect the resulting type at the end. An error is emitted if the type is not a `FnDef`. - `SymStatic` directly holds a path and the `DefId` of the `static` that it is pointing to. - The representation at the MIR level is mostly unchanged. There is a minor change to THIR where `SymFn` is a constant instead of an expression. - At the codegen level we need to apply the target's symbol mangling to the result of `tcx.symbol_name()` depending on the target. This is done by calling the LLVM name mangler, which handles all of the details. - On Mach-O, all symbols have a leading underscore. - On x86 Windows, different mangling is used for cdecl, stdcall, fastcall and vectorcall. - No mangling is needed on other platforms. r? `@nagisa` cc `@eddyb`
Diffstat (limited to 'compiler/rustc_codegen_ssa/src')
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/mono_item.rs | 24 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/traits/asm.rs | 8 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/traits/mod.rs | 4 |
3 files changed, 30 insertions, 6 deletions
diff --git a/compiler/rustc_codegen_ssa/src/mono_item.rs b/compiler/rustc_codegen_ssa/src/mono_item.rs index 5414c619dcb..5006a2157fc 100644 --- a/compiler/rustc_codegen_ssa/src/mono_item.rs +++ b/compiler/rustc_codegen_ssa/src/mono_item.rs @@ -4,7 +4,9 @@ use crate::traits::*; use rustc_hir as hir; use rustc_middle::mir::mono::MonoItem; use rustc_middle::mir::mono::{Linkage, Visibility}; +use rustc_middle::ty; use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf}; +use rustc_middle::ty::Instance; pub trait MonoItemExt<'a, 'tcx> { fn define<Bx: BuilderMethods<'a, 'tcx>>(&self, cx: &'a Bx::CodegenCx); @@ -56,7 +58,27 @@ impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> { ); GlobalAsmOperandRef::Const { string } } - _ => span_bug!(*op_sp, "invalid operand type for global_asm!"), + hir::InlineAsmOperand::SymFn { ref anon_const } => { + let ty = cx + .tcx() + .typeck_body(anon_const.body) + .node_type(anon_const.hir_id); + let instance = match ty.kind() { + &ty::FnDef(def_id, substs) => Instance::new(def_id, substs), + _ => span_bug!(*op_sp, "asm sym is not a function"), + }; + + GlobalAsmOperandRef::SymFn { instance } + } + hir::InlineAsmOperand::SymStatic { path: _, def_id } => { + GlobalAsmOperandRef::SymStatic { def_id } + } + hir::InlineAsmOperand::In { .. } + | hir::InlineAsmOperand::Out { .. } + | hir::InlineAsmOperand::InOut { .. } + | hir::InlineAsmOperand::SplitInOut { .. } => { + span_bug!(*op_sp, "invalid operand type for global_asm!") + } }) .collect(); diff --git a/compiler/rustc_codegen_ssa/src/traits/asm.rs b/compiler/rustc_codegen_ssa/src/traits/asm.rs index 11111a79744..c2ae74b18d8 100644 --- a/compiler/rustc_codegen_ssa/src/traits/asm.rs +++ b/compiler/rustc_codegen_ssa/src/traits/asm.rs @@ -36,8 +36,10 @@ pub enum InlineAsmOperandRef<'tcx, B: BackendTypes + ?Sized> { } #[derive(Debug)] -pub enum GlobalAsmOperandRef { +pub enum GlobalAsmOperandRef<'tcx> { Const { string: String }, + SymFn { instance: Instance<'tcx> }, + SymStatic { def_id: DefId }, } pub trait AsmBuilderMethods<'tcx>: BackendTypes { @@ -53,11 +55,11 @@ pub trait AsmBuilderMethods<'tcx>: BackendTypes { ); } -pub trait AsmMethods { +pub trait AsmMethods<'tcx> { fn codegen_global_asm( &self, template: &[InlineAsmTemplatePiece], - operands: &[GlobalAsmOperandRef], + operands: &[GlobalAsmOperandRef<'tcx>], options: InlineAsmOptions, line_spans: &[Span], ); diff --git a/compiler/rustc_codegen_ssa/src/traits/mod.rs b/compiler/rustc_codegen_ssa/src/traits/mod.rs index c529fbbf518..396768e0a42 100644 --- a/compiler/rustc_codegen_ssa/src/traits/mod.rs +++ b/compiler/rustc_codegen_ssa/src/traits/mod.rs @@ -60,7 +60,7 @@ pub trait CodegenMethods<'tcx>: + StaticMethods + CoverageInfoMethods<'tcx> + DebugInfoMethods<'tcx> - + AsmMethods + + AsmMethods<'tcx> + PreDefineMethods<'tcx> + HasParamEnv<'tcx> + HasTyCtxt<'tcx> @@ -76,7 +76,7 @@ impl<'tcx, T> CodegenMethods<'tcx> for T where + StaticMethods + CoverageInfoMethods<'tcx> + DebugInfoMethods<'tcx> - + AsmMethods + + AsmMethods<'tcx> + PreDefineMethods<'tcx> + HasParamEnv<'tcx> + HasTyCtxt<'tcx> |
