|
10 | 10 |
|
11 | 11 | use coresimd::powerpc::*;
|
12 | 12 | use coresimd::simd::*;
|
| 13 | +use coresimd::simd_llvm::*; |
| 14 | + |
| 15 | +#[cfg(test)] |
| 16 | +use stdsimd_test::assert_instr; |
| 17 | + |
| 18 | +use mem; |
13 | 19 |
|
14 | 20 | types! {
|
15 | 21 | // pub struct vector_Float16 = f16x8;
|
@@ -216,3 +222,75 @@ impl_from_bits_!(
|
216 | 222 | vector_bool_long,
|
217 | 223 | vector_double
|
218 | 224 | );
|
| 225 | + |
| 226 | +mod sealed { |
| 227 | + |
| 228 | + use super::*; |
| 229 | + |
| 230 | + pub trait VectorPermDI { |
| 231 | + unsafe fn vec_xxpermdi(self, b: Self, dm: u8) -> Self; |
| 232 | + } |
| 233 | + |
| 234 | + #[inline] |
| 235 | + #[target_feature(enable = "vsx")] |
| 236 | + #[cfg_attr(test, assert_instr(xxpermdi, dm = 0x0))] |
| 237 | + unsafe fn xxpermdi(a: i64x2, b: i64x2, dm: u8) -> i64x2 { |
| 238 | + match dm & 0b11 { |
| 239 | + 0 => simd_shuffle2(a, b, [0b00, 0b10]), |
| 240 | + 1 => simd_shuffle2(a, b, [0b01, 0b10]), |
| 241 | + 2 => simd_shuffle2(a, b, [0b00, 0b11]), |
| 242 | + _ => simd_shuffle2(a, b, [0b01, 0b11]), |
| 243 | + } |
| 244 | + } |
| 245 | + |
| 246 | + macro_rules! vec_xxpermdi { |
| 247 | + {$impl: ident} => { |
| 248 | + impl VectorPermDI for $impl { |
| 249 | + #[inline] |
| 250 | + #[target_feature(enable = "vsx")] |
| 251 | + unsafe fn vec_xxpermdi(self, b: Self, dm: u8) -> Self { |
| 252 | + mem::transmute(xxpermdi(mem::transmute(self), mem::transmute(b), dm)) |
| 253 | + } |
| 254 | + } |
| 255 | + } |
| 256 | + } |
| 257 | + |
| 258 | + vec_xxpermdi! { vector_unsigned_long } |
| 259 | + vec_xxpermdi! { vector_signed_long } |
| 260 | + vec_xxpermdi! { vector_bool_long } |
| 261 | + vec_xxpermdi! { vector_double } |
| 262 | +} |
| 263 | + |
| 264 | +/// Vector permute. |
| 265 | +#[inline] |
| 266 | +#[target_feature(enable = "vsx")] |
| 267 | +#[rustc_args_required_const(2)] |
| 268 | +pub unsafe fn vec_xxpermdi<T>(a: T, b: T, dm: u8) -> T |
| 269 | +where |
| 270 | + T: sealed::VectorPermDI, |
| 271 | +{ |
| 272 | + a.vec_xxpermdi(b, dm) |
| 273 | +} |
| 274 | + |
| 275 | +#[cfg(test)] |
| 276 | +mod tests { |
| 277 | + #[cfg(target_arch = "powerpc")] |
| 278 | + use coresimd::arch::powerpc::*; |
| 279 | + |
| 280 | + #[cfg(target_arch = "powerpc64")] |
| 281 | + use coresimd::arch::powerpc64::*; |
| 282 | + |
| 283 | + use simd::*; |
| 284 | + use stdsimd_test::simd_test; |
| 285 | + |
| 286 | + #[simd_test(enable = "vsx")] |
| 287 | + unsafe fn vec_xxpermdi_u62x2() { |
| 288 | + let a: vector_unsigned_long = u64x2::new(0, 1).into_bits(); |
| 289 | + let b = u64x2::new(2, 3).into_bits(); |
| 290 | + |
| 291 | + assert_eq!(u64x2::new(0, 2), vec_xxpermdi(a, b, 0).into_bits()); |
| 292 | + assert_eq!(u64x2::new(1, 2), vec_xxpermdi(a, b, 1).into_bits()); |
| 293 | + assert_eq!(u64x2::new(0, 3), vec_xxpermdi(a, b, 2).into_bits()); |
| 294 | + assert_eq!(u64x2::new(1, 3), vec_xxpermdi(a, b, 3).into_bits()); |
| 295 | + } |
| 296 | +} |
0 commit comments