about summary refs log tree commit diff
path: root/library/stdarch/crates
diff options
context:
space:
mode:
Diffstat (limited to 'library/stdarch/crates')
-rw-r--r--library/stdarch/crates/stdarch-verify/tests/x86-intel.rs94
1 files changed, 74 insertions, 20 deletions
diff --git a/library/stdarch/crates/stdarch-verify/tests/x86-intel.rs b/library/stdarch/crates/stdarch-verify/tests/x86-intel.rs
index 76170922f76..cb772ac8822 100644
--- a/library/stdarch/crates/stdarch-verify/tests/x86-intel.rs
+++ b/library/stdarch/crates/stdarch-verify/tests/x86-intel.rs
@@ -67,7 +67,7 @@ static TUPLE: Type = Type::Tuple;
 static CPUID: Type = Type::CpuidResult;
 static NEVER: Type = Type::Never;
 
-#[derive(Debug)]
+#[derive(Debug, PartialEq, Copy, Clone)]
 enum Type {
     PrimFloat(u8),
     PrimSigned(u8),
@@ -520,7 +520,7 @@ fn matches(rust: &Function, intel: &Intrinsic) -> Result<(), String> {
 
     // Make sure we've got the right return type.
     if let Some(t) = rust.ret {
-        equate(t, &intel.return_.type_, "", rust.name, false)?;
+        equate(t, &intel.return_.type_, "", intel, false)?;
     } else if !intel.return_.type_.is_empty() && intel.return_.type_ != "void" {
         bail!(
             "{} returns `{}` with intel, void in rust",
@@ -542,7 +542,7 @@ fn matches(rust: &Function, intel: &Intrinsic) -> Result<(), String> {
         }
         for (i, (a, b)) in intel.parameters.iter().zip(rust.arguments).enumerate() {
             let is_const = rust.required_const.contains(&i);
-            equate(b, &a.type_, &a.etype, &intel.name, is_const)?;
+            equate(b, &a.type_, &a.etype, &intel, is_const)?;
         }
     }
 
@@ -655,11 +655,59 @@ fn matches(rust: &Function, intel: &Intrinsic) -> Result<(), String> {
     Ok(())
 }
 
+fn pointed_type(intrinsic: &Intrinsic) -> Result<Type, String> {
+    Ok(
+        if intrinsic.tech == "AMX"
+            || intrinsic
+                .cpuid
+                .iter()
+                .any(|cpuid| matches!(&**cpuid, "KEYLOCKER" | "KEYLOCKER_WIDE" | "XSAVE" | "FXSR"))
+        {
+            // AMX, KEYLOCKER and XSAVE intrinsics should take `*u8`
+            U8
+        } else if intrinsic.name == "_mm_clflush" {
+            // Just a false match in the following logic
+            U8
+        } else if ["_mm_storeu_si", "_mm_loadu_si"]
+            .iter()
+            .any(|x| intrinsic.name.starts_with(x))
+        {
+            // These have already been stabilized, so cannot be changed anymore
+            U8
+        } else if intrinsic.name.ends_with("i8") {
+            I8
+        } else if intrinsic.name.ends_with("i16") {
+            I16
+        } else if intrinsic.name.ends_with("i32") {
+            I32
+        } else if intrinsic.name.ends_with("i64") {
+            I64
+        } else if intrinsic.name.ends_with("i128") {
+            M128I
+        } else if intrinsic.name.ends_with("i256") {
+            M256I
+        } else if intrinsic.name.ends_with("i512") {
+            M512I
+        } else if intrinsic.name.ends_with("h") {
+            F16
+        } else if intrinsic.name.ends_with("s") {
+            F32
+        } else if intrinsic.name.ends_with("d") {
+            F64
+        } else {
+            bail!(
+                "Don't know what type of *void to use for {}",
+                intrinsic.name
+            );
+        },
+    )
+}
+
 fn equate(
     t: &Type,
     intel: &str,
     etype: &str,
-    intrinsic: &str,
+    intrinsic: &Intrinsic,
     is_const: bool,
 ) -> Result<(), String> {
     // Make pointer adjacent to the type: float * foo => float* foo
@@ -676,7 +724,7 @@ fn equate(
     if etype == "IMM" || intel == "constexpr int" {
         // The _bittest intrinsics claim to only accept immediates but actually
         // accept run-time values as well.
-        if !is_const && !intrinsic.starts_with("_bittest") {
+        if !is_const && !intrinsic.name.starts_with("_bittest") {
             bail!("argument required to be const but isn't");
         }
     } else {
@@ -723,7 +771,16 @@ fn equate(
         (&Type::MMASK16, "__mmask16") => {}
         (&Type::MMASK8, "__mmask8") => {}
 
-        (&Type::MutPtr(_), "void*") => {}
+        (&Type::MutPtr(_type), "void*") | (&Type::ConstPtr(_type), "void const*") => {
+            let pointed_type = pointed_type(intrinsic)?;
+            if _type != &pointed_type {
+                bail!(
+                    "incorrect void pointer type {_type:?} in {}, should be pointer to {pointed_type:?}",
+                    intrinsic.name,
+                );
+            }
+        }
+
         (&Type::MutPtr(&Type::PrimFloat(32)), "float*") => {}
         (&Type::MutPtr(&Type::PrimFloat(64)), "double*") => {}
         (&Type::MutPtr(&Type::PrimSigned(8)), "char*") => {}
@@ -752,7 +809,6 @@ fn equate(
         (&Type::MutPtr(&Type::M512I), "__m512i*") => {}
         (&Type::MutPtr(&Type::M512D), "__m512d*") => {}
 
-        (&Type::ConstPtr(_), "void const*") => {}
         (&Type::ConstPtr(&Type::PrimFloat(16)), "_Float16 const*") => {}
         (&Type::ConstPtr(&Type::PrimFloat(32)), "float const*") => {}
         (&Type::ConstPtr(&Type::PrimFloat(64)), "double const*") => {}
@@ -792,34 +848,32 @@ fn equate(
         // This is a macro (?) in C which seems to mutate its arguments, but
         // that means that we're taking pointers to arguments in rust
         // as we're not exposing it as a macro.
-        (&Type::MutPtr(&Type::M128), "__m128") if intrinsic == "_MM_TRANSPOSE4_PS" => {}
+        (&Type::MutPtr(&Type::M128), "__m128") if intrinsic.name == "_MM_TRANSPOSE4_PS" => {}
 
         // The _rdtsc intrinsic uses a __int64 return type, but this is a bug in
         // the intrinsics guide: https://github.com/rust-lang/stdarch/issues/559
         // We have manually fixed the bug by changing the return type to `u64`.
-        (&Type::PrimUnsigned(64), "__int64") if intrinsic == "_rdtsc" => {}
+        (&Type::PrimUnsigned(64), "__int64") if intrinsic.name == "_rdtsc" => {}
 
         // The _bittest and _bittest64 intrinsics takes a mutable pointer in the
         // intrinsics guide even though it never writes through the pointer:
-        (&Type::ConstPtr(&Type::PrimSigned(32)), "__int32*") if intrinsic == "_bittest" => {}
-        (&Type::ConstPtr(&Type::PrimSigned(64)), "__int64*") if intrinsic == "_bittest64" => {}
+        (&Type::ConstPtr(&Type::PrimSigned(32)), "__int32*") if intrinsic.name == "_bittest" => {}
+        (&Type::ConstPtr(&Type::PrimSigned(64)), "__int64*") if intrinsic.name == "_bittest64" => {}
         // The _xrstor, _fxrstor, _xrstor64, _fxrstor64 intrinsics take a
         // mutable pointer in the intrinsics guide even though they never write
         // through the pointer:
         (&Type::ConstPtr(&Type::PrimUnsigned(8)), "void*")
-            if intrinsic == "_xrstor"
-                || intrinsic == "_xrstor64"
-                || intrinsic == "_fxrstor"
-                || intrinsic == "_fxrstor64" => {}
+            if matches!(
+                &*intrinsic.name,
+                "_xrstor" | "_xrstor64" | "_fxrstor" | "_fxrstor64"
+            ) => {}
         // The _mm_stream_load_si128 intrinsic take a mutable pointer in the intrinsics
         // guide even though they never write through the pointer
-        (&Type::ConstPtr(&Type::M128I), "void*") if intrinsic == "_mm_stream_load_si128" => {}
+        (&Type::ConstPtr(&Type::M128I), "void*") if intrinsic.name == "_mm_stream_load_si128" => {}
 
         _ => bail!(
-            "failed to equate: `{}` and {:?} for {}",
-            intel,
-            t,
-            intrinsic
+            "failed to equate: `{intel}` and {t:?} for {}",
+            intrinsic.name
         ),
     }
     Ok(())