Skip to content

Commit b5d2d36

Browse files
lu-zeroAmanieu
authored andcommitted
Add vec_cft
1 parent c63a4ed commit b5d2d36

File tree

1 file changed

+71
-0
lines changed

1 file changed

+71
-0
lines changed

crates/core_arch/src/powerpc/altivec.rs

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,11 @@ extern "C" {
285285
fn vcmpgtfp_p(cr: i32, a: vector_float, b: vector_float) -> i32;
286286
#[link_name = "llvm.ppc.altivec.vcmpbfp.p"]
287287
fn vcmpbfp_p(cr: i32, a: vector_float, b: vector_float) -> i32;
288+
289+
#[link_name = "llvm.ppc.altivec.vcfsx"]
290+
fn vcfsx(a: vector_signed_int, b: i32) -> vector_float;
291+
#[link_name = "llvm.ppc.altivec.vcfux"]
292+
fn vcfux(a: vector_unsigned_int, b: i32) -> vector_float;
288293
}
289294

290295
macro_rules! s_t_l {
@@ -1960,6 +1965,38 @@ mod sealed {
19601965
}
19611966

19621967
impl_vec_trait! { [VectorNor vec_nor] 2 (vec_vnorub, vec_vnorsb, vec_vnoruh, vec_vnorsh, vec_vnoruw, vec_vnorsw) }
1968+
1969+
#[inline]
1970+
#[target_feature(enable = "altivec")]
1971+
#[cfg_attr(test, assert_instr(vcfsx, IMM5 = 1))]
1972+
unsafe fn vec_ctf_i32<const IMM5: i32>(a: vector_signed_int) -> vector_float {
1973+
static_assert_uimm_bits!(IMM5, 5);
1974+
vcfsx(a, IMM5)
1975+
}
1976+
1977+
#[inline]
1978+
#[target_feature(enable = "altivec")]
1979+
#[cfg_attr(test, assert_instr(vcfux, IMM5 = 1))]
1980+
unsafe fn vec_ctf_u32<const IMM5: i32>(a: vector_unsigned_int) -> vector_float {
1981+
static_assert_uimm_bits!(IMM5, 5);
1982+
vcfux(a, IMM5)
1983+
}
1984+
1985+
pub trait VectorCtf {
1986+
unsafe fn vec_ctf<const IMM5: i32>(self) -> vector_float;
1987+
}
1988+
1989+
impl VectorCtf for vector_signed_int {
1990+
unsafe fn vec_ctf<const IMM5: i32>(self) -> vector_float {
1991+
vec_ctf_i32::<IMM5>(self)
1992+
}
1993+
}
1994+
1995+
impl VectorCtf for vector_unsigned_int {
1996+
unsafe fn vec_ctf<const IMM5: i32>(self) -> vector_float {
1997+
vec_ctf_u32::<IMM5>(self)
1998+
}
1999+
}
19632000
}
19642001

19652002
/// Vector Load Indexed.
@@ -2221,6 +2258,16 @@ where
22212258
a.vec_add(b)
22222259
}
22232260

2261+
/// Vector Convert to Floating-Point
2262+
#[inline]
2263+
#[target_feature(enable = "altivec")]
2264+
pub unsafe fn vec_ctf<const IMM5: i32, T>(a: T) -> vector_float
2265+
where
2266+
T: sealed::VectorCtf,
2267+
{
2268+
a.vec_ctf::<IMM5>()
2269+
}
2270+
22242271
/// Endian-biased intrinsics
22252272
#[cfg(target_endian = "little")]
22262273
mod endian {
@@ -4510,4 +4557,28 @@ mod tests {
45104557
let z = vec_add(x, y);
45114558
assert_eq!(i32x4::splat(5), transmute(z));
45124559
}
4560+
4561+
#[simd_test(enable = "altivec")]
4562+
unsafe fn vec_ctf_u32() {
4563+
let v: vector_unsigned_int = transmute(u32x4::new(0, u32::MAX, u32::MAX - 42, 42));
4564+
let v2 = vec_ctf::<1, _>(v);
4565+
let r2: vector_float = transmute(f32x4::new(0.0, 2147483600.0, 2147483600.0, 21.0));
4566+
let v4 = vec_ctf::<2, _>(v);
4567+
let r4: vector_float = transmute(f32x4::new(0.0, 1073741800.0, 1073741800.0, 10.5));
4568+
let v8 = vec_ctf::<3, _>(v);
4569+
let r8: vector_float = transmute(f32x4::new(0.0, 536870900.0, 536870900.0, 5.25));
4570+
4571+
let check = |a, b| {
4572+
let r = transmute(vec_cmple(
4573+
vec_abs(vec_sub(a, b)),
4574+
vec_splats(std::f32::EPSILON),
4575+
));
4576+
let e = m32x4::new(true, true, true, true);
4577+
assert_eq!(e, r);
4578+
};
4579+
4580+
check(v2, r2);
4581+
check(v4, r4);
4582+
check(v8, r8);
4583+
}
45134584
}

0 commit comments

Comments
 (0)