]> git.proxmox.com Git - rustc.git/blobdiff - compiler/rustc_target/src/asm/mod.rs
New upstream version 1.53.0+dfsg1
[rustc.git] / compiler / rustc_target / src / asm / mod.rs
index 5ebd6c4a2349f5a689656f22b6ee9ce77462cca4..e2268a61a42571277939de276759cc94827d1d0b 100644 (file)
@@ -13,23 +13,23 @@ macro_rules! def_reg_class {
             $class:ident,
         )*
     }) => {
-        #[derive(Copy, Clone, Encodable, Decodable, Debug, Eq, PartialEq, Hash, HashStable_Generic)]
+        #[derive(Copy, Clone, Encodable, Decodable, Debug, Eq, PartialEq, PartialOrd, Hash, HashStable_Generic)]
         #[allow(non_camel_case_types)]
         pub enum $arch_regclass {
             $($class,)*
         }
 
         impl $arch_regclass {
-            pub fn name(self) -> &'static str {
+            pub fn name(self) -> rustc_span::Symbol {
                 match self {
-                    $(Self::$class => stringify!($class),)*
+                    $(Self::$class => rustc_span::symbol::sym::$class,)*
                 }
             }
 
-            pub fn parse(_arch: super::InlineAsmArch, name: &str) -> Result<Self, &'static str> {
+            pub fn parse(_arch: super::InlineAsmArch, name: rustc_span::Symbol) -> Result<Self, &'static str> {
                 match name {
                     $(
-                        stringify!($class) => Ok(Self::$class),
+                        rustc_span::sym::$class => Ok(Self::$class),
                     )*
                     _ => Err("unknown register class"),
                 }
@@ -62,7 +62,7 @@ macro_rules! def_regs {
         )*
     }) => {
         #[allow(unreachable_code)]
-        #[derive(Copy, Clone, Encodable, Decodable, Debug, Eq, PartialEq, Hash, HashStable_Generic)]
+        #[derive(Copy, Clone, Encodable, Decodable, Debug, Eq, PartialEq, PartialOrd, Hash, HashStable_Generic)]
         #[allow(non_camel_case_types)]
         pub enum $arch_reg {
             $($reg,)*
@@ -90,7 +90,7 @@ macro_rules! def_regs {
                 match name {
                     $(
                         $($alias)|* | $reg_name => {
-                            $($filter(_arch, &mut _has_feature, _target, false)?;)?
+                            $($filter(_arch, &mut _has_feature, _target)?;)?
                             Ok(Self::$reg)
                         }
                     )*
@@ -114,7 +114,7 @@ macro_rules! def_regs {
             #[allow(unused_imports)]
             use super::{InlineAsmReg, InlineAsmRegClass};
             $(
-                if $($filter(_arch, &mut _has_feature, _target, true).is_ok() &&)? true {
+                if $($filter(_arch, &mut _has_feature, _target).is_ok() &&)? true {
                     if let Some(set) = _map.get_mut(&InlineAsmRegClass::$arch($arch_regclass::$class)) {
                         set.insert(InlineAsmReg::$arch($arch_reg::$reg));
                     }
@@ -156,6 +156,7 @@ mod mips;
 mod nvptx;
 mod riscv;
 mod spirv;
+mod wasm;
 mod x86;
 
 pub use aarch64::{AArch64InlineAsmReg, AArch64InlineAsmRegClass};
@@ -165,6 +166,7 @@ pub use mips::{MipsInlineAsmReg, MipsInlineAsmRegClass};
 pub use nvptx::{NvptxInlineAsmReg, NvptxInlineAsmRegClass};
 pub use riscv::{RiscVInlineAsmReg, RiscVInlineAsmRegClass};
 pub use spirv::{SpirVInlineAsmReg, SpirVInlineAsmRegClass};
+pub use wasm::{WasmInlineAsmReg, WasmInlineAsmRegClass};
 pub use x86::{X86InlineAsmReg, X86InlineAsmRegClass};
 
 #[derive(Copy, Clone, Encodable, Decodable, Debug, Eq, PartialEq, Hash)]
@@ -180,6 +182,7 @@ pub enum InlineAsmArch {
     Mips,
     Mips64,
     SpirV,
+    Wasm32,
 }
 
 impl FromStr for InlineAsmArch {
@@ -198,12 +201,24 @@ impl FromStr for InlineAsmArch {
             "mips" => Ok(Self::Mips),
             "mips64" => Ok(Self::Mips64),
             "spirv" => Ok(Self::SpirV),
+            "wasm32" => Ok(Self::Wasm32),
             _ => Err(()),
         }
     }
 }
 
-#[derive(Copy, Clone, Encodable, Decodable, Debug, Eq, PartialEq, Hash, HashStable_Generic)]
+#[derive(
+    Copy,
+    Clone,
+    Encodable,
+    Decodable,
+    Debug,
+    Eq,
+    PartialEq,
+    PartialOrd,
+    Hash,
+    HashStable_Generic
+)]
 pub enum InlineAsmReg {
     X86(X86InlineAsmReg),
     Arm(ArmInlineAsmReg),
@@ -213,6 +228,9 @@ pub enum InlineAsmReg {
     Hexagon(HexagonInlineAsmReg),
     Mips(MipsInlineAsmReg),
     SpirV(SpirVInlineAsmReg),
+    Wasm(WasmInlineAsmReg),
+    // Placeholder for invalid register constraints for the current target
+    Err,
 }
 
 impl InlineAsmReg {
@@ -224,6 +242,7 @@ impl InlineAsmReg {
             Self::RiscV(r) => r.name(),
             Self::Hexagon(r) => r.name(),
             Self::Mips(r) => r.name(),
+            Self::Err => "<reg>",
         }
     }
 
@@ -235,6 +254,7 @@ impl InlineAsmReg {
             Self::RiscV(r) => InlineAsmRegClass::RiscV(r.reg_class()),
             Self::Hexagon(r) => InlineAsmRegClass::Hexagon(r.reg_class()),
             Self::Mips(r) => InlineAsmRegClass::Mips(r.reg_class()),
+            Self::Err => InlineAsmRegClass::Err,
         }
     }
 
@@ -272,6 +292,9 @@ impl InlineAsmReg {
             InlineAsmArch::SpirV => {
                 Self::SpirV(SpirVInlineAsmReg::parse(arch, has_feature, target, &name)?)
             }
+            InlineAsmArch::Wasm32 => {
+                Self::Wasm(WasmInlineAsmReg::parse(arch, has_feature, target, &name)?)
+            }
         })
     }
 
@@ -290,6 +313,7 @@ impl InlineAsmReg {
             Self::RiscV(r) => r.emit(out, arch, modifier),
             Self::Hexagon(r) => r.emit(out, arch, modifier),
             Self::Mips(r) => r.emit(out, arch, modifier),
+            Self::Err => unreachable!("Use of InlineAsmReg::Err"),
         }
     }
 
@@ -301,11 +325,23 @@ impl InlineAsmReg {
             Self::RiscV(_) => cb(self),
             Self::Hexagon(r) => r.overlapping_regs(|r| cb(Self::Hexagon(r))),
             Self::Mips(_) => cb(self),
+            Self::Err => unreachable!("Use of InlineAsmReg::Err"),
         }
     }
 }
 
-#[derive(Copy, Clone, Encodable, Decodable, Debug, Eq, PartialEq, Hash, HashStable_Generic)]
+#[derive(
+    Copy,
+    Clone,
+    Encodable,
+    Decodable,
+    Debug,
+    Eq,
+    PartialEq,
+    PartialOrd,
+    Hash,
+    HashStable_Generic
+)]
 pub enum InlineAsmRegClass {
     X86(X86InlineAsmRegClass),
     Arm(ArmInlineAsmRegClass),
@@ -315,10 +351,13 @@ pub enum InlineAsmRegClass {
     Hexagon(HexagonInlineAsmRegClass),
     Mips(MipsInlineAsmRegClass),
     SpirV(SpirVInlineAsmRegClass),
+    Wasm(WasmInlineAsmRegClass),
+    // Placeholder for invalid register constraints for the current target
+    Err,
 }
 
 impl InlineAsmRegClass {
-    pub fn name(self) -> &'static str {
+    pub fn name(self) -> Symbol {
         match self {
             Self::X86(r) => r.name(),
             Self::Arm(r) => r.name(),
@@ -328,6 +367,8 @@ impl InlineAsmRegClass {
             Self::Hexagon(r) => r.name(),
             Self::Mips(r) => r.name(),
             Self::SpirV(r) => r.name(),
+            Self::Wasm(r) => r.name(),
+            Self::Err => rustc_span::symbol::sym::reg,
         }
     }
 
@@ -344,6 +385,8 @@ impl InlineAsmRegClass {
             Self::Hexagon(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Hexagon),
             Self::Mips(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Mips),
             Self::SpirV(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::SpirV),
+            Self::Wasm(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Wasm),
+            Self::Err => unreachable!("Use of InlineAsmRegClass::Err"),
         }
     }
 
@@ -367,6 +410,8 @@ impl InlineAsmRegClass {
             Self::Hexagon(r) => r.suggest_modifier(arch, ty),
             Self::Mips(r) => r.suggest_modifier(arch, ty),
             Self::SpirV(r) => r.suggest_modifier(arch, ty),
+            Self::Wasm(r) => r.suggest_modifier(arch, ty),
+            Self::Err => unreachable!("Use of InlineAsmRegClass::Err"),
         }
     }
 
@@ -386,6 +431,8 @@ impl InlineAsmRegClass {
             Self::Hexagon(r) => r.default_modifier(arch),
             Self::Mips(r) => r.default_modifier(arch),
             Self::SpirV(r) => r.default_modifier(arch),
+            Self::Wasm(r) => r.default_modifier(arch),
+            Self::Err => unreachable!("Use of InlineAsmRegClass::Err"),
         }
     }
 
@@ -404,32 +451,28 @@ impl InlineAsmRegClass {
             Self::Hexagon(r) => r.supported_types(arch),
             Self::Mips(r) => r.supported_types(arch),
             Self::SpirV(r) => r.supported_types(arch),
+            Self::Wasm(r) => r.supported_types(arch),
+            Self::Err => unreachable!("Use of InlineAsmRegClass::Err"),
         }
     }
 
     pub fn parse(arch: InlineAsmArch, name: Symbol) -> Result<Self, &'static str> {
-        // FIXME: use direct symbol comparison for register class names
-        name.with(|name| {
-            Ok(match arch {
-                InlineAsmArch::X86 | InlineAsmArch::X86_64 => {
-                    Self::X86(X86InlineAsmRegClass::parse(arch, name)?)
-                }
-                InlineAsmArch::Arm => Self::Arm(ArmInlineAsmRegClass::parse(arch, name)?),
-                InlineAsmArch::AArch64 => {
-                    Self::AArch64(AArch64InlineAsmRegClass::parse(arch, name)?)
-                }
-                InlineAsmArch::RiscV32 | InlineAsmArch::RiscV64 => {
-                    Self::RiscV(RiscVInlineAsmRegClass::parse(arch, name)?)
-                }
-                InlineAsmArch::Nvptx64 => Self::Nvptx(NvptxInlineAsmRegClass::parse(arch, name)?),
-                InlineAsmArch::Hexagon => {
-                    Self::Hexagon(HexagonInlineAsmRegClass::parse(arch, name)?)
-                }
-                InlineAsmArch::Mips | InlineAsmArch::Mips64 => {
-                    Self::Mips(MipsInlineAsmRegClass::parse(arch, name)?)
-                }
-                InlineAsmArch::SpirV => Self::SpirV(SpirVInlineAsmRegClass::parse(arch, name)?),
-            })
+        Ok(match arch {
+            InlineAsmArch::X86 | InlineAsmArch::X86_64 => {
+                Self::X86(X86InlineAsmRegClass::parse(arch, name)?)
+            }
+            InlineAsmArch::Arm => Self::Arm(ArmInlineAsmRegClass::parse(arch, name)?),
+            InlineAsmArch::AArch64 => Self::AArch64(AArch64InlineAsmRegClass::parse(arch, name)?),
+            InlineAsmArch::RiscV32 | InlineAsmArch::RiscV64 => {
+                Self::RiscV(RiscVInlineAsmRegClass::parse(arch, name)?)
+            }
+            InlineAsmArch::Nvptx64 => Self::Nvptx(NvptxInlineAsmRegClass::parse(arch, name)?),
+            InlineAsmArch::Hexagon => Self::Hexagon(HexagonInlineAsmRegClass::parse(arch, name)?),
+            InlineAsmArch::Mips | InlineAsmArch::Mips64 => {
+                Self::Mips(MipsInlineAsmRegClass::parse(arch, name)?)
+            }
+            InlineAsmArch::SpirV => Self::SpirV(SpirVInlineAsmRegClass::parse(arch, name)?),
+            InlineAsmArch::Wasm32 => Self::Wasm(WasmInlineAsmRegClass::parse(arch, name)?),
         })
     }
 
@@ -445,11 +488,24 @@ impl InlineAsmRegClass {
             Self::Hexagon(r) => r.valid_modifiers(arch),
             Self::Mips(r) => r.valid_modifiers(arch),
             Self::SpirV(r) => r.valid_modifiers(arch),
+            Self::Wasm(r) => r.valid_modifiers(arch),
+            Self::Err => unreachable!("Use of InlineAsmRegClass::Err"),
         }
     }
 }
 
-#[derive(Copy, Clone, Encodable, Decodable, Debug, Eq, PartialEq, Hash, HashStable_Generic)]
+#[derive(
+    Copy,
+    Clone,
+    Encodable,
+    Decodable,
+    Debug,
+    Eq,
+    PartialEq,
+    PartialOrd,
+    Hash,
+    HashStable_Generic
+)]
 pub enum InlineAsmRegOrRegClass {
     Reg(InlineAsmReg),
     RegClass(InlineAsmRegClass),
@@ -468,7 +524,7 @@ impl fmt::Display for InlineAsmRegOrRegClass {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match self {
             Self::Reg(r) => write!(f, "\"{}\"", r.name()),
-            Self::RegClass(r) => f.write_str(r.name()),
+            Self::RegClass(r) => write!(f, "{}", r.name()),
         }
     }
 }
@@ -592,5 +648,10 @@ pub fn allocatable_registers(
             spirv::fill_reg_map(arch, has_feature, target, &mut map);
             map
         }
+        InlineAsmArch::Wasm32 => {
+            let mut map = wasm::regclass_map();
+            wasm::fill_reg_map(arch, has_feature, target, &mut map);
+            map
+        }
     }
 }