Skip to content

Commit 76dcd3c

Browse files
committed
Add _mm_cmpunord_ss
1 parent 6147f16 commit 76dcd3c

File tree

1 file changed

+38
-3
lines changed

1 file changed

+38
-3
lines changed

src/x86/sse.rs

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,17 @@ pub unsafe fn _mm_cmpord_ss(a: f32x4, b: f32x4) -> f32x4 {
331331
cmpss(a, b, 7)
332332
}
333333

334+
/// Check if the lowest `f32` of both inputs are unordered. The lowest 32 bits
335+
/// of the result will be `0xffffffff` if any of `a.extract(0)` or
336+
/// `b.extract(0)` is a NaN, or `0` otherwise. The upper 96 bits of the result
337+
/// are the upper 96 bits of `a`.
338+
#[inline(always)]
339+
#[target_feature = "+sse"]
340+
#[cfg_attr(test, assert_instr(cmpunordss))]
341+
pub unsafe fn _mm_cmpunord_ss(a: f32x4, b: f32x4) -> f32x4 {
342+
cmpss(a, b, 3)
343+
}
344+
334345
/// Construct a `f32x4` with the lowest element set to `a` and the rest set to
335346
/// zero.
336347
#[inline(always)]
@@ -1535,9 +1546,6 @@ mod tests {
15351546

15361547
#[simd_test = "sse"]
15371548
unsafe fn _mm_cmpord_ss() {
1538-
// TODO: This test is exactly the same as for _mm_cmplt_ss, but there
1539-
// must be a difference. It may have to do with behavior in the presence
1540-
// of NaNs (signaling or quiet). If so, we should add tests for those.
15411549
use std::mem::transmute;
15421550
use std::f32::NAN;
15431551

@@ -1563,6 +1571,33 @@ mod tests {
15631571
assert_eq!(rd, ed);
15641572
}
15651573

1574+
#[simd_test = "sse"]
1575+
unsafe fn _mm_cmpunord_ss() {
1576+
use std::mem::transmute;
1577+
use std::f32::NAN;
1578+
1579+
let a = f32x4::new(1.0, 2.0, 3.0, 4.0);
1580+
let b = f32x4::new(0.0, 5.0, 6.0, 7.0);
1581+
let c = f32x4::new(NAN, 5.0, 6.0, 7.0);
1582+
let d = f32x4::new(2.0, 5.0, 6.0, 7.0);
1583+
1584+
let b1 = 0u32; // a.extract(0) unord b.extract(0)
1585+
let c1 = !0u32; // a.extract(0) unord c.extract(0)
1586+
let d1 = 0u32; // a.extract(0) unord d.extract(0)
1587+
1588+
let rb: u32x4 = transmute(sse::_mm_cmpunord_ss(a, b));
1589+
let eb: u32x4 = transmute(f32x4::new(transmute(b1), 2.0, 3.0, 4.0));
1590+
assert_eq!(rb, eb);
1591+
1592+
let rc: u32x4 = transmute(sse::_mm_cmpunord_ss(a, c));
1593+
let ec: u32x4 = transmute(f32x4::new(transmute(c1), 2.0, 3.0, 4.0));
1594+
assert_eq!(rc, ec);
1595+
1596+
let rd: u32x4 = transmute(sse::_mm_cmpunord_ss(a, d));
1597+
let ed: u32x4 = transmute(f32x4::new(transmute(d1), 2.0, 3.0, 4.0));
1598+
assert_eq!(rd, ed);
1599+
}
1600+
15661601
#[simd_test = "sse"]
15671602
unsafe fn _mm_set_ss() {
15681603
let r = sse::_mm_set_ss(black_box(4.25));

0 commit comments

Comments
 (0)