#[cfg(test)]
use stdsimd_test::assert_instr;
use coresimd::simd::*;
use coresimd::simd_llvm::*;
use coresimd::x86::*;
#[stable(feature = "simd_x86", since = "1.27.0")]
pub const _SIDD_UBYTE_OPS: i32 = 0b0000_0000;
#[stable(feature = "simd_x86", since = "1.27.0")]
pub const _SIDD_UWORD_OPS: i32 = 0b0000_0001;
#[stable(feature = "simd_x86", since = "1.27.0")]
pub const _SIDD_SBYTE_OPS: i32 = 0b0000_0010;
#[stable(feature = "simd_x86", since = "1.27.0")]
pub const _SIDD_SWORD_OPS: i32 = 0b0000_0011;
#[stable(feature = "simd_x86", since = "1.27.0")]
pub const _SIDD_CMP_EQUAL_ANY: i32 = 0b0000_0000;
#[stable(feature = "simd_x86", since = "1.27.0")]
pub const _SIDD_CMP_RANGES: i32 = 0b0000_0100;
#[stable(feature = "simd_x86", since = "1.27.0")]
pub const _SIDD_CMP_EQUAL_EACH: i32 = 0b0000_1000;
#[stable(feature = "simd_x86", since = "1.27.0")]
pub const _SIDD_CMP_EQUAL_ORDERED: i32 = 0b0000_1100;
#[stable(feature = "simd_x86", since = "1.27.0")]
pub const _SIDD_POSITIVE_POLARITY: i32 = 0b0000_0000;
#[stable(feature = "simd_x86", since = "1.27.0")]
pub const _SIDD_NEGATIVE_POLARITY: i32 = 0b0001_0000;
#[stable(feature = "simd_x86", since = "1.27.0")]
pub const _SIDD_MASKED_POSITIVE_POLARITY: i32 = 0b0010_0000;
#[stable(feature = "simd_x86", since = "1.27.0")]
pub const _SIDD_MASKED_NEGATIVE_POLARITY: i32 = 0b0011_0000;
#[stable(feature = "simd_x86", since = "1.27.0")]
pub const _SIDD_LEAST_SIGNIFICANT: i32 = 0b0000_0000;
#[stable(feature = "simd_x86", since = "1.27.0")]
pub const _SIDD_MOST_SIGNIFICANT: i32 = 0b0100_0000;
#[stable(feature = "simd_x86", since = "1.27.0")]
pub const _SIDD_BIT_MASK: i32 = 0b0000_0000;
#[stable(feature = "simd_x86", since = "1.27.0")]
pub const _SIDD_UNIT_MASK: i32 = 0b0100_0000;
#[inline]
#[target_feature(enable = "sse4.2")]
#[cfg_attr(test, assert_instr(pcmpistrm, imm8 = 0))]
#[rustc_args_required_const(2)]
#[stable(feature = "simd_x86", since = "1.27.0")]
pub unsafe fn _mm_cmpistrm(a: __m128i, b: __m128i, imm8: i32) -> __m128i {
let a = a.as_i8x16();
let b = b.as_i8x16();
macro_rules! call {
($imm8:expr) => {
pcmpistrm128(a, b, $imm8)
};
}
mem::transmute(constify_imm8!(imm8, call))
}
#[inline]
#[target_feature(enable = "sse4.2")]
#[cfg_attr(test, assert_instr(pcmpistri, imm8 = 0))]
#[rustc_args_required_const(2)]
#[stable(feature = "simd_x86", since = "1.27.0")]
pub unsafe fn _mm_cmpistri(a: __m128i, b: __m128i, imm8: i32) -> i32 {
let a = a.as_i8x16();
let b = b.as_i8x16();
macro_rules! call {
($imm8:expr) => {
pcmpistri128(a, b, $imm8)
};
}
constify_imm8!(imm8, call)
}
#[inline]
#[target_feature(enable = "sse4.2")]
#[cfg_attr(test, assert_instr(pcmpistri, imm8 = 0))]
#[rustc_args_required_const(2)]
#[stable(feature = "simd_x86", since = "1.27.0")]
pub unsafe fn _mm_cmpistrz(a: __m128i, b: __m128i, imm8: i32) -> i32 {
let a = a.as_i8x16();
let b = b.as_i8x16();
macro_rules! call {
($imm8:expr) => {
pcmpistriz128(a, b, $imm8)
};
}
constify_imm8!(imm8, call)
}
#[inline]
#[target_feature(enable = "sse4.2")]
#[cfg_attr(test, assert_instr(pcmpistri, imm8 = 0))]
#[rustc_args_required_const(2)]
#[stable(feature = "simd_x86", since = "1.27.0")]
pub unsafe fn _mm_cmpistrc(a: __m128i, b: __m128i, imm8: i32) -> i32 {
let a = a.as_i8x16();
let b = b.as_i8x16();
macro_rules! call {
($imm8:expr) => {
pcmpistric128(a, b, $imm8)
};
}
constify_imm8!(imm8, call)
}
#[inline]
#[target_feature(enable = "sse4.2")]
#[cfg_attr(test, assert_instr(pcmpistri, imm8 = 0))]
#[rustc_args_required_const(2)]
#[stable(feature = "simd_x86", since = "1.27.0")]
pub unsafe fn _mm_cmpistrs(a: __m128i, b: __m128i, imm8: i32) -> i32 {
let a = a.as_i8x16();
let b = b.as_i8x16();
macro_rules! call {
($imm8:expr) => {
pcmpistris128(a, b, $imm8)
};
}
constify_imm8!(imm8, call)
}
#[inline]
#[target_feature(enable = "sse4.2")]
#[cfg_attr(test, assert_instr(pcmpistri, imm8 = 0))]
#[rustc_args_required_const(2)]
#[stable(feature = "simd_x86", since = "1.27.0")]
pub unsafe fn _mm_cmpistro(a: __m128i, b: __m128i, imm8: i32) -> i32 {
let a = a.as_i8x16();
let b = b.as_i8x16();
macro_rules! call {
($imm8:expr) => {
pcmpistrio128(a, b, $imm8)
};
}
constify_imm8!(imm8, call)
}
#[inline]
#[target_feature(enable = "sse4.2")]
#[cfg_attr(test, assert_instr(pcmpistri, imm8 = 0))]
#[rustc_args_required_const(2)]
#[stable(feature = "simd_x86", since = "1.27.0")]
pub unsafe fn _mm_cmpistra(a: __m128i, b: __m128i, imm8: i32) -> i32 {
let a = a.as_i8x16();
let b = b.as_i8x16();
macro_rules! call {
($imm8:expr) => {
pcmpistria128(a, b, $imm8)
};
}
constify_imm8!(imm8, call)
}
#[inline]
#[target_feature(enable = "sse4.2")]
#[cfg_attr(test, assert_instr(pcmpestrm, imm8 = 0))]
#[rustc_args_required_const(4)]
#[stable(feature = "simd_x86", since = "1.27.0")]
pub unsafe fn _mm_cmpestrm(
a: __m128i, la: i32, b: __m128i, lb: i32, imm8: i32,
) -> __m128i {
let a = a.as_i8x16();
let b = b.as_i8x16();
macro_rules! call {
($imm8:expr) => {
pcmpestrm128(a, la, b, lb, $imm8)
};
}
mem::transmute(constify_imm8!(imm8, call))
}
#[inline]
#[target_feature(enable = "sse4.2")]
#[cfg_attr(test, assert_instr(pcmpestri, imm8 = 0))]
#[rustc_args_required_const(4)]
#[stable(feature = "simd_x86", since = "1.27.0")]
pub unsafe fn _mm_cmpestri(
a: __m128i, la: i32, b: __m128i, lb: i32, imm8: i32,
) -> i32 {
let a = a.as_i8x16();
let b = b.as_i8x16();
macro_rules! call {
($imm8:expr) => {
pcmpestri128(a, la, b, lb, $imm8)
};
}
constify_imm8!(imm8, call)
}
#[inline]
#[target_feature(enable = "sse4.2")]
#[cfg_attr(test, assert_instr(pcmpestri, imm8 = 0))]
#[rustc_args_required_const(4)]
#[stable(feature = "simd_x86", since = "1.27.0")]
pub unsafe fn _mm_cmpestrz(
a: __m128i, la: i32, b: __m128i, lb: i32, imm8: i32,
) -> i32 {
let a = a.as_i8x16();
let b = b.as_i8x16();
macro_rules! call {
($imm8:expr) => {
pcmpestriz128(a, la, b, lb, $imm8)
};
}
constify_imm8!(imm8, call)
}
#[inline]
#[target_feature(enable = "sse4.2")]
#[cfg_attr(test, assert_instr(pcmpestri, imm8 = 0))]
#[rustc_args_required_const(4)]
#[stable(feature = "simd_x86", since = "1.27.0")]
pub unsafe fn _mm_cmpestrc(
a: __m128i, la: i32, b: __m128i, lb: i32, imm8: i32,
) -> i32 {
let a = a.as_i8x16();
let b = b.as_i8x16();
macro_rules! call {
($imm8:expr) => {
pcmpestric128(a, la, b, lb, $imm8)
};
}
constify_imm8!(imm8, call)
}
#[inline]
#[target_feature(enable = "sse4.2")]
#[cfg_attr(test, assert_instr(pcmpestri, imm8 = 0))]
#[rustc_args_required_const(4)]
#[stable(feature = "simd_x86", since = "1.27.0")]
pub unsafe fn _mm_cmpestrs(
a: __m128i, la: i32, b: __m128i, lb: i32, imm8: i32,
) -> i32 {
let a = a.as_i8x16();
let b = b.as_i8x16();
macro_rules! call {
($imm8:expr) => {
pcmpestris128(a, la, b, lb, $imm8)
};
}
constify_imm8!(imm8, call)
}
#[inline]
#[target_feature(enable = "sse4.2")]
#[cfg_attr(test, assert_instr(pcmpestri, imm8 = 0))]
#[rustc_args_required_const(4)]
#[stable(feature = "simd_x86", since = "1.27.0")]
pub unsafe fn _mm_cmpestro(
a: __m128i, la: i32, b: __m128i, lb: i32, imm8: i32,
) -> i32 {
let a = a.as_i8x16();
let b = b.as_i8x16();
macro_rules! call {
($imm8:expr) => {
pcmpestrio128(a, la, b, lb, $imm8)
};
}
constify_imm8!(imm8, call)
}
#[inline]
#[target_feature(enable = "sse4.2")]
#[cfg_attr(test, assert_instr(pcmpestri, imm8 = 0))]
#[rustc_args_required_const(4)]
#[stable(feature = "simd_x86", since = "1.27.0")]
pub unsafe fn _mm_cmpestra(
a: __m128i, la: i32, b: __m128i, lb: i32, imm8: i32,
) -> i32 {
let a = a.as_i8x16();
let b = b.as_i8x16();
macro_rules! call {
($imm8:expr) => {
pcmpestria128(a, la, b, lb, $imm8)
};
}
constify_imm8!(imm8, call)
}
#[inline]
#[target_feature(enable = "sse4.2")]
#[cfg_attr(test, assert_instr(crc32))]
#[stable(feature = "simd_x86", since = "1.27.0")]
pub unsafe fn _mm_crc32_u8(crc: u32, v: u8) -> u32 {
crc32_32_8(crc, v)
}
#[inline]
#[target_feature(enable = "sse4.2")]
#[cfg_attr(test, assert_instr(crc32))]
#[stable(feature = "simd_x86", since = "1.27.0")]
pub unsafe fn _mm_crc32_u16(crc: u32, v: u16) -> u32 {
crc32_32_16(crc, v)
}
#[inline]
#[target_feature(enable = "sse4.2")]
#[cfg_attr(test, assert_instr(crc32))]
#[stable(feature = "simd_x86", since = "1.27.0")]
pub unsafe fn _mm_crc32_u32(crc: u32, v: u32) -> u32 {
crc32_32_32(crc, v)
}
#[inline]
#[target_feature(enable = "sse4.2")]
#[cfg_attr(test, assert_instr(pcmpgtq))]
#[stable(feature = "simd_x86", since = "1.27.0")]
pub unsafe fn _mm_cmpgt_epi64(a: __m128i, b: __m128i) -> __m128i {
mem::transmute(simd_gt::<_, i64x2>(a.as_i64x2(), b.as_i64x2()))
}
#[allow(improper_ctypes)]
extern "C" {
#[link_name = "llvm.x86.sse42.pcmpestrm128"]
fn pcmpestrm128(a: i8x16, la: i32, b: i8x16, lb: i32, imm8: i8) -> u8x16;
#[link_name = "llvm.x86.sse42.pcmpestri128"]
fn pcmpestri128(a: i8x16, la: i32, b: i8x16, lb: i32, imm8: i8) -> i32;
#[link_name = "llvm.x86.sse42.pcmpestriz128"]
fn pcmpestriz128(a: i8x16, la: i32, b: i8x16, lb: i32, imm8: i8) -> i32;
#[link_name = "llvm.x86.sse42.pcmpestric128"]
fn pcmpestric128(a: i8x16, la: i32, b: i8x16, lb: i32, imm8: i8) -> i32;
#[link_name = "llvm.x86.sse42.pcmpestris128"]
fn pcmpestris128(a: i8x16, la: i32, b: i8x16, lb: i32, imm8: i8) -> i32;
#[link_name = "llvm.x86.sse42.pcmpestrio128"]
fn pcmpestrio128(a: i8x16, la: i32, b: i8x16, lb: i32, imm8: i8) -> i32;
#[link_name = "llvm.x86.sse42.pcmpestria128"]
fn pcmpestria128(a: i8x16, la: i32, b: i8x16, lb: i32, imm8: i8) -> i32;
#[link_name = "llvm.x86.sse42.pcmpistrm128"]
fn pcmpistrm128(a: i8x16, b: i8x16, imm8: i8) -> i8x16;
#[link_name = "llvm.x86.sse42.pcmpistri128"]
fn pcmpistri128(a: i8x16, b: i8x16, imm8: i8) -> i32;
#[link_name = "llvm.x86.sse42.pcmpistriz128"]
fn pcmpistriz128(a: i8x16, b: i8x16, imm8: i8) -> i32;
#[link_name = "llvm.x86.sse42.pcmpistric128"]
fn pcmpistric128(a: i8x16, b: i8x16, imm8: i8) -> i32;
#[link_name = "llvm.x86.sse42.pcmpistris128"]
fn pcmpistris128(a: i8x16, b: i8x16, imm8: i8) -> i32;
#[link_name = "llvm.x86.sse42.pcmpistrio128"]
fn pcmpistrio128(a: i8x16, b: i8x16, imm8: i8) -> i32;
#[link_name = "llvm.x86.sse42.pcmpistria128"]
fn pcmpistria128(a: i8x16, b: i8x16, imm8: i8) -> i32;
#[link_name = "llvm.x86.sse42.crc32.32.8"]
fn crc32_32_8(crc: u32, v: u8) -> u32;
#[link_name = "llvm.x86.sse42.crc32.32.16"]
fn crc32_32_16(crc: u32, v: u16) -> u32;
#[link_name = "llvm.x86.sse42.crc32.32.32"]
fn crc32_32_32(crc: u32, v: u32) -> u32;
}
#[cfg(test)]
mod tests {
use stdsimd_test::simd_test;
use coresimd::x86::*;
use std::ptr;
#[target_feature(enable = "sse4.2")]
unsafe fn str_to_m128i(s: &[u8]) -> __m128i {
assert!(s.len() <= 16);
let slice = &mut [0u8; 16];
ptr::copy_nonoverlapping(
s.get_unchecked(0) as *const u8 as *const u8,
slice.get_unchecked_mut(0) as *mut u8 as *mut u8,
s.len(),
);
_mm_loadu_si128(slice.as_ptr() as *const _)
}
#[simd_test(enable = "sse4.2")]
unsafe fn test_mm_cmpistrm() {
let a = str_to_m128i(b"Hello! Good-Bye!");
let b = str_to_m128i(b"hello! good-bye!");
let i = _mm_cmpistrm(a, b, _SIDD_UNIT_MASK);
#[cfg_attr(rustfmt, rustfmt_skip)]
let res = _mm_setr_epi8(
0x00, !0, !0, !0, !0, !0, !0, 0x00,
!0, !0, !0, !0, 0x00, !0, !0, !0,
);
assert_eq_m128i(i, res);
}
#[simd_test(enable = "sse4.2")]
unsafe fn test_mm_cmpistri() {
let a = str_to_m128i(b"Hello");
let b = str_to_m128i(b" Hello ");
let i = _mm_cmpistri(a, b, _SIDD_CMP_EQUAL_ORDERED);
assert_eq!(3, i);
}
#[simd_test(enable = "sse4.2")]
unsafe fn test_mm_cmpistrz() {
let a = str_to_m128i(b"");
let b = str_to_m128i(b"Hello");
let i = _mm_cmpistrz(a, b, _SIDD_CMP_EQUAL_ORDERED);
assert_eq!(1, i);
}
#[simd_test(enable = "sse4.2")]
unsafe fn test_mm_cmpistrc() {
let a = str_to_m128i(b" ");
let b = str_to_m128i(b" ! ");
let i = _mm_cmpistrc(a, b, _SIDD_UNIT_MASK);
assert_eq!(1, i);
}
#[simd_test(enable = "sse4.2")]
unsafe fn test_mm_cmpistrs() {
let a = str_to_m128i(b"Hello");
let b = str_to_m128i(b"");
let i = _mm_cmpistrs(a, b, _SIDD_CMP_EQUAL_ORDERED);
assert_eq!(1, i);
}
#[simd_test(enable = "sse4.2")]
unsafe fn test_mm_cmpistro() {
#[cfg_attr(rustfmt, rustfmt_skip)]
let a_bytes = _mm_setr_epi8(
0x00, 0x47, 0x00, 0x65, 0x00, 0x6c, 0x00, 0x6c,
0x00, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
);
#[cfg_attr(rustfmt, rustfmt_skip)]
let b_bytes = _mm_setr_epi8(
0x00, 0x48, 0x00, 0x65, 0x00, 0x6c, 0x00, 0x6c,
0x00, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
);
let a = a_bytes;
let b = b_bytes;
let i = _mm_cmpistro(a, b, _SIDD_UWORD_OPS | _SIDD_UNIT_MASK);
assert_eq!(0, i);
}
#[simd_test(enable = "sse4.2")]
unsafe fn test_mm_cmpistra() {
let a = str_to_m128i(b"");
let b = str_to_m128i(b"Hello!!!!!!!!!!!");
let i = _mm_cmpistra(a, b, _SIDD_UNIT_MASK);
assert_eq!(1, i);
}
#[simd_test(enable = "sse4.2")]
unsafe fn test_mm_cmpestrm() {
let a = str_to_m128i(b"Hello!");
let b = str_to_m128i(b"Hello.");
let i = _mm_cmpestrm(a, 5, b, 5, _SIDD_UNIT_MASK);
#[cfg_attr(rustfmt, rustfmt_skip)]
let r = _mm_setr_epi8(
!0, !0, !0, !0, !0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
);
assert_eq_m128i(i, r);
}
#[simd_test(enable = "sse4.2")]
unsafe fn test_mm_cmpestri() {
let a = str_to_m128i(b"bar - garbage");
let b = str_to_m128i(b"foobar");
let i = _mm_cmpestri(a, 3, b, 6, _SIDD_CMP_EQUAL_ORDERED);
assert_eq!(3, i);
}
#[simd_test(enable = "sse4.2")]
unsafe fn test_mm_cmpestrz() {
let a = str_to_m128i(b"");
let b = str_to_m128i(b"Hello");
let i = _mm_cmpestrz(a, 16, b, 6, _SIDD_CMP_EQUAL_ORDERED);
assert_eq!(1, i);
}
#[simd_test(enable = "sse4.2")]
unsafe fn test_mm_cmpestrc() {
let va = str_to_m128i(b"!!!!!!!!");
let vb = str_to_m128i(b" ");
let i = _mm_cmpestrc(va, 7, vb, 7, _SIDD_UNIT_MASK);
assert_eq!(0, i);
}
#[simd_test(enable = "sse4.2")]
unsafe fn test_mm_cmpestrs() {
#[cfg_attr(rustfmt, rustfmt_skip)]
let a_bytes = _mm_setr_epi8(
0x00, 0x48, 0x00, 0x65, 0x00, 0x6c, 0x00, 0x6c,
0x00, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
);
let a = a_bytes;
let b = _mm_set1_epi8(0x00);
let i = _mm_cmpestrs(a, 8, b, 0, _SIDD_UWORD_OPS);
assert_eq!(0, i);
}
#[simd_test(enable = "sse4.2")]
unsafe fn test_mm_cmpestro() {
let a = str_to_m128i(b"Hello");
let b = str_to_m128i(b"World");
let i = _mm_cmpestro(a, 5, b, 5, _SIDD_UBYTE_OPS);
assert_eq!(0, i);
}
#[simd_test(enable = "sse4.2")]
unsafe fn test_mm_cmpestra() {
let a = str_to_m128i(b"Cannot match a");
let b = str_to_m128i(b"Null after 14");
let i =
_mm_cmpestra(a, 14, b, 16, _SIDD_CMP_EQUAL_EACH | _SIDD_UNIT_MASK);
assert_eq!(1, i);
}
#[simd_test(enable = "sse4.2")]
unsafe fn test_mm_crc32_u8() {
let crc = 0x2aa1e72b;
let v = 0x2a;
let i = _mm_crc32_u8(crc, v);
assert_eq!(i, 0xf24122e4);
}
#[simd_test(enable = "sse4.2")]
unsafe fn test_mm_crc32_u16() {
let crc = 0x8ecec3b5;
let v = 0x22b;
let i = _mm_crc32_u16(crc, v);
assert_eq!(i, 0x13bb2fb);
}
#[simd_test(enable = "sse4.2")]
unsafe fn test_mm_crc32_u32() {
let crc = 0xae2912c8;
let v = 0x845fed;
let i = _mm_crc32_u32(crc, v);
assert_eq!(i, 0xffae2ed1);
}
#[simd_test(enable = "sse4.2")]
unsafe fn test_mm_cmpgt_epi64() {
let a = _mm_setr_epi64x(0, 0x2a);
let b = _mm_set1_epi64x(0x00);
let i = _mm_cmpgt_epi64(a, b);
assert_eq_m128i(
i,
_mm_setr_epi64x(0x00, 0xffffffffffffffffu64 as i64),
);
}
}