Skip to content

Commit 348592f

Browse files
folkertdevAmanieu
authored andcommitted
add vec_mergel and vec_mergeh
1 parent 31f15d5 commit 348592f

File tree

1 file changed

+142
-0
lines changed

1 file changed

+142
-0
lines changed

crates/core_arch/src/s390x/vector.rs

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1120,6 +1120,114 @@ mod sealed {
11201120
transmute(transmute::<_, vector_signed_long_long>(self).vec_revb())
11211121
}
11221122
}
1123+
1124+
#[repr(simd)]
1125+
struct MergeMask<const N: usize>([u32; N]);
1126+
1127+
impl<const N: usize> MergeMask<N> {
1128+
const fn merge_low() -> Self {
1129+
let mut mask = [0; N];
1130+
let mut i = N / 2;
1131+
let mut index = 0;
1132+
while index < N {
1133+
mask[index] = i as u32;
1134+
mask[index + 1] = (i + N) as u32;
1135+
1136+
i += 1;
1137+
index += 2;
1138+
}
1139+
MergeMask(mask)
1140+
}
1141+
1142+
const fn merge_high() -> Self {
1143+
let mut mask = [0; N];
1144+
let mut i = 0;
1145+
let mut index = 0;
1146+
while index < N {
1147+
mask[index] = i as u32;
1148+
mask[index + 1] = (i + N) as u32;
1149+
1150+
i += 1;
1151+
index += 2;
1152+
}
1153+
MergeMask(mask)
1154+
}
1155+
}
1156+
1157+
#[unstable(feature = "stdarch_s390x", issue = "135681")]
1158+
pub trait VectorMergel {
1159+
unsafe fn vec_mergel(self, other: Self) -> Self;
1160+
}
1161+
1162+
#[unstable(feature = "stdarch_s390x", issue = "135681")]
1163+
pub trait VectorMergeh {
1164+
unsafe fn vec_mergeh(self, other: Self) -> Self;
1165+
}
1166+
1167+
macro_rules! impl_merge {
1168+
($($ty:ident, $mergel:ident, $mergeh:ident),*) => {
1169+
$(
1170+
#[inline]
1171+
#[target_feature(enable = "vector")]
1172+
#[cfg_attr(test, assert_instr($mergel))]
1173+
unsafe fn $mergel(a: $ty, b: $ty) -> $ty {
1174+
const N: usize = core::mem::size_of::<$ty>() / core::mem::size_of::<l_t_t!($ty)>();
1175+
simd_shuffle(a, b, const { MergeMask::<N>::merge_low() })
1176+
}
1177+
1178+
#[unstable(feature = "stdarch_s390x", issue = "135681")]
1179+
impl VectorMergel for $ty {
1180+
#[inline]
1181+
#[target_feature(enable = "vector")]
1182+
unsafe fn vec_mergel(self, other: Self) -> Self {
1183+
$mergel(self, other)
1184+
}
1185+
}
1186+
1187+
#[unstable(feature = "stdarch_s390x", issue = "135681")]
1188+
impl VectorMergel for t_u!($ty) {
1189+
#[inline]
1190+
#[target_feature(enable = "vector")]
1191+
unsafe fn vec_mergel(self, other: Self) -> Self {
1192+
transmute($mergel(transmute(self), transmute(other)))
1193+
}
1194+
}
1195+
1196+
#[inline]
1197+
#[target_feature(enable = "vector")]
1198+
#[cfg_attr(test, assert_instr($mergeh))]
1199+
unsafe fn $mergeh(a: $ty, b: $ty) -> $ty {
1200+
const N: usize = core::mem::size_of::<$ty>() / core::mem::size_of::<l_t_t!($ty)>();
1201+
simd_shuffle(a, b, const { MergeMask::<N>::merge_high() })
1202+
}
1203+
1204+
#[unstable(feature = "stdarch_s390x", issue = "135681")]
1205+
impl VectorMergeh for $ty {
1206+
#[inline]
1207+
#[target_feature(enable = "vector")]
1208+
unsafe fn vec_mergeh(self, other: Self) -> Self {
1209+
$mergeh(self, other)
1210+
}
1211+
}
1212+
1213+
#[unstable(feature = "stdarch_s390x", issue = "135681")]
1214+
impl VectorMergeh for t_u!($ty) {
1215+
#[inline]
1216+
#[target_feature(enable = "vector")]
1217+
unsafe fn vec_mergeh(self, other: Self) -> Self {
1218+
transmute($mergeh(transmute(self), transmute(other)))
1219+
}
1220+
}
1221+
)*
1222+
}
1223+
}
1224+
1225+
impl_merge! {
1226+
vector_signed_char, vmrlb, vmrhb,
1227+
vector_signed_short, vmrlh, vmrhh,
1228+
vector_signed_int, vmrlf, vmrhf,
1229+
vector_signed_long_long, vmrlg, vmrhg
1230+
}
11231231
}
11241232

11251233
/// Vector element-wise addition.
@@ -1602,6 +1710,28 @@ where
16021710
a.vec_revb()
16031711
}
16041712

1713+
/// Merges the most significant ("high") halves of two vectors.
1714+
#[inline]
1715+
#[target_feature(enable = "vector")]
1716+
#[unstable(feature = "stdarch_s390x", issue = "135681")]
1717+
pub unsafe fn vec_mergeh<T>(a: T, b: T) -> T
1718+
where
1719+
T: sealed::VectorMergeh,
1720+
{
1721+
a.vec_mergeh(b)
1722+
}
1723+
1724+
/// Merges the least significant ("low") halves of two vectors.
1725+
#[inline]
1726+
#[target_feature(enable = "vector")]
1727+
#[unstable(feature = "stdarch_s390x", issue = "135681")]
1728+
pub unsafe fn vec_mergel<T>(a: T, b: T) -> T
1729+
where
1730+
T: sealed::VectorMergel,
1731+
{
1732+
a.vec_mergel(b)
1733+
}
1734+
16051735
#[cfg(test)]
16061736
mod tests {
16071737
use super::*;
@@ -1967,4 +2097,16 @@ mod tests {
19672097
[0xAABBCCDD, 0xEEFF0011, 0x22334455, 0x66778899],
19682098
[0xDDCCBBAA, 0x1100FFEE, 0x55443322, 0x99887766]
19692099
}
2100+
2101+
test_vec_2! { test_vec_mergeh_u32, vec_mergeh, u32x4,
2102+
[0xAAAAAAAA, 0xBBBBBBBB, 0xCCCCCCCC, 0xDDDDDDDD],
2103+
[0x00000000, 0x11111111, 0x22222222, 0x33333333],
2104+
[0xAAAAAAAA, 0x00000000, 0xBBBBBBBB, 0x11111111]
2105+
}
2106+
2107+
test_vec_2! { test_vec_mergel_u32, vec_mergel, u32x4,
2108+
[0xAAAAAAAA, 0xBBBBBBBB, 0xCCCCCCCC, 0xDDDDDDDD],
2109+
[0x00000000, 0x11111111, 0x22222222, 0x33333333],
2110+
[0xCCCCCCCC, 0x22222222, 0xDDDDDDDD, 0x33333333]
2111+
}
19702112
}

0 commit comments

Comments
 (0)