From 0a2d3ce2fb8601587094a7bdb16109058d6664ae Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9my=20Rakic?= <remy.rakic+github@gmail.com>
Date: Sat, 27 Feb 2021 22:42:30 +0100
Subject: [PATCH 1/8] convert `_mm_shuffle_epi32` to const generics

---
 crates/core_arch/src/x86/avx512f.rs |  4 +-
 crates/core_arch/src/x86/sse2.rs    | 67 ++++++-----------------------
 2 files changed, 16 insertions(+), 55 deletions(-)

diff --git a/crates/core_arch/src/x86/avx512f.rs b/crates/core_arch/src/x86/avx512f.rs
index 6ba96989ab..9137001f32 100644
--- a/crates/core_arch/src/x86/avx512f.rs
+++ b/crates/core_arch/src/x86/avx512f.rs
@@ -22495,7 +22495,7 @@ pub unsafe fn _mm_mask_shuffle_epi32(
 ) -> __m128i {
     macro_rules! call {
         ($imm8:expr) => {
-            _mm_shuffle_epi32(a, $imm8)
+            _mm_shuffle_epi32::<$imm8>(a)
         };
     }
     let r = constify_imm8_sae!(imm8, call);
@@ -22512,7 +22512,7 @@ pub unsafe fn _mm_mask_shuffle_epi32(
 pub unsafe fn _mm_maskz_shuffle_epi32(k: __mmask8, a: __m128i, imm8: _MM_PERM_ENUM) -> __m128i {
     macro_rules! call {
         ($imm8:expr) => {
-            _mm_shuffle_epi32(a, $imm8)
+            _mm_shuffle_epi32::<$imm8>(a)
         };
     }
     let r = constify_imm8_sae!(imm8, call);
diff --git a/crates/core_arch/src/x86/sse2.rs b/crates/core_arch/src/x86/sse2.rs
index 12e7506f02..01c9d9efa1 100644
--- a/crates/core_arch/src/x86/sse2.rs
+++ b/crates/core_arch/src/x86/sse2.rs
@@ -1461,60 +1461,21 @@ pub unsafe fn _mm_movemask_epi8(a: __m128i) -> i32 {
 #[inline]
 #[target_feature(enable = "sse2")]
 #[cfg_attr(test, assert_instr(pshufd, imm8 = 9))]
-#[rustc_args_required_const(1)]
+#[rustc_legacy_const_generics(1)]
 #[stable(feature = "simd_x86", since = "1.27.0")]
-pub unsafe fn _mm_shuffle_epi32(a: __m128i, imm8: i32) -> __m128i {
-    // simd_shuffleX requires that its selector parameter be made up of
-    // constant values, but we can't enforce that here. In spirit, we need
-    // to write a `match` on all possible values of a byte, and for each value,
-    // hard-code the correct `simd_shuffleX` call using only constants. We
-    // then hope for LLVM to do the rest.
-    //
-    // Of course, that's... awful. So we try to use macros to do it for us.
-    let imm8 = (imm8 & 0xFF) as u8;
+pub unsafe fn _mm_shuffle_epi32<const imm8: i32>(a: __m128i) -> __m128i {
+    static_assert!(imm8: i32 where imm8 >= 0 && imm8 <= 255);
     let a = a.as_i32x4();
-
-    macro_rules! shuffle_done {
-        ($x01:expr, $x23:expr, $x45:expr, $x67:expr) => {
-            simd_shuffle4(a, a, [$x01, $x23, $x45, $x67])
-        };
-    }
-    macro_rules! shuffle_x67 {
-        ($x01:expr, $x23:expr, $x45:expr) => {
-            match (imm8 >> 6) & 0b11 {
-                0b00 => shuffle_done!($x01, $x23, $x45, 0),
-                0b01 => shuffle_done!($x01, $x23, $x45, 1),
-                0b10 => shuffle_done!($x01, $x23, $x45, 2),
-                _ => shuffle_done!($x01, $x23, $x45, 3),
-            }
-        };
-    }
-    macro_rules! shuffle_x45 {
-        ($x01:expr, $x23:expr) => {
-            match (imm8 >> 4) & 0b11 {
-                0b00 => shuffle_x67!($x01, $x23, 0),
-                0b01 => shuffle_x67!($x01, $x23, 1),
-                0b10 => shuffle_x67!($x01, $x23, 2),
-                _ => shuffle_x67!($x01, $x23, 3),
-            }
-        };
-    }
-    macro_rules! shuffle_x23 {
-        ($x01:expr) => {
-            match (imm8 >> 2) & 0b11 {
-                0b00 => shuffle_x45!($x01, 0),
-                0b01 => shuffle_x45!($x01, 1),
-                0b10 => shuffle_x45!($x01, 2),
-                _ => shuffle_x45!($x01, 3),
-            }
-        };
-    }
-    let x: i32x4 = match imm8 & 0b11 {
-        0b00 => shuffle_x23!(0),
-        0b01 => shuffle_x23!(1),
-        0b10 => shuffle_x23!(2),
-        _ => shuffle_x23!(3),
-    };
+    let x: i32x4 = simd_shuffle4(
+        a,
+        a,
+        [
+            imm8 as u32 & 0b11,
+            (imm8 as u32 >> 2) & 0b11,
+            (imm8 as u32 >> 4) & 0b11,
+            (imm8 as u32 >> 6) & 0b11,
+        ],
+    );
     transmute(x)
 }
 
@@ -4107,7 +4068,7 @@ mod tests {
     #[simd_test(enable = "sse2")]
     unsafe fn test_mm_shuffle_epi32() {
         let a = _mm_setr_epi32(5, 10, 15, 20);
-        let r = _mm_shuffle_epi32(a, 0b00_01_01_11);
+        let r = _mm_shuffle_epi32::<0b00_01_01_11>(a);
         let e = _mm_setr_epi32(20, 10, 10, 5);
         assert_eq_m128i(r, e);
     }

From 9d38868f6da9bf01d6a5608d66774d024354d295 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9my=20Rakic?= <remy.rakic+github@gmail.com>
Date: Sat, 27 Feb 2021 23:03:24 +0100
Subject: [PATCH 2/8] convert `_mm_shufflehi_epi16` to const generics

---
 crates/core_arch/src/x86/avx512bw.rs |  4 +-
 crates/core_arch/src/x86/sse2.rs     | 64 ++++++++--------------------
 2 files changed, 20 insertions(+), 48 deletions(-)

diff --git a/crates/core_arch/src/x86/avx512bw.rs b/crates/core_arch/src/x86/avx512bw.rs
index f4dc00bd87..f102b7326e 100644
--- a/crates/core_arch/src/x86/avx512bw.rs
+++ b/crates/core_arch/src/x86/avx512bw.rs
@@ -7592,7 +7592,7 @@ pub unsafe fn _mm_mask_shufflehi_epi16(
 ) -> __m128i {
     macro_rules! call {
         ($imm8:expr) => {
-            _mm_shufflehi_epi16(a, $imm8)
+            _mm_shufflehi_epi16::<$imm8>(a)
         };
     }
     let shuffle = constify_imm8_sae!(imm8, call);
@@ -7609,7 +7609,7 @@ pub unsafe fn _mm_mask_shufflehi_epi16(
 pub unsafe fn _mm_maskz_shufflehi_epi16(k: __mmask8, a: __m128i, imm8: i32) -> __m128i {
     macro_rules! call {
         ($imm8:expr) => {
-            _mm_shufflehi_epi16(a, $imm8)
+            _mm_shufflehi_epi16::<$imm8>(a)
         };
     }
     let shuffle = constify_imm8_sae!(imm8, call);
diff --git a/crates/core_arch/src/x86/sse2.rs b/crates/core_arch/src/x86/sse2.rs
index 01c9d9efa1..3e856a482e 100644
--- a/crates/core_arch/src/x86/sse2.rs
+++ b/crates/core_arch/src/x86/sse2.rs
@@ -1489,53 +1489,25 @@ pub unsafe fn _mm_shuffle_epi32<const imm8: i32>(a: __m128i) -> __m128i {
 #[inline]
 #[target_feature(enable = "sse2")]
 #[cfg_attr(test, assert_instr(pshufhw, imm8 = 9))]
-#[rustc_args_required_const(1)]
+#[rustc_legacy_const_generics(1)]
 #[stable(feature = "simd_x86", since = "1.27.0")]
-pub unsafe fn _mm_shufflehi_epi16(a: __m128i, imm8: i32) -> __m128i {
-    // See _mm_shuffle_epi32.
-    let imm8 = (imm8 & 0xFF) as u8;
+pub unsafe fn _mm_shufflehi_epi16<const imm8: i32>(a: __m128i) -> __m128i {
+    static_assert!(imm8: i32 where imm8 >= 0 && imm8 <= 255);
     let a = a.as_i16x8();
-    macro_rules! shuffle_done {
-        ($x01:expr, $x23:expr, $x45:expr, $x67:expr) => {
-            simd_shuffle8(a, a, [0, 1, 2, 3, $x01 + 4, $x23 + 4, $x45 + 4, $x67 + 4])
-        };
-    }
-    macro_rules! shuffle_x67 {
-        ($x01:expr, $x23:expr, $x45:expr) => {
-            match (imm8 >> 6) & 0b11 {
-                0b00 => shuffle_done!($x01, $x23, $x45, 0),
-                0b01 => shuffle_done!($x01, $x23, $x45, 1),
-                0b10 => shuffle_done!($x01, $x23, $x45, 2),
-                _ => shuffle_done!($x01, $x23, $x45, 3),
-            }
-        };
-    }
-    macro_rules! shuffle_x45 {
-        ($x01:expr, $x23:expr) => {
-            match (imm8 >> 4) & 0b11 {
-                0b00 => shuffle_x67!($x01, $x23, 0),
-                0b01 => shuffle_x67!($x01, $x23, 1),
-                0b10 => shuffle_x67!($x01, $x23, 2),
-                _ => shuffle_x67!($x01, $x23, 3),
-            }
-        };
-    }
-    macro_rules! shuffle_x23 {
-        ($x01:expr) => {
-            match (imm8 >> 2) & 0b11 {
-                0b00 => shuffle_x45!($x01, 0),
-                0b01 => shuffle_x45!($x01, 1),
-                0b10 => shuffle_x45!($x01, 2),
-                _ => shuffle_x45!($x01, 3),
-            }
-        };
-    }
-    let x: i16x8 = match imm8 & 0b11 {
-        0b00 => shuffle_x23!(0),
-        0b01 => shuffle_x23!(1),
-        0b10 => shuffle_x23!(2),
-        _ => shuffle_x23!(3),
-    };
+    let x: i16x8 = simd_shuffle8(
+        a,
+        a,
+        [
+            0,
+            1,
+            2,
+            3,
+            (imm8 as u32 & 0b11) + 4,
+            ((imm8 as u32 >> 2) & 0b11) + 4,
+            ((imm8 as u32 >> 4) & 0b11) + 4,
+            ((imm8 as u32 >> 6) & 0b11) + 4,
+        ],
+    );
     transmute(x)
 }
 
@@ -4076,7 +4048,7 @@ mod tests {
     #[simd_test(enable = "sse2")]
     unsafe fn test_mm_shufflehi_epi16() {
         let a = _mm_setr_epi16(1, 2, 3, 4, 5, 10, 15, 20);
-        let r = _mm_shufflehi_epi16(a, 0b00_01_01_11);
+        let r = _mm_shufflehi_epi16::<0b00_01_01_11>(a);
         let e = _mm_setr_epi16(1, 2, 3, 4, 20, 10, 10, 5);
         assert_eq_m128i(r, e);
     }

From 7228fea2caec7e2733e43677fb0ceba2d1aeb2f0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9my=20Rakic?= <remy.rakic+github@gmail.com>
Date: Sat, 27 Feb 2021 23:14:58 +0100
Subject: [PATCH 3/8] convert `_mm_shufflelo_epi16` to const generics

---
 crates/core_arch/src/x86/avx512bw.rs |  4 +-
 crates/core_arch/src/x86/sse2.rs     | 65 ++++++++--------------------
 2 files changed, 20 insertions(+), 49 deletions(-)

diff --git a/crates/core_arch/src/x86/avx512bw.rs b/crates/core_arch/src/x86/avx512bw.rs
index f102b7326e..c2c1a467e3 100644
--- a/crates/core_arch/src/x86/avx512bw.rs
+++ b/crates/core_arch/src/x86/avx512bw.rs
@@ -7414,7 +7414,7 @@ pub unsafe fn _mm_mask_shufflelo_epi16(
 ) -> __m128i {
     macro_rules! call {
         ($imm8:expr) => {
-            _mm_shufflelo_epi16(a, $imm8)
+            _mm_shufflelo_epi16::<$imm8>(a)
         };
     }
     let shuffle = constify_imm8_sae!(imm8, call);
@@ -7431,7 +7431,7 @@ pub unsafe fn _mm_mask_shufflelo_epi16(
 pub unsafe fn _mm_maskz_shufflelo_epi16(k: __mmask8, a: __m128i, imm8: i32) -> __m128i {
     macro_rules! call {
         ($imm8:expr) => {
-            _mm_shufflelo_epi16(a, $imm8)
+            _mm_shufflelo_epi16::<$imm8>(a)
         };
     }
     let shuffle = constify_imm8_sae!(imm8, call);
diff --git a/crates/core_arch/src/x86/sse2.rs b/crates/core_arch/src/x86/sse2.rs
index 3e856a482e..05f28f4663 100644
--- a/crates/core_arch/src/x86/sse2.rs
+++ b/crates/core_arch/src/x86/sse2.rs
@@ -1521,54 +1521,25 @@ pub unsafe fn _mm_shufflehi_epi16<const imm8: i32>(a: __m128i) -> __m128i {
 #[inline]
 #[target_feature(enable = "sse2")]
 #[cfg_attr(test, assert_instr(pshuflw, imm8 = 9))]
-#[rustc_args_required_const(1)]
+#[rustc_legacy_const_generics(1)]
 #[stable(feature = "simd_x86", since = "1.27.0")]
-pub unsafe fn _mm_shufflelo_epi16(a: __m128i, imm8: i32) -> __m128i {
-    // See _mm_shuffle_epi32.
-    let imm8 = (imm8 & 0xFF) as u8;
+pub unsafe fn _mm_shufflelo_epi16<const imm8: i32>(a: __m128i) -> __m128i {
+    static_assert!(imm8: i32 where imm8 >= 0 && imm8 <= 255);
     let a = a.as_i16x8();
-
-    macro_rules! shuffle_done {
-        ($x01:expr, $x23:expr, $x45:expr, $x67:expr) => {
-            simd_shuffle8(a, a, [$x01, $x23, $x45, $x67, 4, 5, 6, 7])
-        };
-    }
-    macro_rules! shuffle_x67 {
-        ($x01:expr, $x23:expr, $x45:expr) => {
-            match (imm8 >> 6) & 0b11 {
-                0b00 => shuffle_done!($x01, $x23, $x45, 0),
-                0b01 => shuffle_done!($x01, $x23, $x45, 1),
-                0b10 => shuffle_done!($x01, $x23, $x45, 2),
-                _ => shuffle_done!($x01, $x23, $x45, 3),
-            }
-        };
-    }
-    macro_rules! shuffle_x45 {
-        ($x01:expr, $x23:expr) => {
-            match (imm8 >> 4) & 0b11 {
-                0b00 => shuffle_x67!($x01, $x23, 0),
-                0b01 => shuffle_x67!($x01, $x23, 1),
-                0b10 => shuffle_x67!($x01, $x23, 2),
-                _ => shuffle_x67!($x01, $x23, 3),
-            }
-        };
-    }
-    macro_rules! shuffle_x23 {
-        ($x01:expr) => {
-            match (imm8 >> 2) & 0b11 {
-                0b00 => shuffle_x45!($x01, 0),
-                0b01 => shuffle_x45!($x01, 1),
-                0b10 => shuffle_x45!($x01, 2),
-                _ => shuffle_x45!($x01, 3),
-            }
-        };
-    }
-    let x: i16x8 = match imm8 & 0b11 {
-        0b00 => shuffle_x23!(0),
-        0b01 => shuffle_x23!(1),
-        0b10 => shuffle_x23!(2),
-        _ => shuffle_x23!(3),
-    };
+    let x: i16x8 = simd_shuffle8(
+        a,
+        a,
+        [
+            imm8 as u32 & 0b11,
+            (imm8 as u32 >> 2) & 0b11,
+            (imm8 as u32 >> 4) & 0b11,
+            (imm8 as u32 >> 6) & 0b11,
+            4,
+            5,
+            6,
+            7,
+        ],
+    );
     transmute(x)
 }
 
@@ -4056,7 +4027,7 @@ mod tests {
     #[simd_test(enable = "sse2")]
     unsafe fn test_mm_shufflelo_epi16() {
         let a = _mm_setr_epi16(5, 10, 15, 20, 1, 2, 3, 4);
-        let r = _mm_shufflelo_epi16(a, 0b00_01_01_11);
+        let r = _mm_shufflelo_epi16::<0b00_01_01_11>(a);
         let e = _mm_setr_epi16(20, 10, 10, 5, 1, 2, 3, 4);
         assert_eq_m128i(r, e);
     }

From 34db275b9c436b26e24225be4add7088d3e26acf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9my=20Rakic?= <remy.rakic+github@gmail.com>
Date: Sun, 28 Feb 2021 00:15:52 +0100
Subject: [PATCH 4/8] convert `_mm_srai_epi16` and `_mm_srai_epi32` to const
 generics

---
 crates/core_arch/src/x86/avx512bw.rs |  4 ++--
 crates/core_arch/src/x86/avx512f.rs  |  4 ++--
 crates/core_arch/src/x86/sse2.rs     | 28 ++++++++--------------------
 3 files changed, 12 insertions(+), 24 deletions(-)

diff --git a/crates/core_arch/src/x86/avx512bw.rs b/crates/core_arch/src/x86/avx512bw.rs
index c2c1a467e3..2abb335434 100644
--- a/crates/core_arch/src/x86/avx512bw.rs
+++ b/crates/core_arch/src/x86/avx512bw.rs
@@ -5858,7 +5858,7 @@ pub unsafe fn _mm256_maskz_srai_epi16(k: __mmask16, a: __m256i, imm8: u32) -> __
 pub unsafe fn _mm_mask_srai_epi16(src: __m128i, k: __mmask8, a: __m128i, imm8: u32) -> __m128i {
     macro_rules! call {
         ($imm8:expr) => {
-            _mm_srai_epi16(a, $imm8)
+            _mm_srai_epi16::<$imm8>(a)
         };
     }
     let shf = constify_imm8_sae!(imm8, call);
@@ -5875,7 +5875,7 @@ pub unsafe fn _mm_mask_srai_epi16(src: __m128i, k: __mmask8, a: __m128i, imm8: u
 pub unsafe fn _mm_maskz_srai_epi16(k: __mmask8, a: __m128i, imm8: u32) -> __m128i {
     macro_rules! call {
         ($imm8:expr) => {
-            _mm_srai_epi16(a, $imm8)
+            _mm_srai_epi16::<$imm8>(a)
         };
     }
     let shf = constify_imm8_sae!(imm8, call);
diff --git a/crates/core_arch/src/x86/avx512f.rs b/crates/core_arch/src/x86/avx512f.rs
index 9137001f32..9fbfb209db 100644
--- a/crates/core_arch/src/x86/avx512f.rs
+++ b/crates/core_arch/src/x86/avx512f.rs
@@ -19238,7 +19238,7 @@ pub unsafe fn _mm256_maskz_srai_epi32(k: __mmask8, a: __m256i, imm8: u32) -> __m
 pub unsafe fn _mm_mask_srai_epi32(src: __m128i, k: __mmask8, a: __m128i, imm8: u32) -> __m128i {
     macro_rules! call {
         ($imm8:expr) => {
-            _mm_srai_epi32(a, $imm8)
+            _mm_srai_epi32::<$imm8>(a)
         };
     }
     let shf = constify_imm8_sae!(imm8, call);
@@ -19255,7 +19255,7 @@ pub unsafe fn _mm_mask_srai_epi32(src: __m128i, k: __mmask8, a: __m128i, imm8: u
 pub unsafe fn _mm_maskz_srai_epi32(k: __mmask8, a: __m128i, imm8: u32) -> __m128i {
     macro_rules! call {
         ($imm8:expr) => {
-            _mm_srai_epi32(a, $imm8)
+            _mm_srai_epi32::<$imm8>(a)
         };
     }
     let shf = constify_imm8_sae!(imm8, call);
diff --git a/crates/core_arch/src/x86/sse2.rs b/crates/core_arch/src/x86/sse2.rs
index 05f28f4663..6db4f4db88 100644
--- a/crates/core_arch/src/x86/sse2.rs
+++ b/crates/core_arch/src/x86/sse2.rs
@@ -594,16 +594,10 @@ pub unsafe fn _mm_sll_epi64(a: __m128i, count: __m128i) -> __m128i {
 #[inline]
 #[target_feature(enable = "sse2")]
 #[cfg_attr(test, assert_instr(psraw, imm8 = 1))]
-#[rustc_args_required_const(1)]
+#[rustc_legacy_const_generics(1)]
 #[stable(feature = "simd_x86", since = "1.27.0")]
-pub unsafe fn _mm_srai_epi16(a: __m128i, imm8: i32) -> __m128i {
-    let a = a.as_i16x8();
-    macro_rules! call {
-        ($imm8:expr) => {
-            transmute(psraiw(a, $imm8))
-        };
-    }
-    constify_imm8!(imm8, call)
+pub unsafe fn _mm_srai_epi16<const imm8: i32>(a: __m128i) -> __m128i {
+    transmute(psraiw(a.as_i16x8(), imm8))
 }
 
 /// Shifts packed 16-bit integers in `a` right by `count` while shifting in sign
@@ -625,16 +619,10 @@ pub unsafe fn _mm_sra_epi16(a: __m128i, count: __m128i) -> __m128i {
 #[inline]
 #[target_feature(enable = "sse2")]
 #[cfg_attr(test, assert_instr(psrad, imm8 = 1))]
-#[rustc_args_required_const(1)]
+#[rustc_legacy_const_generics(1)]
 #[stable(feature = "simd_x86", since = "1.27.0")]
-pub unsafe fn _mm_srai_epi32(a: __m128i, imm8: i32) -> __m128i {
-    let a = a.as_i32x4();
-    macro_rules! call {
-        ($imm8:expr) => {
-            transmute(psraid(a, $imm8))
-        };
-    }
-    constify_imm8!(imm8, call)
+pub unsafe fn _mm_srai_epi32<const imm8: i32>(a: __m128i) -> __m128i {
+    transmute(psraid(a.as_i32x4(), imm8))
 }
 
 /// Shifts packed 32-bit integers in `a` right by `count` while shifting in sign
@@ -3498,7 +3486,7 @@ mod tests {
 
     #[simd_test(enable = "sse2")]
     unsafe fn test_mm_srai_epi16() {
-        let r = _mm_srai_epi16(_mm_set1_epi16(-1), 1);
+        let r = _mm_srai_epi16::<1>(_mm_set1_epi16(-1));
         assert_eq_m128i(r, _mm_set1_epi16(-1));
     }
 
@@ -3512,7 +3500,7 @@ mod tests {
 
     #[simd_test(enable = "sse2")]
     unsafe fn test_mm_srai_epi32() {
-        let r = _mm_srai_epi32(_mm_set1_epi32(-1), 1);
+        let r = _mm_srai_epi32::<1>(_mm_set1_epi32(-1));
         assert_eq_m128i(r, _mm_set1_epi32(-1));
     }
 

From f979a5a196af7227485012bcbbcebf48163b3904 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9my=20Rakic?= <remy.rakic+github@gmail.com>
Date: Sun, 28 Feb 2021 03:00:50 +0100
Subject: [PATCH 5/8] remove duplicate `constify_imm5` macro

The comment "immediate value: -16:15" makes it look it should have been named `constify_imm_s5` but its body is a duplicate of another `constify_imm5`
---
 crates/core_arch/src/macros.rs | 42 ----------------------------------
 1 file changed, 42 deletions(-)

diff --git a/crates/core_arch/src/macros.rs b/crates/core_arch/src/macros.rs
index ab643d9a29..801fadd433 100644
--- a/crates/core_arch/src/macros.rs
+++ b/crates/core_arch/src/macros.rs
@@ -320,48 +320,6 @@ macro_rules! constify_imm5 {
     };
 }
 
-//immediate value: -16:15
-#[allow(unused)]
-macro_rules! constify_imm5 {
-    ($imm8:expr, $expand:ident) => {
-        #[allow(overflowing_literals)]
-        match ($imm8) & 0b1_1111 {
-            0 => $expand!(0),
-            1 => $expand!(1),
-            2 => $expand!(2),
-            3 => $expand!(3),
-            4 => $expand!(4),
-            5 => $expand!(5),
-            6 => $expand!(6),
-            7 => $expand!(7),
-            8 => $expand!(8),
-            9 => $expand!(9),
-            10 => $expand!(10),
-            11 => $expand!(11),
-            12 => $expand!(12),
-            13 => $expand!(13),
-            14 => $expand!(14),
-            15 => $expand!(15),
-            16 => $expand!(16),
-            17 => $expand!(17),
-            18 => $expand!(18),
-            19 => $expand!(19),
-            20 => $expand!(20),
-            21 => $expand!(21),
-            22 => $expand!(22),
-            23 => $expand!(23),
-            24 => $expand!(24),
-            25 => $expand!(25),
-            26 => $expand!(26),
-            27 => $expand!(27),
-            28 => $expand!(28),
-            29 => $expand!(29),
-            30 => $expand!(30),
-            _ => $expand!(31),
-        }
-    };
-}
-
 //immediate value: 0:16
 #[allow(unused)]
 macro_rules! constify_imm4 {

From 66463d5a791484f71b05fdbcf13bebe36f39ab52 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9my=20Rakic?= <remy.rakic+github@gmail.com>
Date: Sun, 28 Feb 2021 03:03:01 +0100
Subject: [PATCH 6/8] add `static_assert_imm8` macro

Since this one will be used a lot, a single macro and struct can be used to avoid duplicating the imm8 check in every function, and instantiating the same MIR struct multiple times.
---
 crates/core_arch/src/macros.rs | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/crates/core_arch/src/macros.rs b/crates/core_arch/src/macros.rs
index 801fadd433..710f8531fd 100644
--- a/crates/core_arch/src/macros.rs
+++ b/crates/core_arch/src/macros.rs
@@ -1,5 +1,21 @@
 //! Utility macros.
 
+// Helper struct used to trigger const eval errors when a const generic immediate value is
+// out of range.
+pub(crate) struct ValidateConstImm8<const imm8: i32>();
+impl<const imm8: i32> ValidateConstImm8<imm8> {
+    pub(crate) const VALID: () = {
+        let _ = 1 / ((imm8 >= 0 && imm8 <= 255) as usize);
+    };
+}
+
+#[allow(unused)]
+macro_rules! static_assert_imm8 {
+    ($imm:ident) => {
+        let _ = $crate::core_arch::macros::ValidateConstImm8::<$imm>::VALID;
+    };
+}
+
 #[allow(unused)]
 macro_rules! static_assert {
     ($imm:ident : $ty:ty where $e:expr) => {

From fb1798b06797ca53d0636c4b2a06ec9ef2addaa6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9my=20Rakic?= <remy.rakic+github@gmail.com>
Date: Sun, 28 Feb 2021 03:05:47 +0100
Subject: [PATCH 7/8] `_mm_srai_epi{16, 32}`: statically assert the const
 generic parameter `imm8` is in range

---
 crates/core_arch/src/x86/sse2.rs | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/crates/core_arch/src/x86/sse2.rs b/crates/core_arch/src/x86/sse2.rs
index 6db4f4db88..aff9e96b3c 100644
--- a/crates/core_arch/src/x86/sse2.rs
+++ b/crates/core_arch/src/x86/sse2.rs
@@ -597,6 +597,7 @@ pub unsafe fn _mm_sll_epi64(a: __m128i, count: __m128i) -> __m128i {
 #[rustc_legacy_const_generics(1)]
 #[stable(feature = "simd_x86", since = "1.27.0")]
 pub unsafe fn _mm_srai_epi16<const imm8: i32>(a: __m128i) -> __m128i {
+    static_assert_imm8!(imm8);
     transmute(psraiw(a.as_i16x8(), imm8))
 }
 
@@ -622,6 +623,7 @@ pub unsafe fn _mm_sra_epi16(a: __m128i, count: __m128i) -> __m128i {
 #[rustc_legacy_const_generics(1)]
 #[stable(feature = "simd_x86", since = "1.27.0")]
 pub unsafe fn _mm_srai_epi32<const imm8: i32>(a: __m128i) -> __m128i {
+    static_assert_imm8!(imm8);
     transmute(psraid(a.as_i32x4(), imm8))
 }
 

From 386e978af4cb20ae0e732265e4d4bbe1033212b4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9my=20Rakic?= <remy.rakic+github@gmail.com>
Date: Sun, 28 Feb 2021 03:07:49 +0100
Subject: [PATCH 8/8] use `static_assert_imm8` instead of the generic
 `static_assert` macro

---
 crates/core_arch/src/x86/sse.rs  | 2 +-
 crates/core_arch/src/x86/sse2.rs | 6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/crates/core_arch/src/x86/sse.rs b/crates/core_arch/src/x86/sse.rs
index 3e7b54e302..98836518da 100644
--- a/crates/core_arch/src/x86/sse.rs
+++ b/crates/core_arch/src/x86/sse.rs
@@ -1010,7 +1010,7 @@ pub const fn _MM_SHUFFLE(z: u32, y: u32, x: u32, w: u32) -> i32 {
 #[rustc_legacy_const_generics(2)]
 #[stable(feature = "simd_x86", since = "1.27.0")]
 pub unsafe fn _mm_shuffle_ps<const mask: i32>(a: __m128, b: __m128) -> __m128 {
-    static_assert!(mask: i32 where mask >= 0 && mask <= 255);
+    static_assert_imm8!(mask);
     simd_shuffle4(
         a,
         b,
diff --git a/crates/core_arch/src/x86/sse2.rs b/crates/core_arch/src/x86/sse2.rs
index aff9e96b3c..ae98df5288 100644
--- a/crates/core_arch/src/x86/sse2.rs
+++ b/crates/core_arch/src/x86/sse2.rs
@@ -1454,7 +1454,7 @@ pub unsafe fn _mm_movemask_epi8(a: __m128i) -> i32 {
 #[rustc_legacy_const_generics(1)]
 #[stable(feature = "simd_x86", since = "1.27.0")]
 pub unsafe fn _mm_shuffle_epi32<const imm8: i32>(a: __m128i) -> __m128i {
-    static_assert!(imm8: i32 where imm8 >= 0 && imm8 <= 255);
+    static_assert_imm8!(imm8);
     let a = a.as_i32x4();
     let x: i32x4 = simd_shuffle4(
         a,
@@ -1482,7 +1482,7 @@ pub unsafe fn _mm_shuffle_epi32<const imm8: i32>(a: __m128i) -> __m128i {
 #[rustc_legacy_const_generics(1)]
 #[stable(feature = "simd_x86", since = "1.27.0")]
 pub unsafe fn _mm_shufflehi_epi16<const imm8: i32>(a: __m128i) -> __m128i {
-    static_assert!(imm8: i32 where imm8 >= 0 && imm8 <= 255);
+    static_assert_imm8!(imm8);
     let a = a.as_i16x8();
     let x: i16x8 = simd_shuffle8(
         a,
@@ -1514,7 +1514,7 @@ pub unsafe fn _mm_shufflehi_epi16<const imm8: i32>(a: __m128i) -> __m128i {
 #[rustc_legacy_const_generics(1)]
 #[stable(feature = "simd_x86", since = "1.27.0")]
 pub unsafe fn _mm_shufflelo_epi16<const imm8: i32>(a: __m128i) -> __m128i {
-    static_assert!(imm8: i32 where imm8 >= 0 && imm8 <= 255);
+    static_assert_imm8!(imm8);
     let a = a.as_i16x8();
     let x: i16x8 = simd_shuffle8(
         a,