Skip to content

Commit fe6f4d9

Browse files
committed
PowerPC:Add vec_min/vec_max support for vector float/double
Adds floating-point support to the existing vec_min and vec_max intrinsics for PowerPC.
1 parent 6332f19 commit fe6f4d9

3 files changed

Lines changed: 103 additions & 29 deletions

File tree

crates/core_arch/src/powerpc/altivec.rs

Lines changed: 22 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,11 @@ unsafe extern "unadjusted" {
230230
#[link_name = "llvm.umin.v4i32"]
231231
fn vminuw(a: vector_unsigned_int, b: vector_unsigned_int) -> vector_unsigned_int;
232232

233+
#[link_name = "llvm.ppc.altivec.vmaxfp"]
234+
fn vmaxfp(a: vector_float, b: vector_float) -> vector_float;
235+
#[link_name = "llvm.ppc.altivec.vminfp"]
236+
fn vminfp(a: vector_float, b: vector_float) -> vector_float;
237+
233238
#[link_name = "llvm.ppc.altivec.vsubsbs"]
234239
fn vsubsbs(a: vector_signed_char, b: vector_signed_char) -> vector_signed_char;
235240
#[link_name = "llvm.ppc.altivec.vsubshs"]
@@ -411,7 +416,7 @@ unsafe extern "unadjusted" {
411416
}
412417

413418
#[macro_use]
414-
mod sealed {
419+
pub(crate) mod sealed {
415420
use super::*;
416421

417422
#[unstable(feature = "stdarch_powerpc", issue = "111145")]
@@ -1657,13 +1662,16 @@ mod sealed {
16571662
test_impl! { vec_vminuh (a: vector_unsigned_short, b: vector_unsigned_short) -> vector_unsigned_short [vminuh, vminuh] }
16581663
test_impl! { vec_vminuw (a: vector_unsigned_int, b: vector_unsigned_int) -> vector_unsigned_int [vminuw, vminuw] }
16591664

1665+
test_impl! { vec_vminfp (a: vector_float, b: vector_float) -> vector_float [vminfp, vminfp / xvminsp] }
1666+
16601667
#[unstable(feature = "stdarch_powerpc", issue = "111145")]
16611668
pub trait VectorMin<Other> {
16621669
type Result;
16631670
unsafe fn vec_min(self, b: Other) -> Self::Result;
16641671
}
16651672

16661673
impl_vec_trait! { [VectorMin vec_min] ~(vminub, vminsb, vminuh, vminsh, vminuw, vminsw) }
1674+
impl_vec_trait! { [VectorMin vec_min] vec_vminfp(vector_float, vector_float) -> vector_float }
16671675

16681676
test_impl! { vec_vmaxsb (a: vector_signed_char, b: vector_signed_char) -> vector_signed_char [vmaxsb, vmaxsb] }
16691677
test_impl! { vec_vmaxsh (a: vector_signed_short, b: vector_signed_short) -> vector_signed_short [vmaxsh, vmaxsh] }
@@ -1673,13 +1681,16 @@ mod sealed {
16731681
test_impl! { vec_vmaxuh (a: vector_unsigned_short, b: vector_unsigned_short) -> vector_unsigned_short [vmaxuh, vmaxuh] }
16741682
test_impl! { vec_vmaxuw (a: vector_unsigned_int, b: vector_unsigned_int) -> vector_unsigned_int [vmaxuw, vmaxuw] }
16751683

1684+
test_impl! { vec_vmaxfp (a: vector_float, b: vector_float) -> vector_float [vmaxfp, vmaxfp / xvmaxsp] }
1685+
16761686
#[unstable(feature = "stdarch_powerpc", issue = "111145")]
16771687
pub trait VectorMax<Other> {
16781688
type Result;
16791689
unsafe fn vec_max(self, b: Other) -> Self::Result;
16801690
}
16811691

16821692
impl_vec_trait! { [VectorMax vec_max] ~(vmaxub, vmaxsb, vmaxuh, vmaxsh, vmaxuw, vmaxsw) }
1693+
impl_vec_trait! { [VectorMax vec_max] vec_vmaxfp(vector_float, vector_float) -> vector_float }
16831694

16841695
#[inline]
16851696
#[target_feature(enable = "altivec")]
@@ -4685,7 +4696,7 @@ mod endian {
46854696
pub use self::endian::*;
46864697

46874698
#[cfg(test)]
4688-
mod tests {
4699+
pub(crate) mod tests {
46894700
use super::*;
46904701

46914702
use std::mem::transmute;
@@ -6118,20 +6129,6 @@ mod tests {
61186129
[2, 1, 0, 0, 2, 1, 0, 0, 2, 1, 0, 0, 2, 1, 0, 0],
61196130
[0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2] }
61206131

6121-
macro_rules! test_vec_min {
6122-
{ $name: ident, $ty: ident, [$($a:expr),+], [$($b:expr),+], [$($d:expr),+] } => {
6123-
#[simd_test(enable = "altivec")]
6124-
fn $name() {
6125-
let a: s_t_l!($ty) = $ty::new($($a),+).into();
6126-
let b: s_t_l!($ty) = $ty::new($($b),+).into();
6127-
6128-
let d = $ty::new($($d),+);
6129-
let r = $ty::from(unsafe { vec_min(a, b) });
6130-
assert_eq!(d, r);
6131-
}
6132-
}
6133-
}
6134-
61356132
test_vec_min! { test_vec_min_i32x4, i32x4,
61366133
[-1, 0, 1, 2],
61376134
[2, 1, -1, -2],
@@ -6162,19 +6159,10 @@ mod tests {
61626159
[2, 1, 0, 0, 2, 1, 0, 0, 2, 1, 0, 0, 2, 1, 0, 0],
61636160
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] }
61646161

6165-
macro_rules! test_vec_max {
6166-
{ $name: ident, $ty: ident, [$($a:expr),+], [$($b:expr),+], [$($d:expr),+] } => {
6167-
#[simd_test(enable = "altivec")]
6168-
fn $name() {
6169-
let a: s_t_l!($ty) = $ty::new($($a),+).into();
6170-
let b: s_t_l!($ty) = $ty::new($($b),+).into();
6171-
6172-
let d = $ty::new($($d),+);
6173-
let r = $ty::from(unsafe { vec_max(a, b) });
6174-
assert_eq!(d, r);
6175-
}
6176-
}
6177-
}
6162+
test_vec_min! { test_vec_min_f32x4, f32x4,
6163+
[-1.0, 0.0, 1.0, 2.0],
6164+
[2.0, 1.0, -1.0, -2.0],
6165+
[-1.0, 0.0, -1.0, -2.0] }
61786166

61796167
test_vec_max! { test_vec_max_i32x4, i32x4,
61806168
[-1, 0, 1, 2],
@@ -6206,6 +6194,11 @@ mod tests {
62066194
[2, 1, 0, 0, 2, 1, 0, 0, 2, 1, 0, 0, 2, 1, 0, 0],
62076195
[2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2] }
62086196

6197+
test_vec_max! { test_vec_max_f32x4, f32x4,
6198+
[-1.0, 0.0, 1.0, 2.0],
6199+
[2.0, 1.0, -1.0, -2.0],
6200+
[2.0, 1.0, 1.0, 2.0] }
6201+
62096202
macro_rules! test_vec_perm {
62106203
{$name:ident,
62116204
$shorttype:ident, $longtype:ident,

crates/core_arch/src/powerpc/macros.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,9 @@ macro_rules! s_t_l {
154154
(f32x4) => {
155155
vector_float
156156
};
157+
(f64x2) => {
158+
vector_double
159+
};
157160
}
158161

159162
macro_rules! t_t_l {
@@ -274,10 +277,44 @@ macro_rules! t_b {
274277
};
275278
}
276279

280+
#[cfg(test)]
281+
macro_rules! test_vec_min {
282+
{ $name: ident, $ty: ident, [$($a:expr),+], [$($b:expr),+], [$($d:expr),+] } => {
283+
#[simd_test(enable = "altivec")]
284+
fn $name() {
285+
let a: s_t_l!($ty) = $ty::new($($a),+).into();
286+
let b: s_t_l!($ty) = $ty::new($($b),+).into();
287+
288+
let d = $ty::new($($d),+);
289+
let r = $ty::from(unsafe { vec_min(a, b) });
290+
assert_eq!(d, r);
291+
}
292+
}
293+
}
294+
295+
#[cfg(test)]
296+
macro_rules! test_vec_max {
297+
{ $name: ident, $ty: ident, [$($a:expr),+], [$($b:expr),+], [$($d:expr),+] } => {
298+
#[simd_test(enable = "altivec")]
299+
fn $name() {
300+
let a: s_t_l!($ty) = $ty::new($($a),+).into();
301+
let b: s_t_l!($ty) = $ty::new($($b),+).into();
302+
303+
let d = $ty::new($($d),+);
304+
let r = $ty::from(unsafe { vec_max(a, b) });
305+
assert_eq!(d, r);
306+
}
307+
}
308+
}
309+
277310
pub(crate) use impl_vec_trait;
278311
pub(crate) use s_t_l;
279312
pub(crate) use t_b;
280313
pub(crate) use t_t_l;
281314
pub(crate) use t_t_s;
282315
pub(crate) use t_u;
283316
pub(crate) use test_impl;
317+
#[cfg(test)]
318+
pub(crate) use test_vec_max;
319+
#[cfg(test)]
320+
pub(crate) use test_vec_min;

crates/core_arch/src/powerpc/vsx.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,11 @@ unsafe extern "unadjusted" {
5959
b: vector_signed_int,
6060
c: vector_unsigned_char,
6161
) -> vector_signed_int;
62+
63+
#[link_name = "llvm.ppc.vsx.xvmaxdp"]
64+
fn xvmaxdp(a: vector_double, b: vector_double) -> vector_double;
65+
#[link_name = "llvm.ppc.vsx.xvmindp"]
66+
fn xvmindp(a: vector_double, b: vector_double) -> vector_double;
6267
}
6368

6469
mod sealed {
@@ -171,6 +176,40 @@ mod sealed {
171176
vec_mergeeo! { vector_unsigned_int, mergee, mergeo }
172177
vec_mergeeo! { vector_bool_int, mergee, mergeo }
173178
vec_mergeeo! { vector_float, mergee, mergeo }
179+
180+
#[inline]
181+
#[target_feature(enable = "vsx")]
182+
#[cfg_attr(test, assert_instr(xvmindp))]
183+
unsafe fn vec_xvmindp(a: vector_double, b: vector_double) -> vector_double {
184+
xvmindp(a, b)
185+
}
186+
187+
#[inline]
188+
#[target_feature(enable = "vsx")]
189+
#[cfg_attr(test, assert_instr(xvmaxdp))]
190+
unsafe fn vec_xvmaxdp(a: vector_double, b: vector_double) -> vector_double {
191+
xvmaxdp(a, b)
192+
}
193+
194+
#[unstable(feature = "stdarch_powerpc", issue = "111145")]
195+
impl super::altivec::sealed::VectorMin<vector_double> for vector_double {
196+
type Result = vector_double;
197+
#[inline]
198+
#[target_feature(enable = "vsx")]
199+
unsafe fn vec_min(self, b: vector_double) -> Self::Result {
200+
vec_xvmindp(self, b)
201+
}
202+
}
203+
204+
#[unstable(feature = "stdarch_powerpc", issue = "111145")]
205+
impl super::altivec::sealed::VectorMax<vector_double> for vector_double {
206+
type Result = vector_double;
207+
#[inline]
208+
#[target_feature(enable = "vsx")]
209+
unsafe fn vec_max(self, b: vector_double) -> Self::Result {
210+
vec_xvmaxdp(self, b)
211+
}
212+
}
174213
}
175214

176215
/// Vector permute.
@@ -234,6 +273,8 @@ mod tests {
234273
use crate::mem::transmute;
235274
use stdarch_test::simd_test;
236275

276+
use super::super::macros::*;
277+
237278
macro_rules! test_vec_xxpermdi {
238279
{$name:ident, $shorttype:ident, $longtype:ident, [$($a:expr),+], [$($b:expr),+], [$($c:expr),+], [$($d:expr),+]} => {
239280
#[simd_test(enable = "vsx")]
@@ -255,4 +296,7 @@ mod tests {
255296
test_vec_xxpermdi! {test_vec_xxpermdi_i64x2, i64x2, vector_signed_long, [0], [-1], [2], [-3]}
256297
test_vec_xxpermdi! {test_vec_xxpermdi_m64x2, m64x2, vector_bool_long, [false], [true], [false], [true]}
257298
test_vec_xxpermdi! {test_vec_xxpermdi_f64x2, f64x2, vector_double, [0.0], [1.0], [2.0], [3.0]}
299+
300+
test_vec_min! { test_vec_min_f64x2, f64x2, [-1.0, 0.0], [2.0, 1.0], [-1.0, 0.0] }
301+
test_vec_max! { test_vec_max_f64x2, f64x2, [-1.0, 0.0], [2.0, 1.0], [2.0, 1.0] }
258302
}

0 commit comments

Comments
 (0)