@@ -285,6 +285,11 @@ extern "C" {
285
285
fn vcmpgtfp_p ( cr : i32 , a : vector_float , b : vector_float ) -> i32 ;
286
286
#[ link_name = "llvm.ppc.altivec.vcmpbfp.p" ]
287
287
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 ;
288
293
}
289
294
290
295
macro_rules! s_t_l {
@@ -1960,6 +1965,38 @@ mod sealed {
1960
1965
}
1961
1966
1962
1967
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
+ }
1963
2000
}
1964
2001
1965
2002
/// Vector Load Indexed.
@@ -2221,6 +2258,16 @@ where
2221
2258
a. vec_add ( b)
2222
2259
}
2223
2260
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
+
2224
2271
/// Endian-biased intrinsics
2225
2272
#[ cfg( target_endian = "little" ) ]
2226
2273
mod endian {
@@ -4510,4 +4557,28 @@ mod tests {
4510
4557
let z = vec_add ( x, y) ;
4511
4558
assert_eq ! ( i32x4:: splat( 5 ) , transmute( z) ) ;
4512
4559
}
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
+ }
4513
4584
}
0 commit comments