]> git.lizzy.rs Git - rust.git/commitdiff
implement simd_saturating intrinsics
authorRalf Jung <post@ralfj.de>
Mon, 7 Mar 2022 19:12:59 +0000 (14:12 -0500)
committerRalf Jung <post@ralfj.de>
Mon, 7 Mar 2022 19:12:59 +0000 (14:12 -0500)
rust-version
src/shims/intrinsics.rs
tests/run-pass/portable-simd.rs

index a769188204f5a8697a18fc4f998b88909d775909..dcc365ef0ad9b51cc363f807a4641755665d4a1c 100644 (file)
@@ -1 +1 @@
-297273c45b205820a4c055082c71677197a40b55
+d137c3a7bd3b180317044f8ccb9a8b4b3bb07db3
index 897ebe4ae79fa231ce9d328ea030a794e0442bf6..49c9c0fb0d9657beb25df8017ee959b128d13145 100644 (file)
@@ -372,7 +372,9 @@ enum Op {
             | "simd_gt"
             | "simd_ge"
             | "simd_fmax"
-            | "simd_fmin" => {
+            | "simd_fmin"
+            | "simd_saturating_add"
+            | "simd_saturating_sub" => {
                 use mir::BinOp;
 
                 let &[ref left, ref right] = check_arg_count(args)?;
@@ -385,6 +387,7 @@ enum Op {
 
                 enum Op {
                     MirOp(BinOp),
+                    SaturatingOp(BinOp),
                     FMax,
                     FMin,
                 }
@@ -407,6 +410,8 @@ enum Op {
                     "simd_ge" => Op::MirOp(BinOp::Ge),
                     "simd_fmax" => Op::FMax,
                     "simd_fmin" => Op::FMin,
+                    "simd_saturating_add" => Op::SaturatingOp(BinOp::Add),
+                    "simd_saturating_sub" => Op::SaturatingOp(BinOp::Sub),
                     _ => unreachable!(),
                 };
 
@@ -442,6 +447,9 @@ enum Op {
                         Op::FMin => {
                             fmin_op(&left, &right)?
                         }
+                        Op::SaturatingOp(mir_op) => {
+                            this.saturating_arith(mir_op, &left, &right)?
+                        }
                     };
                     this.write_scalar(val, &dest.into())?;
                 }
index 48297ee4e6901eaaf4c58b2d4426c31051ccbbe7..b87bd4fd6ad2a585c79d85faddd17375f0e1bac7 100644 (file)
@@ -102,10 +102,27 @@ fn simd_ops_i32() {
     assert_eq!(a % b, i32x4::from_array([0, 0, 1, 2]));
     assert_eq!(i32x2::splat(i32::MIN) % i32x2::splat(-1), i32x2::splat(0));
     assert_eq!(b.abs(), i32x4::from_array([1, 2, 3, 4]));
-    // FIXME not a per-lane method (https://github.com/rust-lang/rust/issues/94682)
+    // FIXME not a per-lane method (https://github.com/rust-lang/portable-simd/issues/247)
     // assert_eq!(a.max(b * i32x4::splat(4)), i32x4::from_array([10, 10, 12, 10]));
     // assert_eq!(a.min(b * i32x4::splat(4)), i32x4::from_array([4, 8, 10, -16]));
 
+    assert_eq!(
+        i8x4::from_array([i8::MAX, -23, 23, i8::MIN]).saturating_add(i8x4::from_array([1, i8::MIN, i8::MAX, 28])),
+        i8x4::from_array([i8::MAX, i8::MIN, i8::MAX, -100])
+    );
+    assert_eq!(
+        i8x4::from_array([i8::MAX, -28, 27, 42]).saturating_sub(i8x4::from_array([1, i8::MAX, i8::MAX, -80])),
+        i8x4::from_array([126, i8::MIN, -100, 122])
+    );
+    assert_eq!(
+        u8x4::from_array([u8::MAX, 0, 23, 42]).saturating_add(u8x4::from_array([1, 1, u8::MAX, 200])),
+        u8x4::from_array([u8::MAX, 1, u8::MAX, 242])
+    );
+    assert_eq!(
+        u8x4::from_array([u8::MAX, 0, 23, 42]).saturating_sub(u8x4::from_array([1, 1, u8::MAX, 200])),
+        u8x4::from_array([254, 0, 0, 0])
+    );
+
     assert_eq!(!b, i32x4::from_array([!1, !2, !3, !-4]));
     assert_eq!(b << i32x4::splat(2), i32x4::from_array([4, 8, 12, -16]));
     assert_eq!(b >> i32x4::splat(1), i32x4::from_array([0, 1, 1, -2]));