diff options
| author | bors <bors@rust-lang.org> | 2021-05-13 22:17:43 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2021-05-13 22:17:43 +0000 |
| commit | 17f30e5451f581d753899d2f628e5be354df33cd (patch) | |
| tree | 58252137260855f9c5791b84bda1dcdb4d90407b /compiler/rustc_codegen_ssa/src | |
| parent | 6d395a1c2946c79966490f5b1e6e619d3a713e6b (diff) | |
| parent | a7ed6a5196996f00dd78a391a44af51ee8088058 (diff) | |
| download | rust-17f30e5451f581d753899d2f628e5be354df33cd.tar.gz rust-17f30e5451f581d753899d2f628e5be354df33cd.zip | |
Auto merge of #84107 - Amanieu:global_asm2, r=nagisa
Add support for const operands and options to global_asm! On x86, the default syntax is also switched to Intel to match asm!. Currently `global_asm!` only supports `const` operands and the `att_syntax` option. In the future, `sym` operands will also be supported. However there is no plan to support any of the other operand types or options since they don't make sense in the context of `global_asm!`. r? `@nagisa`
Diffstat (limited to 'compiler/rustc_codegen_ssa/src')
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/common.rs | 32 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/mir/block.rs | 34 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/mono_item.rs | 36 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/traits/asm.rs | 15 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/traits/mod.rs | 2 |
5 files changed, 83 insertions, 36 deletions
diff --git a/compiler/rustc_codegen_ssa/src/common.rs b/compiler/rustc_codegen_ssa/src/common.rs index afd83bfcb56..955f658eb1c 100644 --- a/compiler/rustc_codegen_ssa/src/common.rs +++ b/compiler/rustc_codegen_ssa/src/common.rs @@ -4,7 +4,8 @@ use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_hir::LangItem; -use rustc_middle::ty::{Ty, TyCtxt}; +use rustc_middle::mir::interpret::ConstValue; +use rustc_middle::ty::{self, layout::TyAndLayout, Ty, TyCtxt}; use rustc_session::Session; use rustc_span::Span; @@ -194,3 +195,32 @@ pub fn shift_mask_val<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( pub fn span_invalid_monomorphization_error(a: &Session, b: Span, c: &str) { struct_span_err!(a, b, E0511, "{}", c).emit(); } + +pub fn asm_const_to_str<'tcx>( + tcx: TyCtxt<'tcx>, + sp: Span, + const_value: ConstValue<'tcx>, + ty_and_layout: TyAndLayout<'tcx>, +) -> String { + let scalar = match const_value { + ConstValue::Scalar(s) => s, + _ => { + span_bug!(sp, "expected Scalar for promoted asm const, but got {:#?}", const_value) + } + }; + let value = scalar.assert_bits(ty_and_layout.size); + match ty_and_layout.ty.kind() { + ty::Uint(_) => value.to_string(), + ty::Int(int_ty) => match int_ty.normalize(tcx.sess.target.pointer_width) { + ty::IntTy::I8 => (value as i8).to_string(), + ty::IntTy::I16 => (value as i16).to_string(), + ty::IntTy::I32 => (value as i32).to_string(), + ty::IntTy::I64 => (value as i64).to_string(), + ty::IntTy::I128 => (value as i128).to_string(), + ty::IntTy::Isize => unreachable!(), + }, + ty::Float(ty::FloatTy::F32) => f32::from_bits(value as u32).to_string(), + ty::Float(ty::FloatTy::F64) => f64::from_bits(value as u64).to_string(), + _ => span_bug!(sp, "asm const has bad type {}", ty_and_layout.ty), + } +} diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 72e9163b88e..2bd35fe9b14 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -12,7 +12,6 @@ use crate::MemFlags; use rustc_ast as ast; use rustc_hir::lang_items::LangItem; use rustc_index::vec::Idx; -use rustc_middle::mir::interpret::ConstValue; use rustc_middle::mir::AssertKind; use rustc_middle::mir::{self, SwitchTargets}; use rustc_middle::ty::layout::{FnAbiExt, HasTyCtxt}; @@ -825,33 +824,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let const_value = self .eval_mir_constant(value) .unwrap_or_else(|_| span_bug!(span, "asm const cannot be resolved")); - let ty = value.ty(); - let size = bx.layout_of(ty).size; - let scalar = match const_value { - ConstValue::Scalar(s) => s, - _ => span_bug!( - span, - "expected Scalar for promoted asm const, but got {:#?}", - const_value - ), - }; - let value = scalar.assert_bits(size); - let string = match ty.kind() { - ty::Uint(_) => value.to_string(), - ty::Int(int_ty) => { - match int_ty.normalize(bx.tcx().sess.target.pointer_width) { - ty::IntTy::I8 => (value as i8).to_string(), - ty::IntTy::I16 => (value as i16).to_string(), - ty::IntTy::I32 => (value as i32).to_string(), - ty::IntTy::I64 => (value as i64).to_string(), - ty::IntTy::I128 => (value as i128).to_string(), - ty::IntTy::Isize => unreachable!(), - } - } - ty::Float(ty::FloatTy::F32) => f32::from_bits(value as u32).to_string(), - ty::Float(ty::FloatTy::F64) => f64::from_bits(value as u64).to_string(), - _ => span_bug!(span, "asm const has bad type {}", ty), - }; + let string = common::asm_const_to_str( + bx.tcx(), + span, + const_value, + bx.layout_of(value.ty()), + ); InlineAsmOperandRef::Const { string } } mir::InlineAsmOperand::SymFn { ref value } => { diff --git a/compiler/rustc_codegen_ssa/src/mono_item.rs b/compiler/rustc_codegen_ssa/src/mono_item.rs index 8e79193759e..48d753e0d84 100644 --- a/compiler/rustc_codegen_ssa/src/mono_item.rs +++ b/compiler/rustc_codegen_ssa/src/mono_item.rs @@ -1,10 +1,11 @@ use crate::base; +use crate::common; 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::layout::HasTyCtxt; - -use rustc_middle::mir::mono::MonoItem; +use rustc_target::abi::LayoutOf; pub trait MonoItemExt<'a, 'tcx> { fn define<Bx: BuilderMethods<'a, 'tcx>>(&self, cx: &'a Bx::CodegenCx); @@ -32,8 +33,35 @@ impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> { } MonoItem::GlobalAsm(item_id) => { let item = cx.tcx().hir().item(item_id); - if let hir::ItemKind::GlobalAsm(ref ga) = item.kind { - cx.codegen_global_asm(ga); + if let hir::ItemKind::GlobalAsm(ref asm) = item.kind { + let operands: Vec<_> = asm + .operands + .iter() + .map(|(op, op_sp)| match *op { + hir::InlineAsmOperand::Const { ref anon_const } => { + let anon_const_def_id = + cx.tcx().hir().local_def_id(anon_const.hir_id).to_def_id(); + let const_value = + cx.tcx().const_eval_poly(anon_const_def_id).unwrap_or_else( + |_| span_bug!(*op_sp, "asm const cannot be resolved"), + ); + let ty = cx + .tcx() + .typeck_body(anon_const.body) + .node_type(anon_const.hir_id); + let string = common::asm_const_to_str( + cx.tcx(), + *op_sp, + const_value, + cx.layout_of(ty), + ); + GlobalAsmOperandRef::Const { string } + } + _ => span_bug!(*op_sp, "invalid operand type for global_asm!"), + }) + .collect(); + + cx.codegen_global_asm(asm.template, &operands, asm.options, asm.line_spans); } else { span_bug!(item.span, "Mismatch between hir::Item type and MonoItem type") } diff --git a/compiler/rustc_codegen_ssa/src/traits/asm.rs b/compiler/rustc_codegen_ssa/src/traits/asm.rs index 69931935c49..86f2781a766 100644 --- a/compiler/rustc_codegen_ssa/src/traits/asm.rs +++ b/compiler/rustc_codegen_ssa/src/traits/asm.rs @@ -3,7 +3,7 @@ use crate::mir::operand::OperandRef; use crate::mir::place::PlaceRef; use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece}; use rustc_hir::def_id::DefId; -use rustc_hir::{GlobalAsm, LlvmInlineAsmInner}; +use rustc_hir::LlvmInlineAsmInner; use rustc_middle::ty::Instance; use rustc_span::Span; use rustc_target::asm::InlineAsmRegOrRegClass; @@ -36,6 +36,11 @@ pub enum InlineAsmOperandRef<'tcx, B: BackendTypes + ?Sized> { }, } +#[derive(Debug)] +pub enum GlobalAsmOperandRef { + Const { string: String }, +} + pub trait AsmBuilderMethods<'tcx>: BackendTypes { /// Take an inline assembly expression and splat it out via LLVM fn codegen_llvm_inline_asm( @@ -57,5 +62,11 @@ pub trait AsmBuilderMethods<'tcx>: BackendTypes { } pub trait AsmMethods { - fn codegen_global_asm(&self, ga: &GlobalAsm); + fn codegen_global_asm( + &self, + template: &[InlineAsmTemplatePiece], + operands: &[GlobalAsmOperandRef], + 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 be2e0ea230f..c529fbbf518 100644 --- a/compiler/rustc_codegen_ssa/src/traits/mod.rs +++ b/compiler/rustc_codegen_ssa/src/traits/mod.rs @@ -29,7 +29,7 @@ mod type_; mod write; pub use self::abi::AbiBuilderMethods; -pub use self::asm::{AsmBuilderMethods, AsmMethods, InlineAsmOperandRef}; +pub use self::asm::{AsmBuilderMethods, AsmMethods, GlobalAsmOperandRef, InlineAsmOperandRef}; pub use self::backend::{Backend, BackendTypes, CodegenBackend, ExtraBackendMethods}; pub use self::builder::{BuilderMethods, OverflowOp}; pub use self::consts::ConstMethods; |
