diff options
Diffstat (limited to 'compiler/rustc_target/src/asm')
| -rw-r--r-- | compiler/rustc_target/src/asm/aarch64.rs | 26 | ||||
| -rw-r--r-- | compiler/rustc_target/src/asm/arm.rs | 78 | ||||
| -rw-r--r-- | compiler/rustc_target/src/asm/avr.rs | 197 | ||||
| -rw-r--r-- | compiler/rustc_target/src/asm/bpf.rs | 10 | ||||
| -rw-r--r-- | compiler/rustc_target/src/asm/hexagon.rs | 3 | ||||
| -rw-r--r-- | compiler/rustc_target/src/asm/mips.rs | 3 | ||||
| -rw-r--r-- | compiler/rustc_target/src/asm/mod.rs | 162 | ||||
| -rw-r--r-- | compiler/rustc_target/src/asm/msp430.rs | 81 | ||||
| -rw-r--r-- | compiler/rustc_target/src/asm/nvptx.rs | 3 | ||||
| -rw-r--r-- | compiler/rustc_target/src/asm/powerpc.rs | 3 | ||||
| -rw-r--r-- | compiler/rustc_target/src/asm/riscv.rs | 10 | ||||
| -rw-r--r-- | compiler/rustc_target/src/asm/s390x.rs | 3 | ||||
| -rw-r--r-- | compiler/rustc_target/src/asm/spirv.rs | 3 | ||||
| -rw-r--r-- | compiler/rustc_target/src/asm/wasm.rs | 3 | ||||
| -rw-r--r-- | compiler/rustc_target/src/asm/x86.rs | 22 |
15 files changed, 512 insertions, 95 deletions
diff --git a/compiler/rustc_target/src/asm/aarch64.rs b/compiler/rustc_target/src/asm/aarch64.rs index 76e50678314..da875508676 100644 --- a/compiler/rustc_target/src/asm/aarch64.rs +++ b/compiler/rustc_target/src/asm/aarch64.rs @@ -1,5 +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! { @@ -57,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); }, @@ -70,6 +73,22 @@ impl AArch64InlineAsmRegClass { } } +pub fn reserved_x18( + _arch: InlineAsmArch, + _target_features: &FxHashSet<Symbol>, + target: &Target, +) -> Result<(), &'static str> { + if target.os == "android" + || target.is_like_fuchsia + || target.is_like_osx + || target.is_like_windows + { + Err("x18 is a reserved register on this target") + } else { + Ok(()) + } +} + def_regs! { AArch64 AArch64InlineAsmReg AArch64InlineAsmRegClass { x0: reg = ["x0", "w0"], @@ -90,6 +109,7 @@ def_regs! { x15: reg = ["x15", "w15"], x16: reg = ["x16", "w16"], x17: reg = ["x17", "w17"], + x18: reg = ["x18", "w18"] % reserved_x18, x20: reg = ["x20", "w20"], x21: reg = ["x21", "w21"], x22: reg = ["x22", "w22"], @@ -149,8 +169,6 @@ def_regs! { p14: preg = ["p14"], p15: preg = ["p15"], ffr: preg = ["ffr"], - #error = ["x18", "w18"] => - "x18 is used as a reserved register on some targets and cannot be used as an operand for inline asm", #error = ["x19", "w19"] => "x19 is used internally by LLVM and cannot be used as an operand for inline asm", #error = ["x29", "w29", "fp", "wfp"] => diff --git a/compiler/rustc_target/src/asm/arm.rs b/compiler/rustc_target/src/asm/arm.rs index 4c323fc35d6..e3615b43c70 100644 --- a/compiler/rustc_target/src/asm/arm.rs +++ b/compiler/rustc_target/src/asm/arm.rs @@ -1,12 +1,13 @@ 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! { Arm ArmInlineAsmRegClass { reg, - reg_thumb, sreg, sreg_low16, dreg, @@ -45,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 | Self::reg_thumb => types! { _: I8, I16, I32, F32; }, - Self::sreg | Self::sreg_low16 => types! { "vfp2": I32, F32; }, + Self::reg => types! { _: I8, I16, 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(()) @@ -78,30 +79,59 @@ 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(()) } } +fn not_thumb1( + _arch: InlineAsmArch, + target_features: &FxHashSet<Symbol>, + _target: &Target, +) -> Result<(), &'static str> { + 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(()) + } +} + +fn reserved_r9( + arch: InlineAsmArch, + target_features: &FxHashSet<Symbol>, + target: &Target, +) -> Result<(), &'static str> { + 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 target_features.contains(&sym::reserved_r9) { + Err("the RWPI static base register (r9) cannot be used as an operand for inline asm") + } else { + Ok(()) + } +} + def_regs! { Arm ArmInlineAsmReg ArmInlineAsmRegClass { - r0: reg, reg_thumb = ["r0", "a1"], - r1: reg, reg_thumb = ["r1", "a2"], - r2: reg, reg_thumb = ["r2", "a3"], - r3: reg, reg_thumb = ["r3", "a4"], - r4: reg, reg_thumb = ["r4", "v1"], - r5: reg, reg_thumb = ["r5", "v2"], - r7: reg, reg_thumb = ["r7", "v4"] % frame_pointer_r7, - r8: reg = ["r8", "v5"], - r10: reg = ["r10", "sl"], + r0: reg = ["r0", "a1"], + r1: reg = ["r1", "a2"], + r2: reg = ["r2", "a3"], + r3: reg = ["r3", "a4"], + r4: reg = ["r4", "v1"], + r5: reg = ["r5", "v2"], + r7: reg = ["r7", "v4"] % frame_pointer_r7, + r8: reg = ["r8", "v5"] % not_thumb1, + r9: reg = ["r9", "v6", "rfp"] % reserved_r9, + r10: reg = ["r10", "sl"] % not_thumb1, r11: reg = ["r11", "fp"] % frame_pointer_r11, - r12: reg = ["r12", "ip"], - r14: reg = ["r14", "lr"], + r12: reg = ["r12", "ip"] % not_thumb1, + r14: reg = ["r14", "lr"] % not_thumb1, s0: sreg, sreg_low16 = ["s0"], s1: sreg, sreg_low16 = ["s1"], s2: sreg, sreg_low16 = ["s2"], @@ -184,8 +214,6 @@ def_regs! { q15: qreg = ["q15"], #error = ["r6", "v3"] => "r6 is used internally by LLVM and cannot be used as an operand for inline asm", - #error = ["r9", "v6", "rfp"] => - "r9 is used internally by LLVM and cannot be used as an operand for inline asm", #error = ["r13", "sp"] => "the stack pointer cannot be used as an operand for inline asm", #error = ["r15", "pc"] => diff --git a/compiler/rustc_target/src/asm/avr.rs b/compiler/rustc_target/src/asm/avr.rs new file mode 100644 index 00000000000..9a96a61f5b2 --- /dev/null +++ b/compiler/rustc_target/src/asm/avr.rs @@ -0,0 +1,197 @@ +use super::{InlineAsmArch, InlineAsmType}; +use rustc_macros::HashStable_Generic; +use rustc_span::Symbol; +use std::fmt; + +def_reg_class! { + Avr AvrInlineAsmRegClass { + reg, + reg_upper, + reg_pair, + reg_iw, + reg_ptr, + } +} + +impl AvrInlineAsmRegClass { + pub fn valid_modifiers(self, _arch: InlineAsmArch) -> &'static [char] { + match self { + Self::reg_pair | Self::reg_iw | Self::reg_ptr => &['h', 'l'], + _ => &[], + } + } + + pub fn suggest_class(self, _arch: InlineAsmArch, _ty: InlineAsmType) -> Option<Self> { + None + } + + pub fn suggest_modifier( + self, + _arch: InlineAsmArch, + _ty: InlineAsmType, + ) -> Option<(char, &'static str)> { + None + } + + pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<(char, &'static str)> { + None + } + + pub fn supported_types( + self, + _arch: InlineAsmArch, + ) -> &'static [(InlineAsmType, Option<Symbol>)] { + match self { + Self::reg => types! { _: I8; }, + Self::reg_upper => types! { _: I8; }, + Self::reg_pair => types! { _: I16; }, + Self::reg_iw => types! { _: I16; }, + Self::reg_ptr => types! { _: I16; }, + } + } +} + +def_regs! { + Avr AvrInlineAsmReg AvrInlineAsmRegClass { + r2: reg = ["r2"], + r3: reg = ["r3"], + r4: reg = ["r4"], + r5: reg = ["r5"], + r6: reg = ["r6"], + r7: reg = ["r7"], + r8: reg = ["r8"], + r9: reg = ["r9"], + r10: reg = ["r10"], + r11: reg = ["r11"], + r12: reg = ["r12"], + r13: reg = ["r13"], + r14: reg = ["r14"], + r15: reg = ["r15"], + r16: reg, reg_upper = ["r16"], + r17: reg, reg_upper = ["r17"], + r18: reg, reg_upper = ["r18"], + r19: reg, reg_upper = ["r19"], + r20: reg, reg_upper = ["r20"], + r21: reg, reg_upper = ["r21"], + r22: reg, reg_upper = ["r22"], + r23: reg, reg_upper = ["r23"], + r24: reg, reg_upper = ["r24"], + r25: reg, reg_upper = ["r25"], + r26: reg, reg_upper = ["r26", "XL"], + r27: reg, reg_upper = ["r27", "XH"], + r30: reg, reg_upper = ["r30", "ZL"], + r31: reg, reg_upper = ["r31", "ZH"], + + r3r2: reg_pair = ["r3r2"], + r5r4: reg_pair = ["r5r4"], + r7r6: reg_pair = ["r7r6"], + r9r8: reg_pair = ["r9r8"], + r11r10: reg_pair = ["r11r10"], + r13r12: reg_pair = ["r13r12"], + r15r14: reg_pair = ["r15r14"], + r17r16: reg_pair = ["r17r16"], + r19r18: reg_pair = ["r19r18"], + r21r20: reg_pair = ["r21r20"], + r23r22: reg_pair = ["r23r22"], + + r25r24: reg_iw, reg_pair = ["r25r24"], + + X: reg_ptr, reg_iw, reg_pair = ["r27r26", "X"], + Z: reg_ptr, reg_iw, reg_pair = ["r31r30", "Z"], + + #error = ["Y", "YL", "YH"] => + "the frame pointer cannot be used as an operand for inline asm", + #error = ["SP", "SPL", "SPH"] => + "the stack pointer cannot be used as an operand for inline asm", + #error = ["r0", "r1", "r1r0"] => + "r0 and r1 are not available due to an issue in LLVM", + } +} + +macro_rules! emit_pairs { + ( + $self:ident $modifier:ident, + $($pair:ident $name:literal $hi:literal $lo:literal,)* + ) => { + match ($self, $modifier) { + $( + (AvrInlineAsmReg::$pair, Some('h')) => $hi, + (AvrInlineAsmReg::$pair, Some('l')) => $lo, + (AvrInlineAsmReg::$pair, _) => $name, + )* + _ => $self.name(), + } + }; +} + +impl AvrInlineAsmReg { + pub fn emit( + self, + out: &mut dyn fmt::Write, + _arch: InlineAsmArch, + modifier: Option<char>, + ) -> fmt::Result { + let name = emit_pairs! { + self modifier, + Z "Z" "ZH" "ZL", + X "X" "XH" "XL", + r25r24 "r25:r24" "r25" "r24", + r23r22 "r23:r22" "r23" "r22", + r21r20 "r21:r20" "r21" "r20", + r19r18 "r19:r18" "r19" "r18", + r17r16 "r17:r16" "r17" "r16", + r15r14 "r15:r14" "r15" "r14", + r13r12 "r13:r12" "r13" "r12", + r11r10 "r11:r10" "r11" "r10", + r9r8 "r9:r8" "r9" "r8", + r7r6 "r7:r6" "r7" "r6", + r5r4 "r5:r4" "r5" "r4", + r3r2 "r3:r2" "r3" "r2", + }; + out.write_str(name) + } + + pub fn overlapping_regs(self, mut cb: impl FnMut(AvrInlineAsmReg)) { + cb(self); + + macro_rules! reg_conflicts { + ( + $( + $pair:ident : $hi:ident $lo:ident, + )* + ) => { + match self { + $( + Self::$pair => { + cb(Self::$hi); + cb(Self::$lo); + } + Self::$hi => { + cb(Self::$pair); + } + Self::$lo => { + cb(Self::$pair); + } + )* + } + }; + } + + reg_conflicts! { + Z : r31 r30, + X : r27 r26, + r25r24 : r25 r24, + r23r22 : r23 r22, + r21r20 : r21 r20, + r19r18 : r19 r18, + r17r16 : r17 r16, + r15r14 : r15 r14, + r13r12 : r13 r12, + r11r10 : r11 r10, + r9r8 : r9 r8, + r7r6 : r7 r6, + r5r4 : r5 r4, + r3r2 : r3 r2, + } + } +} diff --git a/compiler/rustc_target/src/asm/bpf.rs b/compiler/rustc_target/src/asm/bpf.rs index ecb6bdc95ce..d94fcb53e24 100644 --- a/compiler/rustc_target/src/asm/bpf.rs +++ b/compiler/rustc_target/src/asm/bpf.rs @@ -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(()) diff --git a/compiler/rustc_target/src/asm/hexagon.rs b/compiler/rustc_target/src/asm/hexagon.rs index 74afddb69dc..d20270ac9e9 100644 --- a/compiler/rustc_target/src/asm/hexagon.rs +++ b/compiler/rustc_target/src/asm/hexagon.rs @@ -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; }, } diff --git a/compiler/rustc_target/src/asm/mips.rs b/compiler/rustc_target/src/asm/mips.rs index b19489aa439..b1e8737b52b 100644 --- a/compiler/rustc_target/src/asm/mips.rs +++ b/compiler/rustc_target/src/asm/mips.rs @@ -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; }, diff --git a/compiler/rustc_target/src/asm/mod.rs b/compiler/rustc_target/src/asm/mod.rs index 85422aefbeb..a84410d0f3c 100644 --- a/compiler/rustc_target/src/asm/mod.rs +++ b/compiler/rustc_target/src/asm/mod.rs @@ -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)), )*)* ] } @@ -148,9 +148,11 @@ macro_rules! types { mod aarch64; mod arm; +mod avr; mod bpf; mod hexagon; mod mips; +mod msp430; mod nvptx; mod powerpc; mod riscv; @@ -161,9 +163,11 @@ mod x86; pub use aarch64::{AArch64InlineAsmReg, AArch64InlineAsmRegClass}; pub use arm::{ArmInlineAsmReg, ArmInlineAsmRegClass}; +pub use avr::{AvrInlineAsmReg, AvrInlineAsmRegClass}; pub use bpf::{BpfInlineAsmReg, BpfInlineAsmRegClass}; pub use hexagon::{HexagonInlineAsmReg, HexagonInlineAsmRegClass}; pub use mips::{MipsInlineAsmReg, MipsInlineAsmRegClass}; +pub use msp430::{Msp430InlineAsmReg, Msp430InlineAsmRegClass}; pub use nvptx::{NvptxInlineAsmReg, NvptxInlineAsmRegClass}; pub use powerpc::{PowerPCInlineAsmReg, PowerPCInlineAsmRegClass}; pub use riscv::{RiscVInlineAsmReg, RiscVInlineAsmRegClass}; @@ -189,7 +193,10 @@ pub enum InlineAsmArch { S390x, SpirV, Wasm32, + Wasm64, Bpf, + Avr, + Msp430, } impl FromStr for InlineAsmArch { @@ -212,7 +219,10 @@ impl FromStr for InlineAsmArch { "s390x" => Ok(Self::S390x), "spirv" => Ok(Self::SpirV), "wasm32" => Ok(Self::Wasm32), + "wasm64" => Ok(Self::Wasm64), "bpf" => Ok(Self::Bpf), + "avr" => Ok(Self::Avr), + "msp430" => Ok(Self::Msp430), _ => Err(()), } } @@ -243,6 +253,8 @@ pub enum InlineAsmReg { SpirV(SpirVInlineAsmReg), Wasm(WasmInlineAsmReg), Bpf(BpfInlineAsmReg), + Avr(AvrInlineAsmReg), + Msp430(Msp430InlineAsmReg), // Placeholder for invalid register constraints for the current target Err, } @@ -259,6 +271,8 @@ impl InlineAsmReg { Self::Mips(r) => r.name(), Self::S390x(r) => r.name(), Self::Bpf(r) => r.name(), + Self::Avr(r) => r.name(), + Self::Msp430(r) => r.name(), Self::Err => "<reg>", } } @@ -274,13 +288,15 @@ impl InlineAsmReg { Self::Mips(r) => InlineAsmRegClass::Mips(r.reg_class()), Self::S390x(r) => InlineAsmRegClass::S390x(r.reg_class()), Self::Bpf(r) => InlineAsmRegClass::Bpf(r.reg_class()), + Self::Avr(r) => InlineAsmRegClass::Avr(r.reg_class()), + Self::Msp430(r) => InlineAsmRegClass::Msp430(r.reg_class()), Self::Err => InlineAsmRegClass::Err, } } pub fn parse( arch: InlineAsmArch, - has_feature: impl FnMut(&str) -> bool, + target_features: &FxHashSet<Symbol>, target: &Target, name: Symbol, ) -> Result<Self, &'static str> { @@ -289,40 +305,46 @@ 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 => { - Self::Wasm(WasmInlineAsmReg::parse(arch, has_feature, target, &name)?) + InlineAsmArch::Wasm32 | InlineAsmArch::Wasm64 => { + 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, target_features, target, name)?) + } + InlineAsmArch::Msp430 => { + Self::Msp430(Msp430InlineAsmReg::parse(arch, target_features, target, name)?) } }) } @@ -345,6 +367,8 @@ impl InlineAsmReg { Self::Mips(r) => r.emit(out, arch, modifier), Self::S390x(r) => r.emit(out, arch, modifier), Self::Bpf(r) => r.emit(out, arch, modifier), + Self::Avr(r) => r.emit(out, arch, modifier), + Self::Msp430(r) => r.emit(out, arch, modifier), Self::Err => unreachable!("Use of InlineAsmReg::Err"), } } @@ -360,6 +384,8 @@ impl InlineAsmReg { Self::Mips(_) => cb(self), Self::S390x(_) => cb(self), Self::Bpf(r) => r.overlapping_regs(|r| cb(Self::Bpf(r))), + Self::Avr(r) => r.overlapping_regs(|r| cb(Self::Avr(r))), + Self::Msp430(_) => cb(self), Self::Err => unreachable!("Use of InlineAsmReg::Err"), } } @@ -390,6 +416,8 @@ pub enum InlineAsmRegClass { SpirV(SpirVInlineAsmRegClass), Wasm(WasmInlineAsmRegClass), Bpf(BpfInlineAsmRegClass), + Avr(AvrInlineAsmRegClass), + Msp430(Msp430InlineAsmRegClass), // Placeholder for invalid register constraints for the current target Err, } @@ -409,6 +437,8 @@ impl InlineAsmRegClass { Self::SpirV(r) => r.name(), Self::Wasm(r) => r.name(), Self::Bpf(r) => r.name(), + Self::Avr(r) => r.name(), + Self::Msp430(r) => r.name(), Self::Err => rustc_span::symbol::sym::reg, } } @@ -430,6 +460,8 @@ impl InlineAsmRegClass { Self::SpirV(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::SpirV), Self::Wasm(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Wasm), Self::Bpf(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Bpf), + Self::Avr(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Avr), + Self::Msp430(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Msp430), Self::Err => unreachable!("Use of InlineAsmRegClass::Err"), } } @@ -458,6 +490,8 @@ impl InlineAsmRegClass { Self::SpirV(r) => r.suggest_modifier(arch, ty), Self::Wasm(r) => r.suggest_modifier(arch, ty), Self::Bpf(r) => r.suggest_modifier(arch, ty), + Self::Avr(r) => r.suggest_modifier(arch, ty), + Self::Msp430(r) => r.suggest_modifier(arch, ty), Self::Err => unreachable!("Use of InlineAsmRegClass::Err"), } } @@ -482,6 +516,8 @@ impl InlineAsmRegClass { Self::SpirV(r) => r.default_modifier(arch), Self::Wasm(r) => r.default_modifier(arch), Self::Bpf(r) => r.default_modifier(arch), + Self::Avr(r) => r.default_modifier(arch), + Self::Msp430(r) => r.default_modifier(arch), Self::Err => unreachable!("Use of InlineAsmRegClass::Err"), } } @@ -491,7 +527,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), @@ -505,6 +541,8 @@ impl InlineAsmRegClass { Self::SpirV(r) => r.supported_types(arch), Self::Wasm(r) => r.supported_types(arch), Self::Bpf(r) => r.supported_types(arch), + Self::Avr(r) => r.supported_types(arch), + Self::Msp430(r) => r.supported_types(arch), Self::Err => unreachable!("Use of InlineAsmRegClass::Err"), } } @@ -529,8 +567,12 @@ impl InlineAsmRegClass { } InlineAsmArch::S390x => Self::S390x(S390xInlineAsmRegClass::parse(arch, name)?), InlineAsmArch::SpirV => Self::SpirV(SpirVInlineAsmRegClass::parse(arch, name)?), - InlineAsmArch::Wasm32 => Self::Wasm(WasmInlineAsmRegClass::parse(arch, name)?), + InlineAsmArch::Wasm32 | InlineAsmArch::Wasm64 => { + Self::Wasm(WasmInlineAsmRegClass::parse(arch, 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)?), }) } @@ -550,6 +592,8 @@ impl InlineAsmRegClass { Self::SpirV(r) => r.valid_modifiers(arch), Self::Wasm(r) => r.valid_modifiers(arch), Self::Bpf(r) => r.valid_modifiers(arch), + Self::Avr(r) => r.valid_modifiers(arch), + Self::Msp430(r) => r.valid_modifiers(arch), Self::Err => unreachable!("Use of InlineAsmRegClass::Err"), } } @@ -671,68 +715,78 @@ 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::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, target_features, target, &mut map); + map + } + InlineAsmArch::Msp430 => { + let mut map = msp430::regclass_map(); + msp430::fill_reg_map(arch, target_features, target, &mut map); map } } @@ -756,6 +810,7 @@ pub enum InlineAsmClobberAbi { X86_64SysV, Arm, AArch64, + AArch64NoX18, RiscV, } @@ -764,10 +819,11 @@ impl InlineAsmClobberAbi { /// clobber ABIs for the target. pub fn parse( arch: InlineAsmArch, + target_features: &FxHashSet<Symbol>, target: &Target, name: Symbol, ) -> Result<Self, &'static [&'static str]> { - let name = &*name.as_str(); + let name = name.as_str(); match arch { InlineAsmArch::X86 => match name { "C" | "system" | "efiapi" | "cdecl" | "stdcall" | "fastcall" => { @@ -787,7 +843,13 @@ impl InlineAsmClobberAbi { _ => Err(&["C", "system", "efiapi", "aapcs"]), }, InlineAsmArch::AArch64 => match name { - "C" | "system" | "efiapi" => Ok(InlineAsmClobberAbi::AArch64), + "C" | "system" | "efiapi" => { + Ok(if aarch64::reserved_x18(arch, target_features, target).is_err() { + InlineAsmClobberAbi::AArch64NoX18 + } else { + InlineAsmClobberAbi::AArch64 + }) + } _ => Err(&["C", "system", "efiapi"]), }, InlineAsmArch::RiscV32 | InlineAsmArch::RiscV64 => match name { @@ -862,8 +924,25 @@ impl InlineAsmClobberAbi { AArch64 AArch64InlineAsmReg { x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, - // x18 is platform-reserved or temporary, but we exclude it - // here since it is a reserved register. + x16, x17, x18, x30, + + // Technically the low 64 bits of v8-v15 are preserved, but + // we have no way of expressing this using clobbers. + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10, v11, v12, v13, v14, v15, + v16, v17, v18, v19, v20, v21, v22, v23, + v24, v25, v26, v27, v28, v29, v30, v31, + + p0, p1, p2, p3, p4, p5, p6, p7, + p8, p9, p10, p11, p12, p13, p14, p15, + ffr, + + } + }, + InlineAsmClobberAbi::AArch64NoX18 => clobbered_regs! { + AArch64 AArch64InlineAsmReg { + x0, x1, x2, x3, x4, x5, x6, x7, + x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x30, // Technically the low 64 bits of v8-v15 are preserved, but @@ -881,7 +960,8 @@ impl InlineAsmClobberAbi { }, InlineAsmClobberAbi::Arm => clobbered_regs! { Arm ArmInlineAsmReg { - // r9 is platform-reserved and is treated as callee-saved. + // r9 is either platform-reserved or callee-saved. Either + // way we don't need to clobber it. r0, r1, r2, r3, r12, r14, // The finest-grained register variant is used here so that diff --git a/compiler/rustc_target/src/asm/msp430.rs b/compiler/rustc_target/src/asm/msp430.rs new file mode 100644 index 00000000000..a27d6390a72 --- /dev/null +++ b/compiler/rustc_target/src/asm/msp430.rs @@ -0,0 +1,81 @@ +use super::{InlineAsmArch, InlineAsmType}; +use rustc_macros::HashStable_Generic; +use rustc_span::Symbol; +use std::fmt; + +def_reg_class! { + Msp430 Msp430InlineAsmRegClass { + reg, + } +} + +impl Msp430InlineAsmRegClass { + pub fn valid_modifiers(self, _arch: super::InlineAsmArch) -> &'static [char] { + &[] + } + + pub fn suggest_class(self, _arch: InlineAsmArch, _ty: InlineAsmType) -> Option<Self> { + None + } + + pub fn suggest_modifier( + self, + _arch: InlineAsmArch, + _ty: InlineAsmType, + ) -> Option<(char, &'static str)> { + None + } + + pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<(char, &'static str)> { + None + } + + pub fn supported_types( + self, + arch: InlineAsmArch, + ) -> &'static [(InlineAsmType, Option<Symbol>)] { + match (self, arch) { + (Self::reg, _) => types! { _: I8, I16; }, + } + } +} + +// The reserved registers are taken from: +// https://github.com/llvm/llvm-project/blob/36cb29cbbe1b22dcd298ad65e1fabe899b7d7249/llvm/lib/Target/MSP430/MSP430RegisterInfo.cpp#L73. +def_regs! { + Msp430 Msp430InlineAsmReg Msp430InlineAsmRegClass { + r5: reg = ["r5"], + r6: reg = ["r6"], + r7: reg = ["r7"], + r8: reg = ["r8"], + r9: reg = ["r9"], + r10: reg = ["r10"], + r11: reg = ["r11"], + r12: reg = ["r12"], + r13: reg = ["r13"], + r14: reg = ["r14"], + r15: reg = ["r15"], + + #error = ["r0", "pc"] => + "the program counter cannot be used as an operand for inline asm", + #error = ["r1", "sp"] => + "the stack pointer cannot be used as an operand for inline asm", + #error = ["r2", "sr"] => + "the status register cannot be used as an operand for inline asm", + #error = ["r3", "cg"] => + "the constant generator cannot be used as an operand for inline asm", + #error = ["r4", "fp"] => + "the frame pointer cannot be used as an operand for inline asm", + } +} + +impl Msp430InlineAsmReg { + pub fn emit( + self, + out: &mut dyn fmt::Write, + _arch: InlineAsmArch, + _modifier: Option<char>, + ) -> fmt::Result { + out.write_str(self.name()) + } +} diff --git a/compiler/rustc_target/src/asm/nvptx.rs b/compiler/rustc_target/src/asm/nvptx.rs index 43d16ae0f5d..8e1e91e7c5f 100644 --- a/compiler/rustc_target/src/asm/nvptx.rs +++ b/compiler/rustc_target/src/asm/nvptx.rs @@ -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; }, diff --git a/compiler/rustc_target/src/asm/powerpc.rs b/compiler/rustc_target/src/asm/powerpc.rs index 51a4303689e..d3ccb30350a 100644 --- a/compiler/rustc_target/src/asm/powerpc.rs +++ b/compiler/rustc_target/src/asm/powerpc.rs @@ -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 { diff --git a/compiler/rustc_target/src/asm/riscv.rs b/compiler/rustc_target/src/asm/riscv.rs index 314bd01de12..39644d232ba 100644 --- a/compiler/rustc_target/src/asm/riscv.rs +++ b/compiler/rustc_target/src/asm/riscv.rs @@ -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(()) diff --git a/compiler/rustc_target/src/asm/s390x.rs b/compiler/rustc_target/src/asm/s390x.rs index a74873f1747..0a50064f587 100644 --- a/compiler/rustc_target/src/asm/s390x.rs +++ b/compiler/rustc_target/src/asm/s390x.rs @@ -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; }, diff --git a/compiler/rustc_target/src/asm/spirv.rs b/compiler/rustc_target/src/asm/spirv.rs index da82749e96a..31073da10b2 100644 --- a/compiler/rustc_target/src/asm/spirv.rs +++ b/compiler/rustc_target/src/asm/spirv.rs @@ -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; } diff --git a/compiler/rustc_target/src/asm/wasm.rs b/compiler/rustc_target/src/asm/wasm.rs index 1b33f8f9632..f095b7c6e11 100644 --- a/compiler/rustc_target/src/asm/wasm.rs +++ b/compiler/rustc_target/src/asm/wasm.rs @@ -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; } diff --git a/compiler/rustc_target/src/asm/x86.rs b/compiler/rustc_target/src/asm/x86.rs index 5e3828d7d85..01d32570f78 100644 --- a/compiler/rustc_target/src/asm/x86.rs +++ b/compiler/rustc_target/src/asm/x86.rs @@ -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 { |
