diff --git a/crates/core_arch/src/loongarch64/lasx/generated.rs b/crates/core_arch/src/loongarch64/lasx/generated.rs index 8e2bf10114..711ade4039 100644 --- a/crates/core_arch/src/loongarch64/lasx/generated.rs +++ b/crates/core_arch/src/loongarch64/lasx/generated.rs @@ -339,10 +339,6 @@ unsafe extern "unadjusted" { fn __lasx_xvfrstp_h(a: __v16i16, b: __v16i16, c: __v16i16) -> __v16i16; #[link_name = "llvm.loongarch.lasx.xvshuf4i.d"] fn __lasx_xvshuf4i_d(a: __v4i64, b: __v4i64, c: u32) -> __v4i64; - #[link_name = "llvm.loongarch.lasx.xvbsrl.v"] - fn __lasx_xvbsrl_v(a: __v32i8, b: u32) -> __v32i8; - #[link_name = "llvm.loongarch.lasx.xvbsll.v"] - fn __lasx_xvbsll_v(a: __v32i8, b: u32) -> __v32i8; #[link_name = "llvm.loongarch.lasx.xvextrins.b"] fn __lasx_xvextrins_b(a: __v32i8, b: __v32i8, c: u32) -> __v32i8; #[link_name = "llvm.loongarch.lasx.xvextrins.h"] @@ -2185,24 +2181,6 @@ pub fn lasx_xvshuf4i_d(a: m256i, b: m256i) -> m256i { unsafe { transmute(__lasx_xvshuf4i_d(transmute(a), transmute(b), IMM8)) } } -#[inline] -#[target_feature(enable = "lasx")] -#[rustc_legacy_const_generics(1)] -#[unstable(feature = "stdarch_loongarch", issue = "117427")] -pub fn lasx_xvbsrl_v(a: m256i) -> m256i { - static_assert_uimm_bits!(IMM5, 5); - unsafe { transmute(__lasx_xvbsrl_v(transmute(a), IMM5)) } -} - -#[inline] -#[target_feature(enable = "lasx")] -#[rustc_legacy_const_generics(1)] -#[unstable(feature = "stdarch_loongarch", issue = "117427")] -pub fn lasx_xvbsll_v(a: m256i) -> m256i { - static_assert_uimm_bits!(IMM5, 5); - unsafe { transmute(__lasx_xvbsll_v(transmute(a), IMM5)) } -} - #[inline] #[target_feature(enable = "lasx")] #[rustc_legacy_const_generics(2)] diff --git a/crates/core_arch/src/loongarch64/lasx/portable.rs b/crates/core_arch/src/loongarch64/lasx/portable.rs index 2f8bb33ab3..73ea74d9dc 100644 --- a/crates/core_arch/src/loongarch64/lasx/portable.rs +++ b/crates/core_arch/src/loongarch64/lasx/portable.rs @@ -314,6 +314,280 @@ const unsafe fn simd_ext_shuf4i_w(a: T) -> T { ) } +#[inline(always)] +#[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")] +pub(super) const unsafe fn simd_ext_bsll(a: T) -> T { + let z = simd_ext_splat(0); + match I & 0xf { + 0 => simd_shuffle!( + a, + z, + [ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 + ] + ), + 1 => simd_shuffle!( + a, + z, + [ + 32, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 32, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 + ] + ), + 2 => simd_shuffle!( + a, + z, + [ + 32, 32, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 32, 32, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + ] + ), + 3 => simd_shuffle!( + a, + z, + [ + 32, 32, 32, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 32, 32, 32, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, + ] + ), + 4 => simd_shuffle!( + a, + z, + [ + 32, 32, 32, 32, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 32, 32, 32, 32, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, + ] + ), + 5 => simd_shuffle!( + a, + z, + [ + 32, 32, 32, 32, 32, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, + 32, 32, 32, 32, 32, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, + ] + ), + 6 => simd_shuffle!( + a, + z, + [ + 32, 32, 32, 32, 32, 32, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 32, 32, 32, 32, 32, 32, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + ] + ), + 7 => simd_shuffle!( + a, + z, + [ + 32, 32, 32, 32, 32, 32, 32, 0, 1, 2, 3, 4, 5, 6, 7, 8, + 32, 32, 32, 32, 32, 32, 32, 16, 17, 18, 19, 20, 21, 22, 23, 24, + ] + ), + 8 => simd_shuffle!( + a, + z, + [ + 32, 32, 32, 32, 32, 32, 32, 32, 0, 1, 2, 3, 4, 5, 6, 7, + 32, 32, 32, 32, 32, 32, 32, 32, 16, 17, 18, 19, 20, 21, 22, 23, + ] + ), + 9 => simd_shuffle!( + a, + z, + [ + 32, 32, 32, 32, 32, 32, 32, 32, 32, 0, 1, 2, 3, 4, 5, 6, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 16, 17, 18, 19, 20, 21, 22, + ] + ), + 10 => simd_shuffle!( + a, + z, + [ + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 0, 1, 2, 3, 4, 5, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 16, 17, 18, 19, 20, 21, + ] + ), + 11 => simd_shuffle!( + a, + z, + [ + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 0, 1, 2, 3, 4, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 16, 17, 18, 19, 20, + ] + ), + 12 => simd_shuffle!( + a, + z, + [ + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 0, 1, 2, 3, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 16, 17, 18, 19, + ] + ), + 13 => simd_shuffle!( + a, + z, + [ + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 0, 1, 2, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 16, 17, 18, + ] + ), + 14 => simd_shuffle!( + a, + z, + [ + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 0, 1, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 16, 17, + ] + ), + 15 => simd_shuffle!( + a, + z, + [ + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 0, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 16, + ] + ), + _ => unreachable!(), + } +} + +#[inline(always)] +#[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")] +pub(super) const unsafe fn simd_ext_bsrl(a: T) -> T { + let z = simd_ext_splat(0); + match I & 0xf { + 0 => simd_shuffle!( + a, + z, + [ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 + ] + ), + 1 => simd_shuffle!( + a, + z, + [ + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 32, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32 + ] + ), + 2 => simd_shuffle!( + a, + z, + [ + 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 32, 32, + 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 32 + ] + ), + 3 => simd_shuffle!( + a, + z, + [ + 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 32, 32, 32, + 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 32, 32 + ] + ), + 4 => simd_shuffle!( + a, + z, + [ + 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 32, 32, 32, 32, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 32, 32, 32 + ] + ), + 5 => simd_shuffle!( + a, + z, + [ + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 32, 32, 32, 32, 32, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 32, 32, 32, 32 + ] + ), + 6 => simd_shuffle!( + a, + z, + [ + 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 32, 32, 32, 32, 32, 32, + 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 32, 32, 32, 32, 32 + ] + ), + 7 => simd_shuffle!( + a, + z, + [ + 7, 8, 9, 10, 11, 12, 13, 14, 15, 32, 32, 32, 32, 32, 32, 32, + 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 32, 32, 32, 32, 32, 32 + ] + ), + 8 => simd_shuffle!( + a, + z, + [ + 8, 9, 10, 11, 12, 13, 14, 15, 32, 32, 32, 32, 32, 32, 32, 32, + 24, 25, 26, 27, 28, 29, 30, 31, 32, 32, 32, 32, 32, 32, 32, 32 + ] + ), + 9 => simd_shuffle!( + a, + z, + [ + 9, 10, 11, 12, 13, 14, 15, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 25, 26, 27, 28, 29, 30, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32 + ] + ), + 10 => simd_shuffle!( + a, + z, + [ + 10, 11, 12, 13, 14, 15, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 26, 27, 28, 29, 30, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32 + ] + ), + 11 => simd_shuffle!( + a, + z, + [ + 11, 12, 13, 14, 15, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 27, 28, 29, 30, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32 + ] + ), + 12 => simd_shuffle!( + a, + z, + [ + 12, 13, 14, 15, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 28, 29, 30, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32 + ] + ), + 13 => simd_shuffle!( + a, + z, + [ + 13, 14, 15, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 29, 30, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32 + ] + ), + 14 => simd_shuffle!( + a, + z, + [ + 14, 15, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 30, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32 + ] + ), + 15 => simd_shuffle!( + a, + z, + [ + 15, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32 + ] + ), + _ => unreachable!(), + } +} + impl_vv!("lasx", lasx_xvpcnt_b, simd_ctpop, m256i, i8x32); impl_vv!("lasx", lasx_xvpcnt_h, simd_ctpop, m256i, i16x16); impl_vv!("lasx", lasx_xvpcnt_w, simd_ctpop, m256i, i32x8); @@ -573,6 +847,8 @@ impl_vuv!("lasx", lasx_xvrepl128vei_d, simd_ext_replvei_d, m256i, i64x4, 1, cons impl_vuv!("lasx", lasx_xvshuf4i_b, simd_ext_shuf4i_b, m256i, i8x32, 8, const); impl_vuv!("lasx", lasx_xvshuf4i_h, simd_ext_shuf4i_h, m256i, i16x16, 8, const); impl_vuv!("lasx", lasx_xvshuf4i_w, simd_ext_shuf4i_w, m256i, i32x8, 8, const); +impl_vuv!("lasx", lasx_xvbsll_v, simd_ext_bsll, m256i, i8x32, 5, const); +impl_vuv!("lasx", lasx_xvbsrl_v, simd_ext_bsrl, m256i, i8x32, 5, const); impl_vug!("lasx", lasx_xvpickve2gr_w, simd_extract, m256i, i32x8, i32, 3); impl_vug!("lasx", lasx_xvpickve2gr_d, simd_extract, m256i, i64x4, i64, 2); @@ -626,6 +902,7 @@ mod tests { core_arch::{loongarch64::*, simd::*}, mem::transmute, }; + use std::hint::black_box; use stdarch_test::simd_test; #[simd_test(enable = "lasx")] @@ -801,4 +1078,180 @@ mod tests { ); assert_eq!(r, transmute(lasx_xvldi::<-854>())); } + + #[simd_test(enable = "lasx")] + unsafe fn xvbsll_v() { + let a = i8x32::new( + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, + ); + let r = i8x32::new( + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, + ); + assert_eq!(r, transmute(lasx_xvbsll_v::<0>(black_box(transmute(a))))); + let r = i8x32::new( + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, + ); + assert_eq!(r, transmute(lasx_xvbsll_v::<1>(black_box(transmute(a))))); + let r = i8x32::new( + 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0, 0, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, + ); + assert_eq!(r, transmute(lasx_xvbsll_v::<2>(black_box(transmute(a))))); + let r = i8x32::new( + 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 0, 17, 18, 19, 20, 21, 22, + 23, 24, 25, 26, 27, 28, 29, + ); + assert_eq!(r, transmute(lasx_xvbsll_v::<3>(black_box(transmute(a))))); + let r = i8x32::new( + 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0, 0, 0, 0, 17, 18, 19, 20, 21, 22, + 23, 24, 25, 26, 27, 28, + ); + assert_eq!(r, transmute(lasx_xvbsll_v::<4>(black_box(transmute(a))))); + let r = i8x32::new( + 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 0, 0, 0, 0, 17, 18, 19, 20, 21, + 22, 23, 24, 25, 26, 27, + ); + assert_eq!(r, transmute(lasx_xvbsll_v::<5>(black_box(transmute(a))))); + let r = i8x32::new( + 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0, 0, 0, 0, 0, 0, 17, 18, 19, 20, 21, + 22, 23, 24, 25, 26, + ); + assert_eq!(r, transmute(lasx_xvbsll_v::<6>(black_box(transmute(a))))); + let r = i8x32::new( + 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 17, 18, 19, 20, + 21, 22, 23, 24, 25, + ); + assert_eq!(r, transmute(lasx_xvbsll_v::<7>(black_box(transmute(a))))); + let r = i8x32::new( + 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 0, 0, 0, 0, 0, 0, 0, 0, 17, 18, 19, 20, + 21, 22, 23, 24, + ); + assert_eq!(r, transmute(lasx_xvbsll_v::<8>(black_box(transmute(a))))); + let r = i8x32::new( + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 18, 19, + 20, 21, 22, 23, + ); + assert_eq!(r, transmute(lasx_xvbsll_v::<9>(black_box(transmute(a))))); + let r = i8x32::new( + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 18, + 19, 20, 21, 22, + ); + assert_eq!(r, transmute(lasx_xvbsll_v::<10>(black_box(transmute(a))))); + let r = i8x32::new( + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, + 18, 19, 20, 21, + ); + assert_eq!(r, transmute(lasx_xvbsll_v::<11>(black_box(transmute(a))))); + let r = i8x32::new( + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, + 18, 19, 20, + ); + assert_eq!(r, transmute(lasx_xvbsll_v::<12>(black_box(transmute(a))))); + let r = i8x32::new( + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 17, 18, 19, + ); + assert_eq!(r, transmute(lasx_xvbsll_v::<13>(black_box(transmute(a))))); + let r = i8x32::new( + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 17, 18, + ); + assert_eq!(r, transmute(lasx_xvbsll_v::<14>(black_box(transmute(a))))); + let r = i8x32::new( + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 17, + ); + assert_eq!(r, transmute(lasx_xvbsll_v::<15>(black_box(transmute(a))))); + } + + #[simd_test(enable = "lasx")] + unsafe fn xvbsrl_v() { + let a = i8x32::new( + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, + ); + let r = i8x32::new( + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, + ); + assert_eq!(r, transmute(lasx_xvbsrl_v::<0>(black_box(transmute(a))))); + let r = i8x32::new( + 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 18, 19, 20, 21, 22, 23, 24, 25, + 26, 27, 28, 29, 30, 31, 32, 0, + ); + assert_eq!(r, transmute(lasx_xvbsrl_v::<1>(black_box(transmute(a))))); + let r = i8x32::new( + 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 19, 20, 21, 22, 23, 24, 25, 26, + 27, 28, 29, 30, 31, 32, 0, 0, + ); + assert_eq!(r, transmute(lasx_xvbsrl_v::<2>(black_box(transmute(a))))); + let r = i8x32::new( + 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 20, 21, 22, 23, 24, 25, 26, 27, + 28, 29, 30, 31, 32, 0, 0, 0, + ); + assert_eq!(r, transmute(lasx_xvbsrl_v::<3>(black_box(transmute(a))))); + let r = i8x32::new( + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 21, 22, 23, 24, 25, 26, 27, 28, + 29, 30, 31, 32, 0, 0, 0, 0, + ); + assert_eq!(r, transmute(lasx_xvbsrl_v::<4>(black_box(transmute(a))))); + let r = i8x32::new( + 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 0, 0, 0, 0, 0, + ); + assert_eq!(r, transmute(lasx_xvbsrl_v::<5>(black_box(transmute(a))))); + let r = i8x32::new( + 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 23, 24, 25, 26, 27, 28, 29, 30, + 31, 32, 0, 0, 0, 0, 0, 0, + ); + assert_eq!(r, transmute(lasx_xvbsrl_v::<6>(black_box(transmute(a))))); + let r = i8x32::new( + 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 0, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 0, 0, 0, 0, 0, 0, 0, + ); + assert_eq!(r, transmute(lasx_xvbsrl_v::<7>(black_box(transmute(a))))); + let r = i8x32::new( + 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 0, 0, 25, 26, 27, 28, 29, 30, 31, 32, + 0, 0, 0, 0, 0, 0, 0, 0, + ); + assert_eq!(r, transmute(lasx_xvbsrl_v::<8>(black_box(transmute(a))))); + let r = i8x32::new( + 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 27, 28, 29, 30, 31, 32, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + ); + assert_eq!(r, transmute(lasx_xvbsrl_v::<9>(black_box(transmute(a))))); + let r = i8x32::new( + 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 28, 29, 30, 31, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, + ); + assert_eq!(r, transmute(lasx_xvbsrl_v::<10>(black_box(transmute(a))))); + let r = i8x32::new( + 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 29, 30, 31, 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + ); + assert_eq!(r, transmute(lasx_xvbsrl_v::<11>(black_box(transmute(a))))); + let r = i8x32::new( + 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 30, 31, 32, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + ); + assert_eq!(r, transmute(lasx_xvbsrl_v::<12>(black_box(transmute(a))))); + let r = i8x32::new( + 14, 15, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 31, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + ); + assert_eq!(r, transmute(lasx_xvbsrl_v::<13>(black_box(transmute(a))))); + let r = i8x32::new( + 15, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ); + assert_eq!(r, transmute(lasx_xvbsrl_v::<14>(black_box(transmute(a))))); + let r = i8x32::new( + 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ); + assert_eq!(r, transmute(lasx_xvbsrl_v::<15>(black_box(transmute(a))))); + } } diff --git a/crates/core_arch/src/loongarch64/lsx/generated.rs b/crates/core_arch/src/loongarch64/lsx/generated.rs index 869fe9052d..1542633a34 100644 --- a/crates/core_arch/src/loongarch64/lsx/generated.rs +++ b/crates/core_arch/src/loongarch64/lsx/generated.rs @@ -333,10 +333,6 @@ unsafe extern "unadjusted" { fn __lsx_vfrstp_b(a: __v16i8, b: __v16i8, c: __v16i8) -> __v16i8; #[link_name = "llvm.loongarch.lsx.vfrstp.h"] fn __lsx_vfrstp_h(a: __v8i16, b: __v8i16, c: __v8i16) -> __v8i16; - #[link_name = "llvm.loongarch.lsx.vbsrl.v"] - fn __lsx_vbsrl_v(a: __v16i8, b: u32) -> __v16i8; - #[link_name = "llvm.loongarch.lsx.vbsll.v"] - fn __lsx_vbsll_v(a: __v16i8, b: u32) -> __v16i8; #[link_name = "llvm.loongarch.lsx.vextrins.b"] fn __lsx_vextrins_b(a: __v16i8, b: __v16i8, c: u32) -> __v16i8; #[link_name = "llvm.loongarch.lsx.vextrins.h"] @@ -2080,24 +2076,6 @@ pub fn lsx_vfrstp_h(a: m128i, b: m128i, c: m128i) -> m128i { unsafe { transmute(__lsx_vfrstp_h(transmute(a), transmute(b), transmute(c))) } } -#[inline] -#[target_feature(enable = "lsx")] -#[rustc_legacy_const_generics(1)] -#[unstable(feature = "stdarch_loongarch", issue = "117427")] -pub fn lsx_vbsrl_v(a: m128i) -> m128i { - static_assert_uimm_bits!(IMM5, 5); - unsafe { transmute(__lsx_vbsrl_v(transmute(a), IMM5)) } -} - -#[inline] -#[target_feature(enable = "lsx")] -#[rustc_legacy_const_generics(1)] -#[unstable(feature = "stdarch_loongarch", issue = "117427")] -pub fn lsx_vbsll_v(a: m128i) -> m128i { - static_assert_uimm_bits!(IMM5, 5); - unsafe { transmute(__lsx_vbsll_v(transmute(a), IMM5)) } -} - #[inline] #[target_feature(enable = "lsx")] #[rustc_legacy_const_generics(2)] diff --git a/crates/core_arch/src/loongarch64/lsx/portable.rs b/crates/core_arch/src/loongarch64/lsx/portable.rs index d82c858953..31467bf013 100644 --- a/crates/core_arch/src/loongarch64/lsx/portable.rs +++ b/crates/core_arch/src/loongarch64/lsx/portable.rs @@ -213,6 +213,56 @@ const unsafe fn simd_ext_shuf4i_d(a: T, b: T) -> T { simd_shuffle!(a, b, [((I >> 0) & 3), ((I >> 2) & 3)]) } +#[inline(always)] +#[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")] +pub(super) const unsafe fn simd_ext_bsll(a: T) -> T { + let z = simd_ext_splat(0); + match I & 0xf { + 0 => simd_shuffle!(a, z, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]), + 1 => simd_shuffle!(a, z, [16, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]), + 2 => simd_shuffle!(a, z, [16, 16, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]), + 3 => simd_shuffle!(a, z, [16, 16, 16, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]), + 4 => simd_shuffle!(a, z, [16, 16, 16, 16, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]), + 5 => simd_shuffle!(a, z, [16, 16, 16, 16, 16, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]), + 6 => simd_shuffle!(a, z, [16, 16, 16, 16, 16, 16, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]), + 7 => simd_shuffle!(a, z, [16, 16, 16, 16, 16, 16, 16, 0, 1, 2, 3, 4, 5, 6, 7, 8]), + 8 => simd_shuffle!(a, z, [16, 16, 16, 16, 16, 16, 16, 16, 0, 1, 2, 3, 4, 5, 6, 7]), + 9 => simd_shuffle!(a, z, [16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 1, 2, 3, 4, 5, 6]), + 10 => simd_shuffle!(a, z, [16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 1, 2, 3, 4, 5]), + 11 => simd_shuffle!(a, z, [16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 1, 2, 3, 4]), + 12 => simd_shuffle!(a, z, [16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 1, 2, 3]), + 13 => simd_shuffle!(a, z, [16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 1, 2]), + 14 => simd_shuffle!(a, z, [16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 1]), + 15 => simd_shuffle!(a, z, [16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 0]), + _ => unreachable!(), + } +} + +#[inline(always)] +#[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")] +pub(super) const unsafe fn simd_ext_bsrl(a: T) -> T { + let z = simd_ext_splat(0); + match I & 0xf { + 0 => simd_shuffle!(a, z, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]), + 1 => simd_shuffle!(a, z, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]), + 2 => simd_shuffle!(a, z, [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 16]), + 3 => simd_shuffle!(a, z, [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 16, 16]), + 4 => simd_shuffle!(a, z, [4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 16, 16, 16]), + 5 => simd_shuffle!(a, z, [5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 16, 16, 16, 16]), + 6 => simd_shuffle!(a, z, [6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16]), + 7 => simd_shuffle!(a, z, [7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16]), + 8 => simd_shuffle!(a, z, [8, 9, 10, 11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16, 16]), + 9 => simd_shuffle!(a, z, [9, 10, 11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16]), + 10 => simd_shuffle!(a, z, [10, 11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16]), + 11 => simd_shuffle!(a, z, [11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16]), + 12 => simd_shuffle!(a, z, [12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16]), + 13 => simd_shuffle!(a, z, [13, 14, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16]), + 14 => simd_shuffle!(a, z, [14, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16]), + 15 => simd_shuffle!(a, z, [15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16]), + _ => unreachable!(), + } +} + impl_vv!("lsx", lsx_vpcnt_b, simd_ctpop, m128i, i8x16); impl_vv!("lsx", lsx_vpcnt_h, simd_ctpop, m128i, i16x8); impl_vv!("lsx", lsx_vpcnt_w, simd_ctpop, m128i, i32x4); @@ -467,6 +517,8 @@ impl_vuv!("lsx", lsx_vreplvei_d, simd_ext_replvei_d, m128i, i64x2, 1, const); impl_vuv!("lsx", lsx_vshuf4i_b, simd_ext_shuf4i_b, m128i, i8x16, 8, const); impl_vuv!("lsx", lsx_vshuf4i_h, simd_ext_shuf4i_h, m128i, i16x8, 8, const); impl_vuv!("lsx", lsx_vshuf4i_w, simd_ext_shuf4i_w, m128i, i32x4, 8, const); +impl_vuv!("lsx", lsx_vbsll_v, simd_ext_bsll, m128i, i8x16, 5, const); +impl_vuv!("lsx", lsx_vbsrl_v, simd_ext_bsrl, m128i, i8x16, 5, const); impl_vug!("lsx", lsx_vpickve2gr_b, simd_extract, m128i, i8x16, i32, 4); impl_vug!("lsx", lsx_vpickve2gr_h, simd_extract, m128i, i16x8, i32, 3); @@ -528,6 +580,7 @@ mod tests { core_arch::{loongarch64::*, simd::*}, mem::transmute, }; + use std::hint::black_box; use stdarch_test::simd_test; #[simd_test(enable = "lsx")] @@ -613,4 +666,78 @@ mod tests { let r = i8x16::new(0, 0, 0, 0, 0, 0, 42, -64, 0, 0, 0, 0, 0, 0, 42, -64); assert_eq!(r, transmute(lsx_vldi::<-854>())); } + + #[simd_test(enable = "lsx")] + unsafe fn vbsll_v() { + let a = i8x16::new(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); + let r = i8x16::new(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); + assert_eq!(r, transmute(lsx_vbsll_v::<0>(black_box(transmute(a))))); + let r = i8x16::new(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); + assert_eq!(r, transmute(lsx_vbsll_v::<1>(black_box(transmute(a))))); + let r = i8x16::new(0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14); + assert_eq!(r, transmute(lsx_vbsll_v::<2>(black_box(transmute(a))))); + let r = i8x16::new(0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13); + assert_eq!(r, transmute(lsx_vbsll_v::<3>(black_box(transmute(a))))); + let r = i8x16::new(0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12); + assert_eq!(r, transmute(lsx_vbsll_v::<4>(black_box(transmute(a))))); + let r = i8x16::new(0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11); + assert_eq!(r, transmute(lsx_vbsll_v::<5>(black_box(transmute(a))))); + let r = i8x16::new(0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + assert_eq!(r, transmute(lsx_vbsll_v::<6>(black_box(transmute(a))))); + let r = i8x16::new(0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9); + assert_eq!(r, transmute(lsx_vbsll_v::<7>(black_box(transmute(a))))); + let r = i8x16::new(0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8); + assert_eq!(r, transmute(lsx_vbsll_v::<8>(black_box(transmute(a))))); + let r = i8x16::new(0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7); + assert_eq!(r, transmute(lsx_vbsll_v::<9>(black_box(transmute(a))))); + let r = i8x16::new(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6); + assert_eq!(r, transmute(lsx_vbsll_v::<10>(black_box(transmute(a))))); + let r = i8x16::new(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5); + assert_eq!(r, transmute(lsx_vbsll_v::<11>(black_box(transmute(a))))); + let r = i8x16::new(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4); + assert_eq!(r, transmute(lsx_vbsll_v::<12>(black_box(transmute(a))))); + let r = i8x16::new(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3); + assert_eq!(r, transmute(lsx_vbsll_v::<13>(black_box(transmute(a))))); + let r = i8x16::new(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2); + assert_eq!(r, transmute(lsx_vbsll_v::<14>(black_box(transmute(a))))); + let r = i8x16::new(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1); + assert_eq!(r, transmute(lsx_vbsll_v::<15>(black_box(transmute(a))))); + } + + #[simd_test(enable = "lsx")] + unsafe fn vbsrl_v() { + let a = i8x16::new(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); + let r = i8x16::new(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); + assert_eq!(r, transmute(lsx_vbsrl_v::<0>(black_box(transmute(a))))); + let r = i8x16::new(2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0); + assert_eq!(r, transmute(lsx_vbsrl_v::<1>(black_box(transmute(a))))); + let r = i8x16::new(3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0); + assert_eq!(r, transmute(lsx_vbsrl_v::<2>(black_box(transmute(a))))); + let r = i8x16::new(4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0); + assert_eq!(r, transmute(lsx_vbsrl_v::<3>(black_box(transmute(a))))); + let r = i8x16::new(5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0); + assert_eq!(r, transmute(lsx_vbsrl_v::<4>(black_box(transmute(a))))); + let r = i8x16::new(6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0); + assert_eq!(r, transmute(lsx_vbsrl_v::<5>(black_box(transmute(a))))); + let r = i8x16::new(7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0); + assert_eq!(r, transmute(lsx_vbsrl_v::<6>(black_box(transmute(a))))); + let r = i8x16::new(8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 0); + assert_eq!(r, transmute(lsx_vbsrl_v::<7>(black_box(transmute(a))))); + let r = i8x16::new(9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 0, 0); + assert_eq!(r, transmute(lsx_vbsrl_v::<8>(black_box(transmute(a))))); + let r = i8x16::new(10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0); + assert_eq!(r, transmute(lsx_vbsrl_v::<9>(black_box(transmute(a))))); + let r = i8x16::new(11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + assert_eq!(r, transmute(lsx_vbsrl_v::<10>(black_box(transmute(a))))); + let r = i8x16::new(12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + assert_eq!(r, transmute(lsx_vbsrl_v::<11>(black_box(transmute(a))))); + let r = i8x16::new(13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + assert_eq!(r, transmute(lsx_vbsrl_v::<12>(black_box(transmute(a))))); + let r = i8x16::new(14, 15, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + assert_eq!(r, transmute(lsx_vbsrl_v::<13>(black_box(transmute(a))))); + let r = i8x16::new(15, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + assert_eq!(r, transmute(lsx_vbsrl_v::<14>(black_box(transmute(a))))); + let r = i8x16::new(16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + assert_eq!(r, transmute(lsx_vbsrl_v::<15>(black_box(transmute(a))))); + } } diff --git a/crates/stdarch-gen-loongarch/lasx.spec b/crates/stdarch-gen-loongarch/lasx.spec index 2498264ef5..9eff3d01fa 100644 --- a/crates/stdarch-gen-loongarch/lasx.spec +++ b/crates/stdarch-gen-loongarch/lasx.spec @@ -2324,11 +2324,13 @@ asm-fmts = xd, xj, ui8 data-types = V4DI, V4DI, V4DI, USI /// lasx_xvbsrl_v +impl = portable name = lasx_xvbsrl_v asm-fmts = xd, xj, ui5 data-types = V32QI, V32QI, UQI /// lasx_xvbsll_v +impl = portable name = lasx_xvbsll_v asm-fmts = xd, xj, ui5 data-types = V32QI, V32QI, UQI diff --git a/crates/stdarch-gen-loongarch/lsx.spec b/crates/stdarch-gen-loongarch/lsx.spec index 01e7a0565e..ba2554b0cf 100644 --- a/crates/stdarch-gen-loongarch/lsx.spec +++ b/crates/stdarch-gen-loongarch/lsx.spec @@ -2387,11 +2387,13 @@ asm-fmts = vd, vj, ui8 data-types = V2DI, V2DI, V2DI, USI /// lsx_vbsrl_v +impl = portable name = lsx_vbsrl_v asm-fmts = vd, vj, ui5 data-types = V16QI, V16QI, UQI /// lsx_vbsll_v +impl = portable name = lsx_vbsll_v asm-fmts = vd, vj, ui5 data-types = V16QI, V16QI, UQI diff --git a/crates/stdarch-gen-loongarch/src/portable-intrinsics.txt b/crates/stdarch-gen-loongarch/src/portable-intrinsics.txt index be709509a0..8b8c82b3bb 100644 --- a/crates/stdarch-gen-loongarch/src/portable-intrinsics.txt +++ b/crates/stdarch-gen-loongarch/src/portable-intrinsics.txt @@ -294,6 +294,8 @@ lsx_vmuh_hu lsx_vmuh_wu lsx_vmuh_du lsx_vldi +lsx_vbsll_v +lsx_vbsrl_v # LASX intrinsics lasx_xvsll_b @@ -589,3 +591,5 @@ lasx_xvmuh_hu lasx_xvmuh_wu lasx_xvmuh_du lasx_xvldi +lasx_xvbsll_v +lasx_xvbsrl_v