mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 06:44:35 +00:00
Auto merge of #92731 - bjorn3:asm_support_changes, r=nagisa
Avoid unnecessary monomorphization of inline asm related functions This should reduce build time for codegen backends by avoiding duplicated monomorphization of certain inline asm related functions for each passed in closure type.
This commit is contained in:
commit
9ad5d82f82
@ -6,7 +6,7 @@ use rustc_data_structures::stable_set::FxHashSet;
|
||||
use rustc_errors::struct_span_err;
|
||||
use rustc_hir as hir;
|
||||
use rustc_session::parse::feature_err;
|
||||
use rustc_span::{sym, Span, Symbol};
|
||||
use rustc_span::{sym, Span};
|
||||
use rustc_target::asm;
|
||||
use std::collections::hash_map::Entry;
|
||||
use std::fmt::Write;
|
||||
@ -66,7 +66,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
for (abi_name, abi_span) in &asm.clobber_abis {
|
||||
match asm::InlineAsmClobberAbi::parse(
|
||||
asm_arch,
|
||||
|feature| self.sess.target_features.contains(&Symbol::intern(feature)),
|
||||
&self.sess.target_features,
|
||||
&self.sess.target,
|
||||
*abi_name,
|
||||
) {
|
||||
@ -134,7 +134,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
asm::InlineAsmRegOrRegClass::Reg(if let Some(asm_arch) = asm_arch {
|
||||
asm::InlineAsmReg::parse(
|
||||
asm_arch,
|
||||
|feature| sess.target_features.contains(&Symbol::intern(feature)),
|
||||
&sess.target_features,
|
||||
&sess.target,
|
||||
s,
|
||||
)
|
||||
|
@ -6,7 +6,7 @@ use std::fmt::Write;
|
||||
|
||||
use rustc_ast::ast::{InlineAsmOptions, InlineAsmTemplatePiece};
|
||||
use rustc_middle::mir::InlineAsmOperand;
|
||||
use rustc_span::Symbol;
|
||||
use rustc_span::sym;
|
||||
use rustc_target::asm::*;
|
||||
|
||||
pub(crate) fn codegen_inline_asm<'tcx>(
|
||||
@ -182,11 +182,7 @@ struct InlineAssemblyGenerator<'a, 'tcx> {
|
||||
impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> {
|
||||
fn allocate_registers(&mut self) {
|
||||
let sess = self.tcx.sess;
|
||||
let map = allocatable_registers(
|
||||
self.arch,
|
||||
|feature| sess.target_features.contains(&Symbol::intern(feature)),
|
||||
&sess.target,
|
||||
);
|
||||
let map = allocatable_registers(self.arch, &sess.target_features, &sess.target);
|
||||
let mut allocated = FxHashMap::<_, (bool, bool)>::default();
|
||||
let mut regs = vec![None; self.operands.len()];
|
||||
|
||||
@ -319,9 +315,9 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> {
|
||||
// Allocate stack slots for saving clobbered registers
|
||||
let abi_clobber = InlineAsmClobberAbi::parse(
|
||||
self.arch,
|
||||
|feature| self.tcx.sess.target_features.contains(&Symbol::intern(feature)),
|
||||
&self.tcx.sess.target_features,
|
||||
&self.tcx.sess.target,
|
||||
Symbol::intern("C"),
|
||||
sym::C,
|
||||
)
|
||||
.unwrap()
|
||||
.clobbered_regs();
|
||||
|
@ -5,7 +5,7 @@ use rustc_codegen_ssa::mir::place::PlaceRef;
|
||||
use rustc_codegen_ssa::traits::{AsmBuilderMethods, AsmMethods, BaseTypeMethods, BuilderMethods, GlobalAsmOperandRef, InlineAsmOperandRef};
|
||||
|
||||
use rustc_middle::{bug, ty::Instance};
|
||||
use rustc_span::{Span, Symbol};
|
||||
use rustc_span::Span;
|
||||
use rustc_target::asm::*;
|
||||
|
||||
use std::borrow::Cow;
|
||||
@ -172,7 +172,7 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
|
||||
let is_target_supported = reg.reg_class().supported_types(asm_arch).iter()
|
||||
.any(|&(_, feature)| {
|
||||
if let Some(feature) = feature {
|
||||
self.tcx.sess.target_features.contains(&Symbol::intern(feature))
|
||||
self.tcx.sess.target_features.contains(&feature)
|
||||
} else {
|
||||
true // Register class is unconditionally supported
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ use rustc_codegen_ssa::traits::*;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_middle::ty::layout::TyAndLayout;
|
||||
use rustc_middle::{bug, span_bug, ty::Instance};
|
||||
use rustc_span::{Pos, Span, Symbol};
|
||||
use rustc_span::{Pos, Span};
|
||||
use rustc_target::abi::*;
|
||||
use rustc_target::asm::*;
|
||||
|
||||
@ -45,9 +45,8 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
|
||||
for &(_, feature) in reg_class.supported_types(asm_arch) {
|
||||
if let Some(feature) = feature {
|
||||
let codegen_fn_attrs = self.tcx.codegen_fn_attrs(instance.def_id());
|
||||
let feature_name = Symbol::intern(feature);
|
||||
if self.tcx.sess.target_features.contains(&feature_name)
|
||||
|| codegen_fn_attrs.target_features.contains(&feature_name)
|
||||
if self.tcx.sess.target_features.contains(&feature)
|
||||
|| codegen_fn_attrs.target_features.contains(&feature)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
@ -294,9 +294,8 @@ impl<'tcx> ExprVisitor<'tcx> {
|
||||
// (!). In that case we still need the earlier check to verify that the
|
||||
// register class is usable at all.
|
||||
if let Some(feature) = feature {
|
||||
let feat_sym = Symbol::intern(feature);
|
||||
if !self.tcx.sess.target_features.contains(&feat_sym)
|
||||
&& !target_features.contains(&feat_sym)
|
||||
if !self.tcx.sess.target_features.contains(&feature)
|
||||
&& !target_features.contains(&feature)
|
||||
{
|
||||
let msg = &format!("`{}` target feature is not enabled", feature);
|
||||
let mut err = self.tcx.sess.struct_span_err(expr.span, msg);
|
||||
@ -377,9 +376,8 @@ impl<'tcx> ExprVisitor<'tcx> {
|
||||
{
|
||||
match feature {
|
||||
Some(feature) => {
|
||||
let feat_sym = Symbol::intern(feature);
|
||||
if self.tcx.sess.target_features.contains(&feat_sym)
|
||||
|| attrs.target_features.contains(&feat_sym)
|
||||
if self.tcx.sess.target_features.contains(&feature)
|
||||
|| attrs.target_features.contains(&feature)
|
||||
{
|
||||
missing_required_features.clear();
|
||||
break;
|
||||
@ -413,7 +411,11 @@ impl<'tcx> ExprVisitor<'tcx> {
|
||||
let msg = format!(
|
||||
"register class `{}` requires at least one of the following target features: {}",
|
||||
reg_class.name(),
|
||||
features.join(", ")
|
||||
features
|
||||
.iter()
|
||||
.map(|f| f.as_str())
|
||||
.intersperse(", ")
|
||||
.collect::<String>(),
|
||||
);
|
||||
self.tcx.sess.struct_span_err(*op_sp, &msg).emit();
|
||||
// register isn't enabled, don't do more checks
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
|
||||
#![feature(crate_visibility_modifier)]
|
||||
#![feature(iter_intersperse)]
|
||||
#![feature(let_else)]
|
||||
#![feature(map_try_insert)]
|
||||
#![feature(min_specialization)]
|
||||
|
@ -316,6 +316,7 @@ symbols! {
|
||||
allow_internal_unsafe,
|
||||
allow_internal_unstable,
|
||||
allowed,
|
||||
alu32,
|
||||
always,
|
||||
and,
|
||||
and_then,
|
||||
@ -362,7 +363,10 @@ symbols! {
|
||||
augmented_assignments,
|
||||
auto_traits,
|
||||
automatically_derived,
|
||||
avx,
|
||||
avx512_target_feature,
|
||||
avx512bw,
|
||||
avx512f,
|
||||
await_macro,
|
||||
bang,
|
||||
begin_panic,
|
||||
@ -593,6 +597,7 @@ symbols! {
|
||||
dylib,
|
||||
dyn_metadata,
|
||||
dyn_trait,
|
||||
e,
|
||||
edition_macro_pats,
|
||||
edition_panic,
|
||||
eh_catch_typeinfo,
|
||||
@ -683,6 +688,7 @@ symbols! {
|
||||
format_args_macro,
|
||||
format_args_nl,
|
||||
format_macro,
|
||||
fp,
|
||||
freeze,
|
||||
freg,
|
||||
frem_fast,
|
||||
@ -908,6 +914,7 @@ symbols! {
|
||||
neg,
|
||||
negate_unsigned,
|
||||
negative_impls,
|
||||
neon,
|
||||
never,
|
||||
never_type,
|
||||
never_type_fallback,
|
||||
@ -1102,6 +1109,7 @@ symbols! {
|
||||
repr_packed,
|
||||
repr_simd,
|
||||
repr_transparent,
|
||||
reserved_r9: "reserved-r9",
|
||||
residual,
|
||||
result,
|
||||
rhs,
|
||||
@ -1296,6 +1304,7 @@ symbols! {
|
||||
sqrtf64,
|
||||
sreg,
|
||||
sreg_low16,
|
||||
sse,
|
||||
sse4a_target_feature,
|
||||
stable,
|
||||
staged_api,
|
||||
@ -1362,6 +1371,8 @@ symbols! {
|
||||
thread,
|
||||
thread_local,
|
||||
thread_local_macro,
|
||||
thumb2,
|
||||
thumb_mode: "thumb-mode",
|
||||
todo_macro,
|
||||
tool_attributes,
|
||||
tool_lints,
|
||||
@ -1455,6 +1466,7 @@ symbols! {
|
||||
vec,
|
||||
vec_macro,
|
||||
version,
|
||||
vfp2,
|
||||
vis,
|
||||
visible_private_types,
|
||||
volatile,
|
||||
|
@ -1,6 +1,8 @@
|
||||
use super::{InlineAsmArch, InlineAsmType};
|
||||
use crate::spec::Target;
|
||||
use rustc_data_structures::stable_set::FxHashSet;
|
||||
use rustc_macros::HashStable_Generic;
|
||||
use rustc_span::Symbol;
|
||||
use std::fmt;
|
||||
|
||||
def_reg_class! {
|
||||
@ -58,11 +60,11 @@ impl AArch64InlineAsmRegClass {
|
||||
pub fn supported_types(
|
||||
self,
|
||||
_arch: InlineAsmArch,
|
||||
) -> &'static [(InlineAsmType, Option<&'static str>)] {
|
||||
) -> &'static [(InlineAsmType, Option<Symbol>)] {
|
||||
match self {
|
||||
Self::reg => types! { _: I8, I16, I32, I64, F32, F64; },
|
||||
Self::vreg | Self::vreg_low16 => types! {
|
||||
"fp": I8, I16, I32, I64, F32, F64,
|
||||
fp: I8, I16, I32, I64, F32, F64,
|
||||
VecI8(8), VecI16(4), VecI32(2), VecI64(1), VecF32(2), VecF64(1),
|
||||
VecI8(16), VecI16(8), VecI32(4), VecI64(2), VecF32(4), VecF64(2);
|
||||
},
|
||||
@ -73,7 +75,7 @@ impl AArch64InlineAsmRegClass {
|
||||
|
||||
pub fn reserved_x18(
|
||||
_arch: InlineAsmArch,
|
||||
_has_feature: impl FnMut(&str) -> bool,
|
||||
_target_features: &FxHashSet<Symbol>,
|
||||
target: &Target,
|
||||
) -> Result<(), &'static str> {
|
||||
if target.os == "android"
|
||||
|
@ -1,6 +1,8 @@
|
||||
use super::{InlineAsmArch, InlineAsmType};
|
||||
use crate::spec::Target;
|
||||
use rustc_data_structures::stable_set::FxHashSet;
|
||||
use rustc_macros::HashStable_Generic;
|
||||
use rustc_span::{sym, Symbol};
|
||||
use std::fmt;
|
||||
|
||||
def_reg_class! {
|
||||
@ -44,31 +46,31 @@ impl ArmInlineAsmRegClass {
|
||||
pub fn supported_types(
|
||||
self,
|
||||
_arch: InlineAsmArch,
|
||||
) -> &'static [(InlineAsmType, Option<&'static str>)] {
|
||||
) -> &'static [(InlineAsmType, Option<Symbol>)] {
|
||||
match self {
|
||||
Self::reg => types! { _: I8, I16, I32, F32; },
|
||||
Self::sreg | Self::sreg_low16 => types! { "vfp2": I32, F32; },
|
||||
Self::sreg | Self::sreg_low16 => types! { vfp2: I32, F32; },
|
||||
Self::dreg | Self::dreg_low16 | Self::dreg_low8 => types! {
|
||||
"vfp2": I64, F64, VecI8(8), VecI16(4), VecI32(2), VecI64(1), VecF32(2);
|
||||
vfp2: I64, F64, VecI8(8), VecI16(4), VecI32(2), VecI64(1), VecF32(2);
|
||||
},
|
||||
Self::qreg | Self::qreg_low8 | Self::qreg_low4 => types! {
|
||||
"neon": VecI8(16), VecI16(8), VecI32(4), VecI64(2), VecF32(4);
|
||||
neon: VecI8(16), VecI16(8), VecI32(4), VecI64(2), VecF32(4);
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This uses the same logic as useR7AsFramePointer in LLVM
|
||||
fn frame_pointer_is_r7(mut has_feature: impl FnMut(&str) -> bool, target: &Target) -> bool {
|
||||
target.is_like_osx || (!target.is_like_windows && has_feature("thumb-mode"))
|
||||
fn frame_pointer_is_r7(target_features: &FxHashSet<Symbol>, target: &Target) -> bool {
|
||||
target.is_like_osx || (!target.is_like_windows && target_features.contains(&sym::thumb_mode))
|
||||
}
|
||||
|
||||
fn frame_pointer_r11(
|
||||
_arch: InlineAsmArch,
|
||||
has_feature: impl FnMut(&str) -> bool,
|
||||
target_features: &FxHashSet<Symbol>,
|
||||
target: &Target,
|
||||
) -> Result<(), &'static str> {
|
||||
if !frame_pointer_is_r7(has_feature, target) {
|
||||
if !frame_pointer_is_r7(target_features, target) {
|
||||
Err("the frame pointer (r11) cannot be used as an operand for inline asm")
|
||||
} else {
|
||||
Ok(())
|
||||
@ -77,10 +79,10 @@ fn frame_pointer_r11(
|
||||
|
||||
fn frame_pointer_r7(
|
||||
_arch: InlineAsmArch,
|
||||
has_feature: impl FnMut(&str) -> bool,
|
||||
target_features: &FxHashSet<Symbol>,
|
||||
target: &Target,
|
||||
) -> Result<(), &'static str> {
|
||||
if frame_pointer_is_r7(has_feature, target) {
|
||||
if frame_pointer_is_r7(target_features, target) {
|
||||
Err("the frame pointer (r7) cannot be used as an operand for inline asm")
|
||||
} else {
|
||||
Ok(())
|
||||
@ -89,10 +91,10 @@ fn frame_pointer_r7(
|
||||
|
||||
fn not_thumb1(
|
||||
_arch: InlineAsmArch,
|
||||
mut has_feature: impl FnMut(&str) -> bool,
|
||||
target_features: &FxHashSet<Symbol>,
|
||||
_target: &Target,
|
||||
) -> Result<(), &'static str> {
|
||||
if has_feature("thumb-mode") && !has_feature("thumb2") {
|
||||
if target_features.contains(&sym::thumb_mode) && !target_features.contains(&sym::thumb2) {
|
||||
Err("high registers (r8+) cannot be used in Thumb-1 code")
|
||||
} else {
|
||||
Ok(())
|
||||
@ -101,14 +103,14 @@ fn not_thumb1(
|
||||
|
||||
fn reserved_r9(
|
||||
arch: InlineAsmArch,
|
||||
mut has_feature: impl FnMut(&str) -> bool,
|
||||
target_features: &FxHashSet<Symbol>,
|
||||
target: &Target,
|
||||
) -> Result<(), &'static str> {
|
||||
not_thumb1(arch, &mut has_feature, target)?;
|
||||
not_thumb1(arch, target_features, target)?;
|
||||
|
||||
// We detect this using the reserved-r9 feature instead of using the target
|
||||
// because the relocation model can be changed with compiler options.
|
||||
if has_feature("reserved-r9") {
|
||||
if target_features.contains(&sym::reserved_r9) {
|
||||
Err("the RWPI static base register (r9) cannot be used as an operand for inline asm")
|
||||
} else {
|
||||
Ok(())
|
||||
|
@ -1,5 +1,6 @@
|
||||
use super::{InlineAsmArch, InlineAsmType};
|
||||
use rustc_macros::HashStable_Generic;
|
||||
use rustc_span::Symbol;
|
||||
use std::fmt;
|
||||
|
||||
def_reg_class! {
|
||||
@ -39,7 +40,7 @@ impl AvrInlineAsmRegClass {
|
||||
pub fn supported_types(
|
||||
self,
|
||||
_arch: InlineAsmArch,
|
||||
) -> &'static [(InlineAsmType, Option<&'static str>)] {
|
||||
) -> &'static [(InlineAsmType, Option<Symbol>)] {
|
||||
match self {
|
||||
Self::reg => types! { _: I8; },
|
||||
Self::reg_upper => types! { _: I8; },
|
||||
|
@ -1,5 +1,7 @@
|
||||
use super::{InlineAsmArch, InlineAsmType, Target};
|
||||
use rustc_data_structures::stable_set::FxHashSet;
|
||||
use rustc_macros::HashStable_Generic;
|
||||
use rustc_span::{sym, Symbol};
|
||||
use std::fmt;
|
||||
|
||||
def_reg_class! {
|
||||
@ -33,20 +35,20 @@ impl BpfInlineAsmRegClass {
|
||||
pub fn supported_types(
|
||||
self,
|
||||
_arch: InlineAsmArch,
|
||||
) -> &'static [(InlineAsmType, Option<&'static str>)] {
|
||||
) -> &'static [(InlineAsmType, Option<Symbol>)] {
|
||||
match self {
|
||||
Self::reg => types! { _: I8, I16, I32, I64; },
|
||||
Self::wreg => types! { "alu32": I8, I16, I32; },
|
||||
Self::wreg => types! { alu32: I8, I16, I32; },
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn only_alu32(
|
||||
_arch: InlineAsmArch,
|
||||
mut has_feature: impl FnMut(&str) -> bool,
|
||||
target_features: &FxHashSet<Symbol>,
|
||||
_target: &Target,
|
||||
) -> Result<(), &'static str> {
|
||||
if !has_feature("alu32") {
|
||||
if !target_features.contains(&sym::alu32) {
|
||||
Err("register can't be used without the `alu32` target feature")
|
||||
} else {
|
||||
Ok(())
|
||||
|
@ -1,5 +1,6 @@
|
||||
use super::{InlineAsmArch, InlineAsmType};
|
||||
use rustc_macros::HashStable_Generic;
|
||||
use rustc_span::Symbol;
|
||||
use std::fmt;
|
||||
|
||||
def_reg_class! {
|
||||
@ -32,7 +33,7 @@ impl HexagonInlineAsmRegClass {
|
||||
pub fn supported_types(
|
||||
self,
|
||||
_arch: InlineAsmArch,
|
||||
) -> &'static [(InlineAsmType, Option<&'static str>)] {
|
||||
) -> &'static [(InlineAsmType, Option<Symbol>)] {
|
||||
match self {
|
||||
Self::reg => types! { _: I8, I16, I32, F32; },
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
use super::{InlineAsmArch, InlineAsmType};
|
||||
use rustc_macros::HashStable_Generic;
|
||||
use rustc_span::Symbol;
|
||||
use std::fmt;
|
||||
|
||||
def_reg_class! {
|
||||
@ -33,7 +34,7 @@ impl MipsInlineAsmRegClass {
|
||||
pub fn supported_types(
|
||||
self,
|
||||
arch: InlineAsmArch,
|
||||
) -> &'static [(InlineAsmType, Option<&'static str>)] {
|
||||
) -> &'static [(InlineAsmType, Option<Symbol>)] {
|
||||
match (self, arch) {
|
||||
(Self::reg, InlineAsmArch::Mips64) => types! { _: I8, I16, I32, I64, F32, F64; },
|
||||
(Self::reg, _) => types! { _: I8, I16, I32, F32; },
|
||||
|
@ -81,14 +81,14 @@ macro_rules! def_regs {
|
||||
|
||||
pub fn parse(
|
||||
_arch: super::InlineAsmArch,
|
||||
mut _has_feature: impl FnMut(&str) -> bool,
|
||||
_target_features: &rustc_data_structures::fx::FxHashSet<Symbol>,
|
||||
_target: &crate::spec::Target,
|
||||
name: &str,
|
||||
) -> Result<Self, &'static str> {
|
||||
match name {
|
||||
$(
|
||||
$($alias)|* | $reg_name => {
|
||||
$($filter(_arch, &mut _has_feature, _target)?;)?
|
||||
$($filter(_arch, _target_features, _target)?;)?
|
||||
Ok(Self::$reg)
|
||||
}
|
||||
)*
|
||||
@ -102,7 +102,7 @@ macro_rules! def_regs {
|
||||
|
||||
pub(super) fn fill_reg_map(
|
||||
_arch: super::InlineAsmArch,
|
||||
mut _has_feature: impl FnMut(&str) -> bool,
|
||||
_target_features: &rustc_data_structures::fx::FxHashSet<Symbol>,
|
||||
_target: &crate::spec::Target,
|
||||
_map: &mut rustc_data_structures::fx::FxHashMap<
|
||||
super::InlineAsmRegClass,
|
||||
@ -112,7 +112,7 @@ macro_rules! def_regs {
|
||||
#[allow(unused_imports)]
|
||||
use super::{InlineAsmReg, InlineAsmRegClass};
|
||||
$(
|
||||
if $($filter(_arch, &mut _has_feature, _target).is_ok() &&)? true {
|
||||
if $($filter(_arch, _target_features, _target).is_ok() &&)? true {
|
||||
if let Some(set) = _map.get_mut(&InlineAsmRegClass::$arch($arch_regclass::$class)) {
|
||||
set.insert(InlineAsmReg::$arch($arch_reg::$reg));
|
||||
}
|
||||
@ -130,7 +130,7 @@ macro_rules! def_regs {
|
||||
macro_rules! types {
|
||||
(
|
||||
$(_ : $($ty:expr),+;)?
|
||||
$($feature:literal: $($ty2:expr),+;)*
|
||||
$($feature:ident: $($ty2:expr),+;)*
|
||||
) => {
|
||||
{
|
||||
use super::InlineAsmType::*;
|
||||
@ -139,7 +139,7 @@ macro_rules! types {
|
||||
($ty, None),
|
||||
)*)?
|
||||
$($(
|
||||
($ty2, Some($feature)),
|
||||
($ty2, Some(rustc_span::sym::$feature)),
|
||||
)*)*
|
||||
]
|
||||
}
|
||||
@ -289,7 +289,7 @@ impl InlineAsmReg {
|
||||
|
||||
pub fn parse(
|
||||
arch: InlineAsmArch,
|
||||
has_feature: impl FnMut(&str) -> bool,
|
||||
target_features: &FxHashSet<Symbol>,
|
||||
target: &Target,
|
||||
name: Symbol,
|
||||
) -> Result<Self, &'static str> {
|
||||
@ -298,43 +298,43 @@ impl InlineAsmReg {
|
||||
let name = name.as_str();
|
||||
Ok(match arch {
|
||||
InlineAsmArch::X86 | InlineAsmArch::X86_64 => {
|
||||
Self::X86(X86InlineAsmReg::parse(arch, has_feature, target, name)?)
|
||||
Self::X86(X86InlineAsmReg::parse(arch, target_features, target, name)?)
|
||||
}
|
||||
InlineAsmArch::Arm => {
|
||||
Self::Arm(ArmInlineAsmReg::parse(arch, has_feature, target, name)?)
|
||||
Self::Arm(ArmInlineAsmReg::parse(arch, target_features, target, name)?)
|
||||
}
|
||||
InlineAsmArch::AArch64 => {
|
||||
Self::AArch64(AArch64InlineAsmReg::parse(arch, has_feature, target, name)?)
|
||||
Self::AArch64(AArch64InlineAsmReg::parse(arch, target_features, target, name)?)
|
||||
}
|
||||
InlineAsmArch::RiscV32 | InlineAsmArch::RiscV64 => {
|
||||
Self::RiscV(RiscVInlineAsmReg::parse(arch, has_feature, target, name)?)
|
||||
Self::RiscV(RiscVInlineAsmReg::parse(arch, target_features, target, name)?)
|
||||
}
|
||||
InlineAsmArch::Nvptx64 => {
|
||||
Self::Nvptx(NvptxInlineAsmReg::parse(arch, has_feature, target, name)?)
|
||||
Self::Nvptx(NvptxInlineAsmReg::parse(arch, target_features, target, name)?)
|
||||
}
|
||||
InlineAsmArch::PowerPC | InlineAsmArch::PowerPC64 => {
|
||||
Self::PowerPC(PowerPCInlineAsmReg::parse(arch, has_feature, target, name)?)
|
||||
Self::PowerPC(PowerPCInlineAsmReg::parse(arch, target_features, target, name)?)
|
||||
}
|
||||
InlineAsmArch::Hexagon => {
|
||||
Self::Hexagon(HexagonInlineAsmReg::parse(arch, has_feature, target, name)?)
|
||||
Self::Hexagon(HexagonInlineAsmReg::parse(arch, target_features, target, name)?)
|
||||
}
|
||||
InlineAsmArch::Mips | InlineAsmArch::Mips64 => {
|
||||
Self::Mips(MipsInlineAsmReg::parse(arch, has_feature, target, name)?)
|
||||
Self::Mips(MipsInlineAsmReg::parse(arch, target_features, target, name)?)
|
||||
}
|
||||
InlineAsmArch::S390x => {
|
||||
Self::S390x(S390xInlineAsmReg::parse(arch, has_feature, target, name)?)
|
||||
Self::S390x(S390xInlineAsmReg::parse(arch, target_features, target, name)?)
|
||||
}
|
||||
InlineAsmArch::SpirV => {
|
||||
Self::SpirV(SpirVInlineAsmReg::parse(arch, has_feature, target, name)?)
|
||||
Self::SpirV(SpirVInlineAsmReg::parse(arch, target_features, target, name)?)
|
||||
}
|
||||
InlineAsmArch::Wasm32 | InlineAsmArch::Wasm64 => {
|
||||
Self::Wasm(WasmInlineAsmReg::parse(arch, has_feature, target, name)?)
|
||||
Self::Wasm(WasmInlineAsmReg::parse(arch, target_features, target, name)?)
|
||||
}
|
||||
InlineAsmArch::Bpf => {
|
||||
Self::Bpf(BpfInlineAsmReg::parse(arch, has_feature, target, name)?)
|
||||
Self::Bpf(BpfInlineAsmReg::parse(arch, target_features, target, name)?)
|
||||
}
|
||||
InlineAsmArch::Avr => {
|
||||
Self::Avr(AvrInlineAsmReg::parse(arch, has_feature, target, name)?)
|
||||
Self::Avr(AvrInlineAsmReg::parse(arch, target_features, target, name)?)
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -510,7 +510,7 @@ impl InlineAsmRegClass {
|
||||
pub fn supported_types(
|
||||
self,
|
||||
arch: InlineAsmArch,
|
||||
) -> &'static [(InlineAsmType, Option<&'static str>)] {
|
||||
) -> &'static [(InlineAsmType, Option<Symbol>)] {
|
||||
match self {
|
||||
Self::X86(r) => r.supported_types(arch),
|
||||
Self::Arm(r) => r.supported_types(arch),
|
||||
@ -695,73 +695,73 @@ impl fmt::Display for InlineAsmType {
|
||||
// falling back to an external assembler.
|
||||
pub fn allocatable_registers(
|
||||
arch: InlineAsmArch,
|
||||
has_feature: impl FnMut(&str) -> bool,
|
||||
target_features: &FxHashSet<Symbol>,
|
||||
target: &crate::spec::Target,
|
||||
) -> FxHashMap<InlineAsmRegClass, FxHashSet<InlineAsmReg>> {
|
||||
match arch {
|
||||
InlineAsmArch::X86 | InlineAsmArch::X86_64 => {
|
||||
let mut map = x86::regclass_map();
|
||||
x86::fill_reg_map(arch, has_feature, target, &mut map);
|
||||
x86::fill_reg_map(arch, target_features, target, &mut map);
|
||||
map
|
||||
}
|
||||
InlineAsmArch::Arm => {
|
||||
let mut map = arm::regclass_map();
|
||||
arm::fill_reg_map(arch, has_feature, target, &mut map);
|
||||
arm::fill_reg_map(arch, target_features, target, &mut map);
|
||||
map
|
||||
}
|
||||
InlineAsmArch::AArch64 => {
|
||||
let mut map = aarch64::regclass_map();
|
||||
aarch64::fill_reg_map(arch, has_feature, target, &mut map);
|
||||
aarch64::fill_reg_map(arch, target_features, target, &mut map);
|
||||
map
|
||||
}
|
||||
InlineAsmArch::RiscV32 | InlineAsmArch::RiscV64 => {
|
||||
let mut map = riscv::regclass_map();
|
||||
riscv::fill_reg_map(arch, has_feature, target, &mut map);
|
||||
riscv::fill_reg_map(arch, target_features, target, &mut map);
|
||||
map
|
||||
}
|
||||
InlineAsmArch::Nvptx64 => {
|
||||
let mut map = nvptx::regclass_map();
|
||||
nvptx::fill_reg_map(arch, has_feature, target, &mut map);
|
||||
nvptx::fill_reg_map(arch, target_features, target, &mut map);
|
||||
map
|
||||
}
|
||||
InlineAsmArch::PowerPC | InlineAsmArch::PowerPC64 => {
|
||||
let mut map = powerpc::regclass_map();
|
||||
powerpc::fill_reg_map(arch, has_feature, target, &mut map);
|
||||
powerpc::fill_reg_map(arch, target_features, target, &mut map);
|
||||
map
|
||||
}
|
||||
InlineAsmArch::Hexagon => {
|
||||
let mut map = hexagon::regclass_map();
|
||||
hexagon::fill_reg_map(arch, has_feature, target, &mut map);
|
||||
hexagon::fill_reg_map(arch, target_features, target, &mut map);
|
||||
map
|
||||
}
|
||||
InlineAsmArch::Mips | InlineAsmArch::Mips64 => {
|
||||
let mut map = mips::regclass_map();
|
||||
mips::fill_reg_map(arch, has_feature, target, &mut map);
|
||||
mips::fill_reg_map(arch, target_features, target, &mut map);
|
||||
map
|
||||
}
|
||||
InlineAsmArch::S390x => {
|
||||
let mut map = s390x::regclass_map();
|
||||
s390x::fill_reg_map(arch, has_feature, target, &mut map);
|
||||
s390x::fill_reg_map(arch, target_features, target, &mut map);
|
||||
map
|
||||
}
|
||||
InlineAsmArch::SpirV => {
|
||||
let mut map = spirv::regclass_map();
|
||||
spirv::fill_reg_map(arch, has_feature, target, &mut map);
|
||||
spirv::fill_reg_map(arch, target_features, target, &mut map);
|
||||
map
|
||||
}
|
||||
InlineAsmArch::Wasm32 | InlineAsmArch::Wasm64 => {
|
||||
let mut map = wasm::regclass_map();
|
||||
wasm::fill_reg_map(arch, has_feature, target, &mut map);
|
||||
wasm::fill_reg_map(arch, target_features, target, &mut map);
|
||||
map
|
||||
}
|
||||
InlineAsmArch::Bpf => {
|
||||
let mut map = bpf::regclass_map();
|
||||
bpf::fill_reg_map(arch, has_feature, target, &mut map);
|
||||
bpf::fill_reg_map(arch, target_features, target, &mut map);
|
||||
map
|
||||
}
|
||||
InlineAsmArch::Avr => {
|
||||
let mut map = avr::regclass_map();
|
||||
avr::fill_reg_map(arch, has_feature, target, &mut map);
|
||||
avr::fill_reg_map(arch, target_features, target, &mut map);
|
||||
map
|
||||
}
|
||||
}
|
||||
@ -794,7 +794,7 @@ impl InlineAsmClobberAbi {
|
||||
/// clobber ABIs for the target.
|
||||
pub fn parse(
|
||||
arch: InlineAsmArch,
|
||||
has_feature: impl FnMut(&str) -> bool,
|
||||
target_features: &FxHashSet<Symbol>,
|
||||
target: &Target,
|
||||
name: Symbol,
|
||||
) -> Result<Self, &'static [&'static str]> {
|
||||
@ -819,7 +819,7 @@ impl InlineAsmClobberAbi {
|
||||
},
|
||||
InlineAsmArch::AArch64 => match name {
|
||||
"C" | "system" | "efiapi" => {
|
||||
Ok(if aarch64::reserved_x18(arch, has_feature, target).is_err() {
|
||||
Ok(if aarch64::reserved_x18(arch, target_features, target).is_err() {
|
||||
InlineAsmClobberAbi::AArch64NoX18
|
||||
} else {
|
||||
InlineAsmClobberAbi::AArch64
|
||||
|
@ -1,5 +1,6 @@
|
||||
use super::{InlineAsmArch, InlineAsmType};
|
||||
use rustc_macros::HashStable_Generic;
|
||||
use rustc_span::Symbol;
|
||||
|
||||
def_reg_class! {
|
||||
Nvptx NvptxInlineAsmRegClass {
|
||||
@ -33,7 +34,7 @@ impl NvptxInlineAsmRegClass {
|
||||
pub fn supported_types(
|
||||
self,
|
||||
_arch: InlineAsmArch,
|
||||
) -> &'static [(InlineAsmType, Option<&'static str>)] {
|
||||
) -> &'static [(InlineAsmType, Option<Symbol>)] {
|
||||
match self {
|
||||
Self::reg16 => types! { _: I8, I16; },
|
||||
Self::reg32 => types! { _: I8, I16, I32, F32; },
|
||||
|
@ -1,5 +1,6 @@
|
||||
use super::{InlineAsmArch, InlineAsmType};
|
||||
use rustc_macros::HashStable_Generic;
|
||||
use rustc_span::Symbol;
|
||||
use std::fmt;
|
||||
|
||||
def_reg_class! {
|
||||
@ -36,7 +37,7 @@ impl PowerPCInlineAsmRegClass {
|
||||
pub fn supported_types(
|
||||
self,
|
||||
arch: InlineAsmArch,
|
||||
) -> &'static [(InlineAsmType, Option<&'static str>)] {
|
||||
) -> &'static [(InlineAsmType, Option<Symbol>)] {
|
||||
match self {
|
||||
Self::reg | Self::reg_nonzero => {
|
||||
if arch == InlineAsmArch::PowerPC {
|
||||
|
@ -1,6 +1,8 @@
|
||||
use super::{InlineAsmArch, InlineAsmType};
|
||||
use crate::spec::Target;
|
||||
use rustc_data_structures::stable_set::FxHashSet;
|
||||
use rustc_macros::HashStable_Generic;
|
||||
use rustc_span::{sym, Symbol};
|
||||
use std::fmt;
|
||||
|
||||
def_reg_class! {
|
||||
@ -35,7 +37,7 @@ impl RiscVInlineAsmRegClass {
|
||||
pub fn supported_types(
|
||||
self,
|
||||
arch: InlineAsmArch,
|
||||
) -> &'static [(InlineAsmType, Option<&'static str>)] {
|
||||
) -> &'static [(InlineAsmType, Option<Symbol>)] {
|
||||
match self {
|
||||
Self::reg => {
|
||||
if arch == InlineAsmArch::RiscV64 {
|
||||
@ -44,7 +46,7 @@ impl RiscVInlineAsmRegClass {
|
||||
types! { _: I8, I16, I32, F32; }
|
||||
}
|
||||
}
|
||||
Self::freg => types! { "f": F32; "d": F64; },
|
||||
Self::freg => types! { f: F32; d: F64; },
|
||||
Self::vreg => &[],
|
||||
}
|
||||
}
|
||||
@ -52,10 +54,10 @@ impl RiscVInlineAsmRegClass {
|
||||
|
||||
fn not_e(
|
||||
_arch: InlineAsmArch,
|
||||
mut has_feature: impl FnMut(&str) -> bool,
|
||||
target_features: &FxHashSet<Symbol>,
|
||||
_target: &Target,
|
||||
) -> Result<(), &'static str> {
|
||||
if has_feature("e") {
|
||||
if target_features.contains(&sym::e) {
|
||||
Err("register can't be used with the `e` target feature")
|
||||
} else {
|
||||
Ok(())
|
||||
|
@ -1,5 +1,6 @@
|
||||
use super::{InlineAsmArch, InlineAsmType};
|
||||
use rustc_macros::HashStable_Generic;
|
||||
use rustc_span::Symbol;
|
||||
use std::fmt;
|
||||
|
||||
def_reg_class! {
|
||||
@ -33,7 +34,7 @@ impl S390xInlineAsmRegClass {
|
||||
pub fn supported_types(
|
||||
self,
|
||||
arch: InlineAsmArch,
|
||||
) -> &'static [(InlineAsmType, Option<&'static str>)] {
|
||||
) -> &'static [(InlineAsmType, Option<Symbol>)] {
|
||||
match (self, arch) {
|
||||
(Self::reg, _) => types! { _: I8, I16, I32, I64; },
|
||||
(Self::freg, _) => types! { _: F32, F64; },
|
||||
|
@ -1,5 +1,6 @@
|
||||
use super::{InlineAsmArch, InlineAsmType};
|
||||
use rustc_macros::HashStable_Generic;
|
||||
use rustc_span::Symbol;
|
||||
|
||||
def_reg_class! {
|
||||
SpirV SpirVInlineAsmRegClass {
|
||||
@ -31,7 +32,7 @@ impl SpirVInlineAsmRegClass {
|
||||
pub fn supported_types(
|
||||
self,
|
||||
_arch: InlineAsmArch,
|
||||
) -> &'static [(InlineAsmType, Option<&'static str>)] {
|
||||
) -> &'static [(InlineAsmType, Option<Symbol>)] {
|
||||
match self {
|
||||
Self::reg => {
|
||||
types! { _: I8, I16, I32, I64, F32, F64; }
|
||||
|
@ -1,5 +1,6 @@
|
||||
use super::{InlineAsmArch, InlineAsmType};
|
||||
use rustc_macros::HashStable_Generic;
|
||||
use rustc_span::Symbol;
|
||||
|
||||
def_reg_class! {
|
||||
Wasm WasmInlineAsmRegClass {
|
||||
@ -31,7 +32,7 @@ impl WasmInlineAsmRegClass {
|
||||
pub fn supported_types(
|
||||
self,
|
||||
_arch: InlineAsmArch,
|
||||
) -> &'static [(InlineAsmType, Option<&'static str>)] {
|
||||
) -> &'static [(InlineAsmType, Option<Symbol>)] {
|
||||
match self {
|
||||
Self::local => {
|
||||
types! { _: I8, I16, I32, I64, F32, F64; }
|
||||
|
@ -1,6 +1,8 @@
|
||||
use super::{InlineAsmArch, InlineAsmType};
|
||||
use crate::spec::Target;
|
||||
use rustc_data_structures::stable_set::FxHashSet;
|
||||
use rustc_macros::HashStable_Generic;
|
||||
use rustc_span::Symbol;
|
||||
use std::fmt;
|
||||
|
||||
def_reg_class! {
|
||||
@ -101,7 +103,7 @@ impl X86InlineAsmRegClass {
|
||||
pub fn supported_types(
|
||||
self,
|
||||
arch: InlineAsmArch,
|
||||
) -> &'static [(InlineAsmType, Option<&'static str>)] {
|
||||
) -> &'static [(InlineAsmType, Option<Symbol>)] {
|
||||
match self {
|
||||
Self::reg | Self::reg_abcd => {
|
||||
if arch == InlineAsmArch::X86_64 {
|
||||
@ -112,23 +114,23 @@ impl X86InlineAsmRegClass {
|
||||
}
|
||||
Self::reg_byte => types! { _: I8; },
|
||||
Self::xmm_reg => types! {
|
||||
"sse": I32, I64, F32, F64,
|
||||
sse: I32, I64, F32, F64,
|
||||
VecI8(16), VecI16(8), VecI32(4), VecI64(2), VecF32(4), VecF64(2);
|
||||
},
|
||||
Self::ymm_reg => types! {
|
||||
"avx": I32, I64, F32, F64,
|
||||
avx: I32, I64, F32, F64,
|
||||
VecI8(16), VecI16(8), VecI32(4), VecI64(2), VecF32(4), VecF64(2),
|
||||
VecI8(32), VecI16(16), VecI32(8), VecI64(4), VecF32(8), VecF64(4);
|
||||
},
|
||||
Self::zmm_reg => types! {
|
||||
"avx512f": I32, I64, F32, F64,
|
||||
avx512f: I32, I64, F32, F64,
|
||||
VecI8(16), VecI16(8), VecI32(4), VecI64(2), VecF32(4), VecF64(2),
|
||||
VecI8(32), VecI16(16), VecI32(8), VecI64(4), VecF32(8), VecF64(4),
|
||||
VecI8(64), VecI16(32), VecI32(16), VecI64(8), VecF32(16), VecF64(8);
|
||||
},
|
||||
Self::kreg => types! {
|
||||
"avx512f": I8, I16;
|
||||
"avx512bw": I32, I64;
|
||||
avx512f: I8, I16;
|
||||
avx512bw: I32, I64;
|
||||
},
|
||||
Self::mmx_reg | Self::x87_reg => &[],
|
||||
}
|
||||
@ -137,7 +139,7 @@ impl X86InlineAsmRegClass {
|
||||
|
||||
fn x86_64_only(
|
||||
arch: InlineAsmArch,
|
||||
_has_feature: impl FnMut(&str) -> bool,
|
||||
_target_features: &FxHashSet<Symbol>,
|
||||
_target: &Target,
|
||||
) -> Result<(), &'static str> {
|
||||
match arch {
|
||||
@ -149,7 +151,7 @@ fn x86_64_only(
|
||||
|
||||
fn high_byte(
|
||||
arch: InlineAsmArch,
|
||||
_has_feature: impl FnMut(&str) -> bool,
|
||||
_target_features: &FxHashSet<Symbol>,
|
||||
_target: &Target,
|
||||
) -> Result<(), &'static str> {
|
||||
match arch {
|
||||
@ -160,7 +162,7 @@ fn high_byte(
|
||||
|
||||
fn rbx_reserved(
|
||||
arch: InlineAsmArch,
|
||||
_has_feature: impl FnMut(&str) -> bool,
|
||||
_target_features: &FxHashSet<Symbol>,
|
||||
_target: &Target,
|
||||
) -> Result<(), &'static str> {
|
||||
match arch {
|
||||
@ -174,7 +176,7 @@ fn rbx_reserved(
|
||||
|
||||
fn esi_reserved(
|
||||
arch: InlineAsmArch,
|
||||
_has_feature: impl FnMut(&str) -> bool,
|
||||
_target_features: &FxHashSet<Symbol>,
|
||||
_target: &Target,
|
||||
) -> Result<(), &'static str> {
|
||||
match arch {
|
||||
|
Loading…
Reference in New Issue
Block a user