@@ -3069,6 +3069,35 @@ mod sealed {
3069
3069
vsegf ( self )
3070
3070
}
3071
3071
}
3072
+
3073
+ // NOTE: VectorSigned and VectorUnsigned make strong safety assumptions around floats.
3074
+ // This is what C provides, but even IBM does not clearly document these constraints.
3075
+ //
3076
+ // https://doc.rust-lang.org/std/intrinsics/simd/fn.simd_cast.html
3077
+
3078
+ #[ unstable( feature = "stdarch_s390x" , issue = "135681" ) ]
3079
+ pub trait VectorSigned {
3080
+ type Result ;
3081
+ unsafe fn vec_signed ( self ) -> Self :: Result ;
3082
+ }
3083
+
3084
+ test_impl ! { vcgsb ( a: vector_float) -> vector_signed_int [ simd_cast, "vector-enhancements-2" vcgsb] }
3085
+ test_impl ! { vcgdb ( a: vector_double) -> vector_signed_long_long [ simd_cast, vcgdb] }
3086
+
3087
+ impl_vec_trait ! { [ VectorSigned vec_signed] vcgsb ( vector_float) -> vector_signed_int }
3088
+ impl_vec_trait ! { [ VectorSigned vec_signed] vcgdb ( vector_double) -> vector_signed_long_long }
3089
+
3090
+ #[ unstable( feature = "stdarch_s390x" , issue = "135681" ) ]
3091
+ pub trait VectorUnsigned {
3092
+ type Result ;
3093
+ unsafe fn vec_unsigned ( self ) -> Self :: Result ;
3094
+ }
3095
+
3096
+ test_impl ! { vclgsb ( a: vector_float) -> vector_unsigned_int [ simd_cast, "vector-enhancements-2" vclgsb] }
3097
+ test_impl ! { vclgdb ( a: vector_double) -> vector_unsigned_long_long [ simd_cast, vclgdb] }
3098
+
3099
+ impl_vec_trait ! { [ VectorUnsigned vec_unsigned] vclgsb ( vector_float) -> vector_unsigned_int }
3100
+ impl_vec_trait ! { [ VectorUnsigned vec_unsigned] vclgdb ( vector_double) -> vector_unsigned_long_long }
3072
3101
}
3073
3102
3074
3103
/// Load Count to Block Boundary
@@ -4388,6 +4417,22 @@ pub unsafe fn vec_extend_s64(a: impl sealed::VectorExtendSigned64) -> vector_sig
4388
4417
a. vec_extend_s64 ( )
4389
4418
}
4390
4419
4420
+ /// Vector Convert floating point to signed
4421
+ #[ inline]
4422
+ #[ target_feature( enable = "vector" ) ]
4423
+ #[ unstable( feature = "stdarch_s390x" , issue = "135681" ) ]
4424
+ pub unsafe fn vec_signed < T : sealed:: VectorSigned > ( a : T ) -> T :: Result {
4425
+ a. vec_signed ( )
4426
+ }
4427
+
4428
+ /// Vector Convert floating point to unsigned
4429
+ #[ inline]
4430
+ #[ target_feature( enable = "vector" ) ]
4431
+ #[ unstable( feature = "stdarch_s390x" , issue = "135681" ) ]
4432
+ pub unsafe fn vec_unsigned < T : sealed:: VectorUnsigned > ( a : T ) -> T :: Result {
4433
+ a. vec_unsigned ( )
4434
+ }
4435
+
4391
4436
#[ cfg( test) ]
4392
4437
mod tests {
4393
4438
use super :: * ;
@@ -5547,4 +5592,27 @@ mod tests {
5547
5592
assert_eq ! ( vec_extend_s64( v) . as_array( ) , & [ 1 , 3 ] ) ;
5548
5593
}
5549
5594
}
5595
+
5596
+ #[ simd_test( enable = "vector" ) ]
5597
+ fn test_vec_signed ( ) {
5598
+ unsafe {
5599
+ let v = vector_float ( [ 1.0 , 2.5 , -2.5 , -0.0 ] ) ;
5600
+ assert_eq ! ( vec_signed( v) . as_array( ) , & [ 1 , 2 , -2 , 0 ] ) ;
5601
+
5602
+ let v = vector_double ( [ 2.5 , -2.5 ] ) ;
5603
+ assert_eq ! ( vec_signed( v) . as_array( ) , & [ 2 , -2 ] ) ;
5604
+ }
5605
+ }
5606
+
5607
+ #[ simd_test( enable = "vector" ) ]
5608
+ fn test_vec_unsigned ( ) {
5609
+ // NOTE: converting a negative floating point value is UB!
5610
+ unsafe {
5611
+ let v = vector_float ( [ 1.0 , 2.5 , 3.5 , 0.0 ] ) ;
5612
+ assert_eq ! ( vec_unsigned( v) . as_array( ) , & [ 1 , 2 , 3 , 0 ] ) ;
5613
+
5614
+ let v = vector_double ( [ 2.5 , 3.5 ] ) ;
5615
+ assert_eq ! ( vec_unsigned( v) . as_array( ) , & [ 2 , 3 ] ) ;
5616
+ }
5617
+ }
5550
5618
}
0 commit comments