Skip to content

Commit b2aac89

Browse files
committed
use generic llvm intrinsics for rounding
1 parent 16693f8 commit b2aac89

File tree

1 file changed

+94
-76
lines changed

1 file changed

+94
-76
lines changed

crates/core_arch/src/s390x/vector.rs

+94-76
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,14 @@ unsafe extern "unadjusted" {
7474
#[link_name = "llvm.umin.v4i32"] fn vmnlf(a: vector_unsigned_int, b: vector_unsigned_int) -> vector_unsigned_int;
7575
#[link_name = "llvm.umin.v2i64"] fn vmnlg(a: vector_unsigned_long_long, b: vector_unsigned_long_long) -> vector_unsigned_long_long;
7676

77-
#[link_name = "llvm.s390.vfisb"] fn vfisb(a: vector_float, b: i32, c: i32) -> vector_float;
78-
#[link_name = "llvm.s390.vfidb"] fn vfidb(a: vector_double, b: i32, c: i32) -> vector_double;
77+
#[link_name = "llvm.nearbyint.v4f32"] fn nearbyint_v4f32(a: vector_float) -> vector_float;
78+
#[link_name = "llvm.nearbyint.v2f64"] fn nearbyint_v2f64(a: vector_double) -> vector_double;
7979

80+
#[link_name = "llvm.rint.v4f32"] fn rint_v4f32(a: vector_float) -> vector_float;
81+
#[link_name = "llvm.rint.v2f64"] fn rint_v2f64(a: vector_double) -> vector_double;
82+
83+
#[link_name = "llvm.roundeven.v4f32"] fn roundeven_v4f32(a: vector_float) -> vector_float;
84+
#[link_name = "llvm.roundeven.v2f64"] fn roundeven_v2f64(a: vector_double) -> vector_double;
8085
}
8186

8287
impl_from! { i8x16, u8x16, i16x8, u16x8, i32x4, u32x4, i64x2, u64x2, f32x4, f64x2 }
@@ -636,70 +641,67 @@ mod sealed {
636641

637642
impl_vec_trait! { [VectorOrc vec_orc]+ 2c (orc) }
638643

644+
// FIXME(vector-enhancements-1) add instr tests for f32
645+
test_impl! { vec_roundc_f32 (a: vector_float) -> vector_float [nearbyint_v4f32, _] }
646+
test_impl! { vec_roundc_f64 (a: vector_double) -> vector_double [nearbyint_v2f64, vfidb] }
647+
648+
// FIXME(llvm) roundeven does not yet lower to vfidb (but should in the future)
649+
test_impl! { vec_round_f32 (a: vector_float) -> vector_float [roundeven_v4f32, _] }
650+
test_impl! { vec_round_f64 (a: vector_double) -> vector_double [roundeven_v2f64, _] }
651+
652+
test_impl! { vec_rint_f32 (a: vector_float) -> vector_float [rint_v4f32, _] }
653+
test_impl! { vec_rint_f64 (a: vector_double) -> vector_double [rint_v2f64, vfidb] }
654+
639655
#[unstable(feature = "stdarch_s390x", issue = "135681")]
640-
pub trait VectorRound: Sized {
641-
unsafe fn vec_round_impl<const N: i32, const MODE: i32>(self) -> Self;
656+
pub trait VectorRoundc {
657+
unsafe fn vec_roundc(self) -> Self;
658+
}
642659

643-
#[inline]
644-
#[target_feature(enable = "vector")]
645-
unsafe fn vec_roundc(self) -> Self {
646-
self.vec_round_impl::<4, 0>()
647-
}
660+
#[unstable(feature = "stdarch_s390x", issue = "135681")]
661+
pub trait VectorRound {
662+
unsafe fn vec_round(self) -> Self;
663+
}
648664

649-
#[inline]
650-
#[target_feature(enable = "vector")]
651-
unsafe fn vec_round(self) -> Self {
652-
// NOTE: simd_round resoles ties by rounding away from zero,
653-
// while the vec_round function rounds towards zero
654-
self.vec_round_impl::<4, 4>()
655-
}
665+
#[unstable(feature = "stdarch_s390x", issue = "135681")]
666+
pub trait VectorRint {
667+
unsafe fn vec_rint(self) -> Self;
668+
}
656669

657-
// NOTE: vec_roundz (vec_round_impl::<4, 5>) is the same as vec_trunc
658-
#[inline]
659-
#[target_feature(enable = "vector")]
660-
unsafe fn vec_trunc(self) -> Self {
661-
simd_trunc(self)
662-
}
670+
impl_vec_trait! { [VectorRoundc vec_roundc] vec_roundc_f32 (vector_float) }
671+
impl_vec_trait! { [VectorRoundc vec_roundc] vec_roundc_f64 (vector_double) }
663672

664-
// NOTE: vec_roundp (vec_round_impl::<4, 6>) is the same as vec_ceil
665-
#[inline]
666-
#[target_feature(enable = "vector")]
667-
unsafe fn vec_ceil(self) -> Self {
668-
simd_ceil(self)
669-
}
673+
impl_vec_trait! { [VectorRound vec_round] vec_round_f32 (vector_float) }
674+
impl_vec_trait! { [VectorRound vec_round] vec_round_f64 (vector_double) }
670675

671-
// NOTE: vec_roundm (vec_round_impl::<4, 7>) is the same as vec_floor
672-
#[inline]
673-
#[target_feature(enable = "vector")]
674-
unsafe fn vec_floor(self) -> Self {
675-
simd_floor(self)
676-
}
676+
impl_vec_trait! { [VectorRint vec_rint] vec_rint_f32 (vector_float) }
677+
impl_vec_trait! { [VectorRint vec_rint] vec_rint_f64 (vector_double) }
677678

678-
#[inline]
679-
#[target_feature(enable = "vector")]
680-
unsafe fn vec_rint(self) -> Self {
681-
self.vec_round_impl::<0, 0>()
682-
}
679+
#[unstable(feature = "stdarch_s390x", issue = "135681")]
680+
pub trait VectorTrunc {
681+
// same as vec_roundz
682+
unsafe fn vec_trunc(self) -> Self;
683683
}
684684

685-
// FIXME(vector-enhancements-1) apply the right target feature to all methods
686685
#[unstable(feature = "stdarch_s390x", issue = "135681")]
687-
impl VectorRound for vector_float {
688-
#[inline]
689-
#[target_feature(enable = "vector")]
690-
unsafe fn vec_round_impl<const N: i32, const MODE: i32>(self) -> Self {
691-
vfisb(self, N, MODE)
692-
}
686+
pub trait VectorCeil {
687+
// same as vec_roundp
688+
unsafe fn vec_ceil(self) -> Self;
693689
}
694690

695691
#[unstable(feature = "stdarch_s390x", issue = "135681")]
696-
impl VectorRound for vector_double {
697-
#[inline]
698-
#[target_feature(enable = "vector")]
699-
unsafe fn vec_round_impl<const N: i32, const MODE: i32>(self) -> Self {
700-
vfidb(self, N, MODE)
701-
}
692+
pub trait VectorFloor {
693+
// same as vec_roundm
694+
unsafe fn vec_floor(self) -> Self;
702695
}
696+
697+
impl_vec_trait! { [VectorTrunc vec_trunc] simd_trunc (vector_float) }
698+
impl_vec_trait! { [VectorTrunc vec_trunc] simd_trunc (vector_double) }
699+
700+
impl_vec_trait! { [VectorCeil vec_ceil] simd_ceil (vector_float) }
701+
impl_vec_trait! { [VectorCeil vec_ceil] simd_ceil (vector_double) }
702+
703+
impl_vec_trait! { [VectorFloor vec_floor] simd_floor (vector_float) }
704+
impl_vec_trait! { [VectorFloor vec_floor] simd_floor (vector_double) }
703705
}
704706

705707
/// Vector element-wise addition.
@@ -920,7 +922,7 @@ where
920922
#[unstable(feature = "stdarch_s390x", issue = "135681")]
921923
pub unsafe fn vec_floor<T>(a: T) -> T
922924
where
923-
T: sealed::VectorRound,
925+
T: sealed::VectorFloor,
924926
{
925927
a.vec_floor()
926928
}
@@ -931,7 +933,7 @@ where
931933
#[unstable(feature = "stdarch_s390x", issue = "135681")]
932934
pub unsafe fn vec_ceil<T>(a: T) -> T
933935
where
934-
T: sealed::VectorRound,
936+
T: sealed::VectorCeil,
935937
{
936938
a.vec_ceil()
937939
}
@@ -943,12 +945,13 @@ where
943945
#[unstable(feature = "stdarch_s390x", issue = "135681")]
944946
pub unsafe fn vec_trunc<T>(a: T) -> T
945947
where
946-
T: sealed::VectorRound,
948+
T: sealed::VectorTrunc,
947949
{
948950
a.vec_trunc()
949951
}
950952

951-
/// Vector round, resolves ties by rounding towards zero.
953+
/// Returns a vector containing the rounded values to the nearest representable floating-point integer,
954+
/// using IEEE round-to-nearest rounding, of the corresponding elements of the given vector
952955
#[inline]
953956
#[target_feature(enable = "vector")]
954957
#[unstable(feature = "stdarch_s390x", issue = "135681")]
@@ -966,7 +969,7 @@ where
966969
#[unstable(feature = "stdarch_s390x", issue = "135681")]
967970
pub unsafe fn vec_roundc<T>(a: T) -> T
968971
where
969-
T: sealed::VectorRound,
972+
T: sealed::VectorRoundc,
970973
{
971974
a.vec_roundc()
972975
}
@@ -978,7 +981,7 @@ where
978981
#[unstable(feature = "stdarch_s390x", issue = "135681")]
979982
pub unsafe fn vec_roundm<T>(a: T) -> T
980983
where
981-
T: sealed::VectorRound,
984+
T: sealed::VectorFloor,
982985
{
983986
// the IBM docs note
984987
//
@@ -995,7 +998,7 @@ where
995998
#[unstable(feature = "stdarch_s390x", issue = "135681")]
996999
pub unsafe fn vec_roundp<T>(a: T) -> T
9971000
where
998-
T: sealed::VectorRound,
1001+
T: sealed::VectorCeil,
9991002
{
10001003
// the IBM docs note
10011004
//
@@ -1012,7 +1015,7 @@ where
10121015
#[unstable(feature = "stdarch_s390x", issue = "135681")]
10131016
pub unsafe fn vec_roundz<T>(a: T) -> T
10141017
where
1015-
T: sealed::VectorRound,
1018+
T: sealed::VectorTrunc,
10161019
{
10171020
// the IBM docs note
10181021
//
@@ -1028,7 +1031,7 @@ where
10281031
#[unstable(feature = "stdarch_s390x", issue = "135681")]
10291032
pub unsafe fn vec_rint<T>(a: T) -> T
10301033
where
1031-
T: sealed::VectorRound,
1034+
T: sealed::VectorRint,
10321035
{
10331036
a.vec_rint()
10341037
}
@@ -1304,11 +1307,16 @@ mod tests {
13041307
[1.0, 1.0]
13051308
}
13061309

1307-
// FIXME(vector-enhancements-1)
1308-
// test_vec_1! { test_vec_round_f32, vec_round, f32x4,
1309-
// [],
1310-
// []
1311-
// }
1310+
test_vec_1! { test_vec_round_f32, vec_round, f32x4,
1311+
[0.1, 0.5, 0.6, 0.9],
1312+
[0.0, 0.0, 1.0, 1.0]
1313+
}
1314+
1315+
test_vec_1! { test_vec_round_f32_even_odd, vec_round, f32x4,
1316+
[0.5, 1.5, 2.5, 3.5],
1317+
[0.0, 2.0, 2.0, 4.0]
1318+
}
1319+
13121320
test_vec_1! { test_vec_round_f64_1, vec_round, f64x2,
13131321
[0.1, 0.5],
13141322
[0.0, 0.0]
@@ -1318,11 +1326,16 @@ mod tests {
13181326
[1.0, 1.0]
13191327
}
13201328

1321-
// FIXME(vector-enhancements-1)
1322-
// test_vec_1! { test_vec_roundc_f32, vec_roundc, f32x4,
1323-
// [],
1324-
// []
1325-
// }
1329+
test_vec_1! { test_vec_roundc_f32, vec_roundc, f32x4,
1330+
[0.1, 0.5, 0.6, 0.9],
1331+
[0.0, 0.0, 1.0, 1.0]
1332+
}
1333+
1334+
test_vec_1! { test_vec_roundc_f32_even_odd, vec_roundc, f32x4,
1335+
[0.5, 1.5, 2.5, 3.5],
1336+
[0.0, 2.0, 2.0, 4.0]
1337+
}
1338+
13261339
test_vec_1! { test_vec_roundc_f64_1, vec_roundc, f64x2,
13271340
[0.1, 0.5],
13281341
[0.0, 0.0]
@@ -1332,11 +1345,16 @@ mod tests {
13321345
[1.0, 1.0]
13331346
}
13341347

1335-
// FIXME(vector-enhancements-1)
1336-
// test_vec_1! { test_vec_rint_f32, vec_rint, f32x4,
1337-
// [],
1338-
// []
1339-
// }
1348+
test_vec_1! { test_vec_rint_f32, vec_rint, f32x4,
1349+
[0.1, 0.5, 0.6, 0.9],
1350+
[0.0, 0.0, 1.0, 1.0]
1351+
}
1352+
1353+
test_vec_1! { test_vec_rint_f32_even_odd, vec_rint, f32x4,
1354+
[0.5, 1.5, 2.5, 3.5],
1355+
[0.0, 2.0, 2.0, 4.0]
1356+
}
1357+
13401358
test_vec_1! { test_vec_rint_f64_1, vec_rint, f64x2,
13411359
[0.1, 0.5],
13421360
[0.0, 0.0]

0 commit comments

Comments
 (0)