Skip to content

Commit f576f59

Browse files
fulmicotonBurntSushi
authored andcommitted
Implementing _mm_shuffle_epi8. (rust-lang#18)
Implementing `_mm_shuffle_epi8`.
1 parent d717ec0 commit f576f59

File tree

2 files changed

+47
-1
lines changed

2 files changed

+47
-1
lines changed

TODO.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,7 @@ ssse3
422422
* [ ] `_mm_abs_epi16`
423423
* [ ] `_mm_abs_pi32`
424424
* [ ] `_mm_abs_epi32`
425-
* [ ] `_mm_shuffle_epi8`
425+
* [x] `_mm_shuffle_epi8`
426426
* [ ] `_mm_shuffle_pi8`
427427
* [ ] `_mm_alignr_epi8`
428428
* [ ] `_mm_alignr_pi8`

src/x86/ssse3.rs

+46
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,46 @@ pub fn _mm_abs_epi8(a: i8x16) -> u8x16 {
88
unsafe { pabsb128(a) }
99
}
1010

11+
12+
13+
/// Shuffle bytes from `a` according to the content of `b`.
14+
///
15+
/// The last 4 bits of each byte of `b` are used as addresses
16+
/// into the 16 bytes of `a`.
17+
///
18+
/// In addition, if the highest significant bit of a byte of `b`
19+
/// is set, the respective destination byte is set to 0.
20+
///
21+
/// Picturing `a` and `b` as `[u8; 16]`, `_mm_shuffle_epi8` is
22+
/// logically equivalent to:
23+
///
24+
/// ```
25+
/// fn mm_shuffle_epi8(a: [u8; 16], b: [u8; 16]) -> [u8; 16] {
26+
/// let mut r = [0u8; 16];
27+
/// for i in 0..16 {
28+
/// // if the most significant bit of b is set,
29+
/// // then the destination byte is set to 0.
30+
/// if b[i] & 0x80 == 0u8 {
31+
/// r[i] = a[(b[i] % 16) as usize];
32+
/// }
33+
/// }
34+
/// r
35+
/// }
36+
/// ```
37+
#[inline(always)]
38+
#[target_feature = "+ssse3"]
39+
pub fn _mm_shuffle_epi8(a: u8x16, b: u8x16) -> u8x16 {
40+
unsafe { pshufb128(a, b) }
41+
}
42+
43+
1144
#[allow(improper_ctypes)]
1245
extern {
1346
#[link_name = "llvm.x86.ssse3.pabs.b.128"]
1447
fn pabsb128(a: i8x16) -> u8x16;
48+
49+
#[link_name = "llvm.x86.ssse3.pshuf.b.128"]
50+
fn pshufb128(a: u8x16, b: u8x16) -> u8x16;
1551
}
1652

1753
#[cfg(test)]
@@ -25,4 +61,14 @@ mod tests {
2561
let r = ssse3::_mm_abs_epi8(i8x16::splat(-5));
2662
assert_eq!(r, u8x16::splat(5));
2763
}
64+
65+
#[test]
66+
#[target_feature = "+ssse3"]
67+
fn _mm_shuffle_epi8() {
68+
let a = u8x16::new(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
69+
let b = u8x16::new(4, 128, 4, 3, 24, 12, 6, 19, 12, 5, 5, 10, 4, 1, 8, 0);
70+
let expected = u8x16::new(5, 0, 5, 4, 9, 13, 7, 4, 13, 6, 6, 11, 5, 2, 9, 1);
71+
let r = ssse3::_mm_shuffle_epi8(a, b);
72+
assert_eq!(r, expected);
73+
}
2874
}

0 commit comments

Comments
 (0)