Skip to content

Commit 588a4c2

Browse files
folkertdevAmanieu
authored andcommitted
add vec_double and vec_float
1 parent c383877 commit 588a4c2

File tree

1 file changed

+158
-0
lines changed

1 file changed

+158
-0
lines changed

crates/core_arch/src/s390x/vector.rs

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2923,6 +2923,86 @@ mod sealed {
29232923
vstrsf vstrszf vector_bool_int
29242924
vstrsf vstrszf vector_unsigned_int
29252925
}
2926+
2927+
#[inline]
2928+
#[target_feature(enable = "vector")]
2929+
#[cfg_attr(test, assert_instr(vcdgb))]
2930+
pub unsafe fn vcdgb(a: vector_signed_long_long) -> vector_double {
2931+
simd_as(a)
2932+
}
2933+
2934+
#[inline]
2935+
#[target_feature(enable = "vector")]
2936+
#[cfg_attr(test, assert_instr(vcdlgb))]
2937+
pub unsafe fn vcdlgb(a: vector_unsigned_long_long) -> vector_double {
2938+
simd_as(a)
2939+
}
2940+
2941+
#[unstable(feature = "stdarch_s390x", issue = "135681")]
2942+
pub trait VectorDouble {
2943+
unsafe fn vec_double(self) -> vector_double;
2944+
}
2945+
2946+
#[unstable(feature = "stdarch_s390x", issue = "135681")]
2947+
impl VectorDouble for vector_signed_long_long {
2948+
#[inline]
2949+
#[target_feature(enable = "vector")]
2950+
unsafe fn vec_double(self) -> vector_double {
2951+
vcdgb(self)
2952+
}
2953+
}
2954+
2955+
#[unstable(feature = "stdarch_s390x", issue = "135681")]
2956+
impl VectorDouble for vector_unsigned_long_long {
2957+
#[inline]
2958+
#[target_feature(enable = "vector")]
2959+
unsafe fn vec_double(self) -> vector_double {
2960+
vcdlgb(self)
2961+
}
2962+
}
2963+
2964+
#[inline]
2965+
#[target_feature(enable = "vector")]
2966+
#[cfg_attr(
2967+
all(test, target_feature = "vector-enhancements-2"),
2968+
assert_instr(vcefb)
2969+
)]
2970+
pub unsafe fn vcefb(a: vector_signed_int) -> vector_float {
2971+
simd_as(a)
2972+
}
2973+
2974+
#[inline]
2975+
#[target_feature(enable = "vector")]
2976+
#[cfg_attr(
2977+
all(test, target_feature = "vector-enhancements-2"),
2978+
assert_instr(vcelfb)
2979+
)]
2980+
pub unsafe fn vcelfb(a: vector_unsigned_int) -> vector_float {
2981+
simd_as(a)
2982+
}
2983+
2984+
#[unstable(feature = "stdarch_s390x", issue = "135681")]
2985+
pub trait VectorFloat {
2986+
unsafe fn vec_float(self) -> vector_float;
2987+
}
2988+
2989+
#[unstable(feature = "stdarch_s390x", issue = "135681")]
2990+
impl VectorFloat for vector_signed_int {
2991+
#[inline]
2992+
#[target_feature(enable = "vector")]
2993+
unsafe fn vec_float(self) -> vector_float {
2994+
vcefb(self)
2995+
}
2996+
}
2997+
2998+
#[unstable(feature = "stdarch_s390x", issue = "135681")]
2999+
impl VectorFloat for vector_unsigned_int {
3000+
#[inline]
3001+
#[target_feature(enable = "vector")]
3002+
unsafe fn vec_float(self) -> vector_float {
3003+
vcelfb(self)
3004+
}
3005+
}
29263006
}
29273007

29283008
/// Load Count to Block Boundary
@@ -4192,6 +4272,48 @@ pub unsafe fn vec_search_string_until_zero_cc<T: sealed::VectorSearchString>(
41924272
a.vec_search_string_until_zero_cc(b, c, d)
41934273
}
41944274

4275+
/// Vector Convert from float (even elements) to double
4276+
#[inline]
4277+
#[target_feature(enable = "vector-enhancements-1")]
4278+
#[unstable(feature = "stdarch_s390x", issue = "135681")]
4279+
// FIXME: this emits `vflls` where `vldeb` is expected
4280+
// #[cfg_attr(all(test, target_feature = "vector-enhancements-1"), assert_instr(vldeb))]
4281+
pub unsafe fn vec_doublee(a: vector_float) -> vector_double {
4282+
let even = simd_shuffle::<_, _, f32x2>(a, a, const { u32x2::from_array([0, 2]) });
4283+
simd_as(even)
4284+
}
4285+
4286+
/// Vector Convert from double to float (even elements)
4287+
#[inline]
4288+
#[target_feature(enable = "vector-enhancements-1")]
4289+
#[unstable(feature = "stdarch_s390x", issue = "135681")]
4290+
// FIXME: the C version uses a shuffle mask with poison; we can't do that
4291+
// #[cfg_attr(all(test, target_feature = "vector-enhancements-1"), assert_instr(vledb))]
4292+
pub unsafe fn vec_floate(a: vector_double) -> vector_float {
4293+
let truncated: f32x2 = simd_as(a);
4294+
simd_shuffle(
4295+
truncated,
4296+
truncated,
4297+
const { u32x4::from_array([0, 0, 1, 1]) },
4298+
)
4299+
}
4300+
4301+
/// Vector Convert from int to float
4302+
#[inline]
4303+
#[target_feature(enable = "vector")]
4304+
#[unstable(feature = "stdarch_s390x", issue = "135681")]
4305+
pub unsafe fn vec_float(a: impl sealed::VectorFloat) -> vector_float {
4306+
a.vec_float()
4307+
}
4308+
4309+
/// Vector Convert from long long to double
4310+
#[inline]
4311+
#[target_feature(enable = "vector")]
4312+
#[unstable(feature = "stdarch_s390x", issue = "135681")]
4313+
pub unsafe fn vec_double(a: impl sealed::VectorDouble) -> vector_double {
4314+
a.vec_double()
4315+
}
4316+
41954317
#[cfg(test)]
41964318
mod tests {
41974319
use super::*;
@@ -5301,4 +5423,40 @@ mod tests {
53015423
assert_eq!(d, 1);
53025424
}
53035425
}
5426+
5427+
#[simd_test(enable = "vector")]
5428+
fn test_vec_doublee() {
5429+
unsafe {
5430+
let v = vector_float([1.0, 2.0, 3.0, 4.0]);
5431+
assert_eq!(vec_doublee(v).as_array(), &[1.0, 3.0]);
5432+
5433+
let v = vector_float([f32::NAN, 2.0, f32::INFINITY, 4.0]);
5434+
let d = vec_doublee(v);
5435+
assert!(d.as_array()[0].is_nan());
5436+
assert_eq!(d.as_array()[1], f64::INFINITY);
5437+
}
5438+
}
5439+
5440+
#[simd_test(enable = "vector")]
5441+
fn test_vec_floate() {
5442+
// NOTE: indices 1 and 3 can have an arbitrary value. With the C version
5443+
// these are poison values, our version initializes the memory but its
5444+
// value still should not be relied upon by application code.
5445+
unsafe {
5446+
let v = vector_double([1.0, 2.0]);
5447+
let d = vec_floate(v);
5448+
assert_eq!(d.as_array()[0], 1.0);
5449+
assert_eq!(d.as_array()[2], 2.0);
5450+
5451+
let v = vector_double([f64::NAN, f64::INFINITY]);
5452+
let d = vec_floate(v);
5453+
assert!(d.as_array()[0].is_nan());
5454+
assert_eq!(d.as_array()[2], f32::INFINITY);
5455+
5456+
let v = vector_double([f64::MIN, f64::MAX]);
5457+
let d = vec_floate(v);
5458+
assert_eq!(d.as_array()[0], f64::MIN as f32);
5459+
assert_eq!(d.as_array()[2], f64::MAX as f32);
5460+
}
5461+
}
53045462
}

0 commit comments

Comments
 (0)