-use crate::abi::Size;
use crate::spec::Target;
+use crate::{abi::Size, spec::RelocModel};
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_macros::HashStable_Generic;
use rustc_span::Symbol;
}
}
- pub fn parse(_arch: super::InlineAsmArch, name: rustc_span::Symbol) -> Result<Self, &'static str> {
+ pub fn parse(name: rustc_span::Symbol) -> Result<Self, &'static str> {
match name {
$(
rustc_span::sym::$class => Ok(Self::$class),
}
}
- pub fn parse(
- _arch: super::InlineAsmArch,
- _target_features: &rustc_data_structures::fx::FxHashSet<Symbol>,
- _target: &crate::spec::Target,
- _is_clobber: bool,
- name: &str,
- ) -> Result<Self, &'static str> {
+ pub fn parse(name: &str) -> Result<Self, &'static str> {
match name {
$(
- $($alias)|* | $reg_name => {
- $($filter(_arch, _target_features, _target, _is_clobber)?;)?
- Ok(Self::$reg)
- }
+ $($alias)|* | $reg_name => Ok(Self::$reg),
)*
$(
$($bad_reg)|* => Err($error),
_ => Err("unknown register"),
}
}
+
+ pub fn validate(self,
+ _arch: super::InlineAsmArch,
+ _reloc_model: crate::spec::RelocModel,
+ _target_features: &rustc_data_structures::fx::FxHashSet<Symbol>,
+ _target: &crate::spec::Target,
+ _is_clobber: bool,
+ ) -> Result<(), &'static str> {
+ match self {
+ $(
+ Self::$reg => {
+ $($filter(
+ _arch,
+ _reloc_model,
+ _target_features,
+ _target,
+ _is_clobber
+ )?;)?
+ Ok(())
+ }
+ )*
+ }
+ }
}
pub(super) fn fill_reg_map(
_arch: super::InlineAsmArch,
+ _reloc_model: crate::spec::RelocModel,
_target_features: &rustc_data_structures::fx::FxHashSet<Symbol>,
_target: &crate::spec::Target,
_map: &mut rustc_data_structures::fx::FxHashMap<
#[allow(unused_imports)]
use super::{InlineAsmReg, InlineAsmRegClass};
$(
- if $($filter(_arch, _target_features, _target, false).is_ok() &&)? true {
+ if $($filter(_arch, _reloc_model, _target_features, _target, false).is_ok() &&)? true {
if let Some(set) = _map.get_mut(&InlineAsmRegClass::$arch($arch_regclass::$class)) {
set.insert(InlineAsmReg::$arch($arch_reg::$reg));
}
}
}
- pub fn parse(
- arch: InlineAsmArch,
- target_features: &FxHashSet<Symbol>,
- target: &Target,
- is_clobber: bool,
- name: Symbol,
- ) -> Result<Self, &'static str> {
+ pub fn parse(arch: InlineAsmArch, name: Symbol) -> Result<Self, &'static str> {
// FIXME: use direct symbol comparison for register names
// Use `Symbol::as_str` instead of `Symbol::with` here because `has_feature` may access `Symbol`.
let name = name.as_str();
Ok(match arch {
- InlineAsmArch::X86 | InlineAsmArch::X86_64 => {
- Self::X86(X86InlineAsmReg::parse(arch, target_features, target, is_clobber, name)?)
+ InlineAsmArch::X86 | InlineAsmArch::X86_64 => Self::X86(X86InlineAsmReg::parse(name)?),
+ InlineAsmArch::Arm => Self::Arm(ArmInlineAsmReg::parse(name)?),
+ InlineAsmArch::AArch64 => Self::AArch64(AArch64InlineAsmReg::parse(name)?),
+ InlineAsmArch::RiscV32 | InlineAsmArch::RiscV64 => {
+ Self::RiscV(RiscVInlineAsmReg::parse(name)?)
}
- InlineAsmArch::Arm => {
- Self::Arm(ArmInlineAsmReg::parse(arch, target_features, target, is_clobber, name)?)
+ InlineAsmArch::Nvptx64 => Self::Nvptx(NvptxInlineAsmReg::parse(name)?),
+ InlineAsmArch::PowerPC | InlineAsmArch::PowerPC64 => {
+ Self::PowerPC(PowerPCInlineAsmReg::parse(name)?)
}
- InlineAsmArch::AArch64 => Self::AArch64(AArch64InlineAsmReg::parse(
- arch,
- target_features,
- target,
- is_clobber,
- name,
- )?),
- InlineAsmArch::RiscV32 | InlineAsmArch::RiscV64 => Self::RiscV(
- RiscVInlineAsmReg::parse(arch, target_features, target, is_clobber, name)?,
- ),
- InlineAsmArch::Nvptx64 => Self::Nvptx(NvptxInlineAsmReg::parse(
- arch,
- target_features,
- target,
- is_clobber,
- name,
- )?),
- InlineAsmArch::PowerPC | InlineAsmArch::PowerPC64 => Self::PowerPC(
- PowerPCInlineAsmReg::parse(arch, target_features, target, is_clobber, name)?,
- ),
- InlineAsmArch::Hexagon => Self::Hexagon(HexagonInlineAsmReg::parse(
- arch,
- target_features,
- target,
- is_clobber,
- name,
- )?),
- InlineAsmArch::Mips | InlineAsmArch::Mips64 => Self::Mips(MipsInlineAsmReg::parse(
- arch,
- target_features,
- target,
- is_clobber,
- name,
- )?),
- InlineAsmArch::S390x => Self::S390x(S390xInlineAsmReg::parse(
- arch,
- target_features,
- target,
- is_clobber,
- name,
- )?),
- InlineAsmArch::SpirV => Self::SpirV(SpirVInlineAsmReg::parse(
- arch,
- target_features,
- target,
- is_clobber,
- name,
- )?),
- InlineAsmArch::Wasm32 | InlineAsmArch::Wasm64 => Self::Wasm(WasmInlineAsmReg::parse(
- arch,
- target_features,
- target,
- is_clobber,
- name,
- )?),
- InlineAsmArch::Bpf => {
- Self::Bpf(BpfInlineAsmReg::parse(arch, target_features, target, is_clobber, name)?)
+ InlineAsmArch::Hexagon => Self::Hexagon(HexagonInlineAsmReg::parse(name)?),
+ InlineAsmArch::Mips | InlineAsmArch::Mips64 => {
+ Self::Mips(MipsInlineAsmReg::parse(name)?)
}
- InlineAsmArch::Avr => {
- Self::Avr(AvrInlineAsmReg::parse(arch, target_features, target, is_clobber, name)?)
+ InlineAsmArch::S390x => Self::S390x(S390xInlineAsmReg::parse(name)?),
+ InlineAsmArch::SpirV => Self::SpirV(SpirVInlineAsmReg::parse(name)?),
+ InlineAsmArch::Wasm32 | InlineAsmArch::Wasm64 => {
+ Self::Wasm(WasmInlineAsmReg::parse(name)?)
}
- InlineAsmArch::Msp430 => Self::Msp430(Msp430InlineAsmReg::parse(
- arch,
- target_features,
- target,
- is_clobber,
- name,
- )?),
+ InlineAsmArch::Bpf => Self::Bpf(BpfInlineAsmReg::parse(name)?),
+ InlineAsmArch::Avr => Self::Avr(AvrInlineAsmReg::parse(name)?),
+ InlineAsmArch::Msp430 => Self::Msp430(Msp430InlineAsmReg::parse(name)?),
})
}
+ pub fn validate(
+ self,
+ arch: InlineAsmArch,
+ reloc_model: RelocModel,
+ target_features: &FxHashSet<Symbol>,
+ target: &Target,
+ is_clobber: bool,
+ ) -> Result<(), &'static str> {
+ match self {
+ Self::X86(r) => r.validate(arch, reloc_model, target_features, target, is_clobber),
+ Self::Arm(r) => r.validate(arch, reloc_model, target_features, target, is_clobber),
+ Self::AArch64(r) => r.validate(arch, reloc_model, target_features, target, is_clobber),
+ Self::RiscV(r) => r.validate(arch, reloc_model, target_features, target, is_clobber),
+ Self::PowerPC(r) => r.validate(arch, reloc_model, target_features, target, is_clobber),
+ Self::Hexagon(r) => r.validate(arch, reloc_model, target_features, target, is_clobber),
+ Self::Mips(r) => r.validate(arch, reloc_model, target_features, target, is_clobber),
+ Self::S390x(r) => r.validate(arch, reloc_model, target_features, target, is_clobber),
+ Self::Bpf(r) => r.validate(arch, reloc_model, target_features, target, is_clobber),
+ Self::Avr(r) => r.validate(arch, reloc_model, target_features, target, is_clobber),
+ Self::Msp430(r) => r.validate(arch, reloc_model, target_features, target, is_clobber),
+ Self::Err => unreachable!(),
+ }
+ }
+
// NOTE: This function isn't used at the moment, but is needed to support
// falling back to an external assembler.
pub fn emit(
pub fn parse(arch: InlineAsmArch, name: Symbol) -> Result<Self, &'static str> {
Ok(match arch {
InlineAsmArch::X86 | InlineAsmArch::X86_64 => {
- Self::X86(X86InlineAsmRegClass::parse(arch, name)?)
+ Self::X86(X86InlineAsmRegClass::parse(name)?)
}
- InlineAsmArch::Arm => Self::Arm(ArmInlineAsmRegClass::parse(arch, name)?),
- InlineAsmArch::AArch64 => Self::AArch64(AArch64InlineAsmRegClass::parse(arch, name)?),
+ InlineAsmArch::Arm => Self::Arm(ArmInlineAsmRegClass::parse(name)?),
+ InlineAsmArch::AArch64 => Self::AArch64(AArch64InlineAsmRegClass::parse(name)?),
InlineAsmArch::RiscV32 | InlineAsmArch::RiscV64 => {
- Self::RiscV(RiscVInlineAsmRegClass::parse(arch, name)?)
+ Self::RiscV(RiscVInlineAsmRegClass::parse(name)?)
}
- InlineAsmArch::Nvptx64 => Self::Nvptx(NvptxInlineAsmRegClass::parse(arch, name)?),
+ InlineAsmArch::Nvptx64 => Self::Nvptx(NvptxInlineAsmRegClass::parse(name)?),
InlineAsmArch::PowerPC | InlineAsmArch::PowerPC64 => {
- Self::PowerPC(PowerPCInlineAsmRegClass::parse(arch, name)?)
+ Self::PowerPC(PowerPCInlineAsmRegClass::parse(name)?)
}
- InlineAsmArch::Hexagon => Self::Hexagon(HexagonInlineAsmRegClass::parse(arch, name)?),
+ InlineAsmArch::Hexagon => Self::Hexagon(HexagonInlineAsmRegClass::parse(name)?),
InlineAsmArch::Mips | InlineAsmArch::Mips64 => {
- Self::Mips(MipsInlineAsmRegClass::parse(arch, name)?)
+ Self::Mips(MipsInlineAsmRegClass::parse(name)?)
}
- InlineAsmArch::S390x => Self::S390x(S390xInlineAsmRegClass::parse(arch, name)?),
- InlineAsmArch::SpirV => Self::SpirV(SpirVInlineAsmRegClass::parse(arch, name)?),
+ InlineAsmArch::S390x => Self::S390x(S390xInlineAsmRegClass::parse(name)?),
+ InlineAsmArch::SpirV => Self::SpirV(SpirVInlineAsmRegClass::parse(name)?),
InlineAsmArch::Wasm32 | InlineAsmArch::Wasm64 => {
- Self::Wasm(WasmInlineAsmRegClass::parse(arch, name)?)
+ Self::Wasm(WasmInlineAsmRegClass::parse(name)?)
}
- InlineAsmArch::Bpf => Self::Bpf(BpfInlineAsmRegClass::parse(arch, name)?),
- InlineAsmArch::Avr => Self::Avr(AvrInlineAsmRegClass::parse(arch, name)?),
- InlineAsmArch::Msp430 => Self::Msp430(Msp430InlineAsmRegClass::parse(arch, name)?),
+ InlineAsmArch::Bpf => Self::Bpf(BpfInlineAsmRegClass::parse(name)?),
+ InlineAsmArch::Avr => Self::Avr(AvrInlineAsmRegClass::parse(name)?),
+ InlineAsmArch::Msp430 => Self::Msp430(Msp430InlineAsmRegClass::parse(name)?),
})
}
// falling back to an external assembler.
pub fn allocatable_registers(
arch: InlineAsmArch,
+ reloc_model: RelocModel,
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, target_features, target, &mut map);
+ x86::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
map
}
InlineAsmArch::Arm => {
let mut map = arm::regclass_map();
- arm::fill_reg_map(arch, target_features, target, &mut map);
+ arm::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
map
}
InlineAsmArch::AArch64 => {
let mut map = aarch64::regclass_map();
- aarch64::fill_reg_map(arch, target_features, target, &mut map);
+ aarch64::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
map
}
InlineAsmArch::RiscV32 | InlineAsmArch::RiscV64 => {
let mut map = riscv::regclass_map();
- riscv::fill_reg_map(arch, target_features, target, &mut map);
+ riscv::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
map
}
InlineAsmArch::Nvptx64 => {
let mut map = nvptx::regclass_map();
- nvptx::fill_reg_map(arch, target_features, target, &mut map);
+ nvptx::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
map
}
InlineAsmArch::PowerPC | InlineAsmArch::PowerPC64 => {
let mut map = powerpc::regclass_map();
- powerpc::fill_reg_map(arch, target_features, target, &mut map);
+ powerpc::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
map
}
InlineAsmArch::Hexagon => {
let mut map = hexagon::regclass_map();
- hexagon::fill_reg_map(arch, target_features, target, &mut map);
+ hexagon::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
map
}
InlineAsmArch::Mips | InlineAsmArch::Mips64 => {
let mut map = mips::regclass_map();
- mips::fill_reg_map(arch, target_features, target, &mut map);
+ mips::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
map
}
InlineAsmArch::S390x => {
let mut map = s390x::regclass_map();
- s390x::fill_reg_map(arch, target_features, target, &mut map);
+ s390x::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
map
}
InlineAsmArch::SpirV => {
let mut map = spirv::regclass_map();
- spirv::fill_reg_map(arch, target_features, target, &mut map);
+ spirv::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
map
}
InlineAsmArch::Wasm32 | InlineAsmArch::Wasm64 => {
let mut map = wasm::regclass_map();
- wasm::fill_reg_map(arch, target_features, target, &mut map);
+ wasm::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
map
}
InlineAsmArch::Bpf => {
let mut map = bpf::regclass_map();
- bpf::fill_reg_map(arch, target_features, target, &mut map);
+ bpf::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
map
}
InlineAsmArch::Avr => {
let mut map = avr::regclass_map();
- avr::fill_reg_map(arch, target_features, target, &mut map);
+ avr::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
map
}
InlineAsmArch::Msp430 => {
let mut map = msp430::regclass_map();
- msp430::fill_reg_map(arch, target_features, target, &mut map);
+ msp430::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
map
}
}
/// clobber ABIs for the target.
pub fn parse(
arch: InlineAsmArch,
- target_features: &FxHashSet<Symbol>,
target: &Target,
name: Symbol,
) -> Result<Self, &'static [&'static str]> {
_ => Err(&["C", "system", "efiapi", "aapcs"]),
},
InlineAsmArch::AArch64 => match name {
- "C" | "system" | "efiapi" => {
- Ok(if aarch64::reserved_x18(arch, target_features, target, true).is_err() {
- InlineAsmClobberAbi::AArch64NoX18
- } else {
- InlineAsmClobberAbi::AArch64
- })
- }
+ "C" | "system" | "efiapi" => Ok(if aarch64::target_reserves_x18(target) {
+ InlineAsmClobberAbi::AArch64NoX18
+ } else {
+ InlineAsmClobberAbi::AArch64
+ }),
_ => Err(&["C", "system", "efiapi"]),
},
InlineAsmArch::RiscV32 | InlineAsmArch::RiscV64 => match name {