Skip to content

Commit de8f85b

Browse files
committed
Add _mm_cmpunord_ss
1 parent 66cd292 commit de8f85b

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
@@ -329,6 +329,17 @@ pub unsafe fn _mm_cmpord_ss(a: f32x4, b: f32x4) -> f32x4 {
329329
cmpss(a, b, 7)
330330
}
331331

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

13391350
#[simd_test = "sse"]
13401351
unsafe fn _mm_cmpord_ss() {
1341-
// TODO: This test is exactly the same as for _mm_cmplt_ss, but there
1342-
// must be a difference. It may have to do with behavior in the presence
1343-
// of NaNs (signaling or quiet). If so, we should add tests for those.
13441352
use std::mem::transmute;
13451353
use std::f32::NAN;
13461354

@@ -1366,6 +1374,33 @@ mod tests {
13661374
assert_eq!(rd, ed);
13671375
}
13681376

1377+
#[simd_test = "sse"]
1378+
unsafe fn _mm_cmpunord_ss() {
1379+
use std::mem::transmute;
1380+
use std::f32::NAN;
1381+
1382+
let a = f32x4::new(1.0, 2.0, 3.0, 4.0);
1383+
let b = f32x4::new(0.0, 5.0, 6.0, 7.0);
1384+
let c = f32x4::new(NAN, 5.0, 6.0, 7.0);
1385+
let d = f32x4::new(2.0, 5.0, 6.0, 7.0);
1386+
1387+
let b1 = 0u32; // a.extract(0) unord b.extract(0)
1388+
let c1 = !0u32; // a.extract(0) unord c.extract(0)
1389+
let d1 = 0u32; // a.extract(0) unord d.extract(0)
1390+
1391+
let rb: u32x4 = transmute(sse::_mm_cmpunord_ss(a, b));
1392+
let eb: u32x4 = transmute(f32x4::new(transmute(b1), 2.0, 3.0, 4.0));
1393+
assert_eq!(rb, eb);
1394+
1395+
let rc: u32x4 = transmute(sse::_mm_cmpunord_ss(a, c));
1396+
let ec: u32x4 = transmute(f32x4::new(transmute(c1), 2.0, 3.0, 4.0));
1397+
assert_eq!(rc, ec);
1398+
1399+
let rd: u32x4 = transmute(sse::_mm_cmpunord_ss(a, d));
1400+
let ed: u32x4 = transmute(f32x4::new(transmute(d1), 2.0, 3.0, 4.0));
1401+
assert_eq!(rd, ed);
1402+
}
1403+
13691404
#[simd_test = "sse"]
13701405
unsafe fn _mm_set_ss() {
13711406
let r = sse::_mm_set_ss(black_box(4.25));

0 commit comments

Comments
 (0)