Skip to content

Commit a04b8e2

Browse files
folkertdevAmanieu
authored andcommitted
add vec_genmask and vec_genmasks
1 parent 3392f21 commit a04b8e2

File tree

1 file changed

+109
-0
lines changed

1 file changed

+109
-0
lines changed

crates/core_arch/src/s390x/vector.rs

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,39 @@ impl<const N: usize> ShuffleMask<N> {
154154
}
155155
}
156156

157+
const fn genmask<const MASK: u16>() -> [u8; 16] {
158+
let mut bits = MASK;
159+
let mut elements = [0u8; 16];
160+
161+
let mut i = 0;
162+
while i < 16 {
163+
elements[i] = match bits & (1u16 << 15) {
164+
0 => 0,
165+
_ => 0xFF,
166+
};
167+
168+
bits <<= 1;
169+
i += 1;
170+
}
171+
172+
elements
173+
}
174+
175+
const fn genmasks(bit_width: u32, a: u8, b: u8) -> u64 {
176+
let bit_width = bit_width as u8;
177+
let a = a % bit_width;
178+
let mut b = b % bit_width;
179+
if a > b {
180+
b = bit_width - 1;
181+
}
182+
183+
// of course these indices start from the left
184+
let a = (bit_width - 1) - a;
185+
let b = (bit_width - 1) - b;
186+
187+
((1u64.wrapping_shl(a as u32 + 1)) - 1) & !((1u64.wrapping_shl(b as u32)) - 1)
188+
}
189+
157190
#[macro_use]
158191
mod sealed {
159192
use super::*;
@@ -1727,6 +1760,52 @@ where
17271760
a.vec_mergel(b)
17281761
}
17291762

1763+
/// Generates byte masks for elements in the return vector. For each bit in a, if the bit is one, all bit positions
1764+
/// in the corresponding byte element of d are set to ones. Otherwise, if the bit is zero, the corresponding byte element is set to zero.
1765+
#[inline]
1766+
#[target_feature(enable = "vector")]
1767+
#[unstable(feature = "stdarch_s390x", issue = "135681")]
1768+
#[cfg_attr(test, assert_instr(vgbm, MASK = 0x00FF))]
1769+
pub unsafe fn vec_genmask<const MASK: u16>() -> vector_unsigned_char {
1770+
vector_unsigned_char(const { genmask::<MASK>() })
1771+
}
1772+
1773+
/// Vector Generate Mask (Byte)
1774+
#[inline]
1775+
#[target_feature(enable = "vector")]
1776+
#[unstable(feature = "stdarch_s390x", issue = "135681")]
1777+
#[cfg_attr(test, assert_instr(vrepib, L = 3, H = 5))]
1778+
pub unsafe fn vec_genmasks_8<const L: u8, const H: u8>() -> vector_unsigned_char {
1779+
vector_unsigned_char(const { [genmasks(u8::BITS, L, H) as u8; 16] })
1780+
}
1781+
1782+
/// Vector Generate Mask (Halfword)
1783+
#[inline]
1784+
#[target_feature(enable = "vector")]
1785+
#[unstable(feature = "stdarch_s390x", issue = "135681")]
1786+
#[cfg_attr(test, assert_instr(vrepih, L = 3, H = 5))]
1787+
pub unsafe fn vec_genmasks_16<const L: u8, const H: u8>() -> vector_unsigned_short {
1788+
vector_unsigned_short(const { [genmasks(u16::BITS, L, H) as u16; 8] })
1789+
}
1790+
1791+
/// Vector Generate Mask (Word)
1792+
#[inline]
1793+
#[target_feature(enable = "vector")]
1794+
#[unstable(feature = "stdarch_s390x", issue = "135681")]
1795+
#[cfg_attr(test, assert_instr(vgmf, L = 3, H = 5))]
1796+
pub unsafe fn vec_genmasks_32<const L: u8, const H: u8>() -> vector_unsigned_int {
1797+
vector_unsigned_int(const { [genmasks(u32::BITS, L, H) as u32; 4] })
1798+
}
1799+
1800+
/// Vector Generate Mask (Doubleword)
1801+
#[inline]
1802+
#[target_feature(enable = "vector")]
1803+
#[unstable(feature = "stdarch_s390x", issue = "135681")]
1804+
#[cfg_attr(test, assert_instr(vgmg, L = 3, H = 5))]
1805+
pub unsafe fn vec_genmasks_64<const L: u8, const H: u8>() -> vector_unsigned_long_long {
1806+
vector_unsigned_long_long(const { [genmasks(u64::BITS, L, H); 2] })
1807+
}
1808+
17301809
#[cfg(test)]
17311810
mod tests {
17321811
use super::*;
@@ -1751,6 +1830,36 @@ mod tests {
17511830
assert_eq!(ShuffleMask::<4>::merge_high().0, [0, 4, 1, 5]);
17521831
}
17531832

1833+
#[test]
1834+
fn test_vec_mask() {
1835+
assert_eq!(
1836+
genmask::<0x00FF>(),
1837+
[
1838+
0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
1839+
]
1840+
);
1841+
}
1842+
1843+
#[test]
1844+
fn test_genmasks() {
1845+
assert_eq!(genmasks(u8::BITS, 3, 5), 28);
1846+
assert_eq!(genmasks(u8::BITS, 3, 7), 31);
1847+
1848+
// If a or b is greater than 8, the operation is performed as if the value gets modulo by 8.
1849+
assert_eq!(genmasks(u8::BITS, 3 + 8, 7 + 8), 31);
1850+
// If a is greater than b, the operation is perform as if b equals 7.
1851+
assert_eq!(genmasks(u8::BITS, 5, 4), genmasks(u8::BITS, 5, 7));
1852+
1853+
assert_eq!(
1854+
genmasks(u16::BITS, 4, 12) as u16,
1855+
u16::from_be_bytes([15, -8i8 as u8])
1856+
);
1857+
assert_eq!(
1858+
genmasks(u32::BITS, 4, 29) as u32,
1859+
u32::from_be_bytes([15, 0xFF, 0xFF, -4i8 as u8])
1860+
);
1861+
}
1862+
17541863
macro_rules! test_vec_1 {
17551864
{ $name: ident, $fn:ident, f32x4, [$($a:expr),+], ~[$($d:expr),+] } => {
17561865
#[simd_test(enable = "vector")]

0 commit comments

Comments
 (0)