Add vec_mergel and vec_mergeh

This commit is contained in:
Luca Barbato
2023-04-30 17:42:15 +00:00
committed by Amanieu d'Antras
parent 1dcba9edde
commit 7b080559bb
2 changed files with 157 additions and 0 deletions

View File

@@ -2002,6 +2002,142 @@ mod sealed {
vec_ctf_u32::<IMM5>(self)
}
}
#[inline]
#[target_feature(enable = "altivec")]
#[cfg_attr(all(test, target_endian = "little"), assert_instr(vmrghb))]
#[cfg_attr(all(test, target_endian = "big"), assert_instr(vmrglb))]
unsafe fn vec_vmrglb(a: vector_signed_char, b: vector_signed_char) -> vector_signed_char {
let mergel_perm = transmute(u8x16::new(
0x08, 0x18, 0x09, 0x19, 0x0A, 0x1A, 0x0B, 0x1B, 0x0C, 0x1C, 0x0D, 0x1D, 0x0E, 0x1E,
0x0F, 0x1F,
));
vec_perm(a, b, mergel_perm)
}
#[inline]
#[target_feature(enable = "altivec")]
#[cfg_attr(all(test, target_endian = "little"), assert_instr(vmrghh))]
#[cfg_attr(all(test, target_endian = "big"), assert_instr(vmrglh))]
unsafe fn vec_vmrglh(a: vector_signed_short, b: vector_signed_short) -> vector_signed_short {
let mergel_perm = transmute(u8x16::new(
0x08, 0x09, 0x18, 0x19, 0x0A, 0x0B, 0x1A, 0x1B, 0x0C, 0x0D, 0x1C, 0x1D, 0x0E, 0x0F,
0x1E, 0x1F,
));
vec_perm(a, b, mergel_perm)
}
#[inline]
#[target_feature(enable = "altivec")]
#[cfg_attr(
all(test, target_endian = "little", not(target_feature = "vsx")),
assert_instr(vmrghw)
)]
#[cfg_attr(
all(test, target_endian = "little", target_feature = "vsx"),
assert_instr(xxmrghw)
)]
#[cfg_attr(
all(test, target_endian = "big", not(target_feature = "vsx")),
assert_instr(vmrglw)
)]
#[cfg_attr(
all(test, target_endian = "big", target_feature = "vsx"),
assert_instr(xxmrglw)
)]
unsafe fn vec_vmrglw(a: vector_signed_int, b: vector_signed_int) -> vector_signed_int {
let mergel_perm = transmute(u8x16::new(
0x08, 0x09, 0x0A, 0x0B, 0x18, 0x19, 0x1A, 0x1B, 0x0C, 0x0D, 0x0E, 0x0F, 0x1C, 0x1D,
0x1E, 0x1F,
));
vec_perm(a, b, mergel_perm)
}
#[inline]
#[target_feature(enable = "altivec")]
#[cfg_attr(all(test, target_endian = "little"), assert_instr(vmrglb))]
#[cfg_attr(all(test, target_endian = "big"), assert_instr(vmrghb))]
unsafe fn vec_vmrghb(a: vector_signed_char, b: vector_signed_char) -> vector_signed_char {
let mergel_perm = transmute(u8x16::new(
0x00, 0x10, 0x01, 0x11, 0x02, 0x12, 0x03, 0x13, 0x04, 0x14, 0x05, 0x15, 0x06, 0x16,
0x07, 0x17,
));
vec_perm(a, b, mergel_perm)
}
#[inline]
#[target_feature(enable = "altivec")]
#[cfg_attr(all(test, target_endian = "little"), assert_instr(vmrglh))]
#[cfg_attr(all(test, target_endian = "big"), assert_instr(vmrghh))]
unsafe fn vec_vmrghh(a: vector_signed_short, b: vector_signed_short) -> vector_signed_short {
let mergel_perm = transmute(u8x16::new(
0x00, 0x01, 0x10, 0x11, 0x02, 0x03, 0x12, 0x13, 0x04, 0x05, 0x14, 0x15, 0x06, 0x07,
0x16, 0x17,
));
vec_perm(a, b, mergel_perm)
}
#[inline]
#[target_feature(enable = "altivec")]
#[cfg_attr(
all(test, target_endian = "little", not(target_feature = "vsx")),
assert_instr(vmrglw)
)]
#[cfg_attr(
all(test, target_endian = "little", target_feature = "vsx"),
assert_instr(xxmrglw)
)]
#[cfg_attr(
all(test, target_endian = "big", not(target_feature = "vsx")),
assert_instr(vmrghw)
)]
#[cfg_attr(
all(test, target_endian = "big", target_feature = "vsx"),
assert_instr(xxmrghw)
)]
unsafe fn vec_vmrghw(a: vector_signed_int, b: vector_signed_int) -> vector_signed_int {
let mergel_perm = transmute(u8x16::new(
0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13, 0x04, 0x05, 0x06, 0x07, 0x14, 0x15,
0x16, 0x17,
));
vec_perm(a, b, mergel_perm)
}
pub trait VectorMergeh<Other> {
type Result;
unsafe fn vec_mergeh(self, b: Other) -> Self::Result;
}
impl_vec_trait! { [VectorMergeh vec_mergeh]+ 2b (vec_vmrghb, vec_vmrghh, vec_vmrghw) }
impl_vec_trait! { [VectorMergeh vec_mergeh]+ vec_vmrghw (vector_float, vector_float) -> vector_float }
pub trait VectorMergel<Other> {
type Result;
unsafe fn vec_mergel(self, b: Other) -> Self::Result;
}
impl_vec_trait! { [VectorMergel vec_mergel]+ 2b (vec_vmrglb, vec_vmrglh, vec_vmrglw) }
impl_vec_trait! { [VectorMergel vec_mergel]+ vec_vmrglw (vector_float, vector_float) -> vector_float }
}
/// Vector Merge Low
#[inline]
#[target_feature(enable = "altivec")]
pub unsafe fn vec_mergel<T, U>(a: T, b: U) -> <T as sealed::VectorMergel<U>>::Result
where
T: sealed::VectorMergel<U>,
{
a.vec_mergel(b)
}
/// Vector Merge High
#[inline]
#[target_feature(enable = "altivec")]
pub unsafe fn vec_mergeh<T, U>(a: T, b: U) -> <T as sealed::VectorMergeh<U>>::Result
where
T: sealed::VectorMergeh<U>,
{
a.vec_mergeh(b)
}
/// Vector Load Indexed.

View File

@@ -58,6 +58,16 @@ macro_rules! impl_vec_trait {
}
}
};
([$Trait:ident $m:ident]+ $fun:ident ($a:ty, $b:ty) -> $r:ty) => {
impl $Trait<$b> for $a {
type Result = $r;
#[inline]
#[target_feature(enable = "altivec")]
unsafe fn $m(self, b: $b) -> Self::Result {
transmute($fun(transmute(self), transmute(b)))
}
}
};
([$Trait:ident $m:ident] $fun:ident ($a:ty, ~$b:ty) -> $r:ty) => {
impl_vec_trait!{ [$Trait $m] $fun ($a, $a) -> $r }
impl_vec_trait!{ [$Trait $m] $fun ($a, $b) -> $r }
@@ -84,5 +94,16 @@ macro_rules! impl_vec_trait {
};
([$Trait:ident $m:ident] 2 ($fn:ident)) => {
impl_vec_trait!{ [$Trait $m] ($fn, $fn, $fn, $fn, $fn, $fn) }
};
([$Trait:ident $m:ident]+ 2b ($b:ident, $h:ident, $w:ident)) => {
impl_vec_trait!{ [$Trait $m]+ $b (vector_bool_char, vector_bool_char) -> vector_bool_char }
impl_vec_trait!{ [$Trait $m]+ $b (vector_unsigned_char, vector_unsigned_char) -> vector_unsigned_char }
impl_vec_trait!{ [$Trait $m]+ $b (vector_signed_char, vector_signed_char) -> vector_signed_char }
impl_vec_trait!{ [$Trait $m]+ $h (vector_bool_short, vector_bool_short) -> vector_bool_short }
impl_vec_trait!{ [$Trait $m]+ $h (vector_unsigned_short, vector_unsigned_short) -> vector_unsigned_short }
impl_vec_trait!{ [$Trait $m]+ $h (vector_signed_short, vector_signed_short) -> vector_signed_short }
impl_vec_trait!{ [$Trait $m]+ $w (vector_bool_int, vector_bool_int) -> vector_bool_int }
impl_vec_trait!{ [$Trait $m]+ $w (vector_unsigned_int, vector_unsigned_int) -> vector_unsigned_int }
impl_vec_trait!{ [$Trait $m]+ $w (vector_signed_int, vector_signed_int) -> vector_signed_int }
}
}