about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbjorn3 <bjorn3@users.noreply.github.com>2019-07-27 17:52:57 +0200
committerbjorn3 <bjorn3@users.noreply.github.com>2019-07-29 11:03:55 +0200
commit9e3f2391b8f9da831c8aa25ce8cdc4eb4dc300ef (patch)
treeb7ea540e18177670a5a2eae70194d9b0cfd6e1b2
parent7fdd058c609e9cc727b44a63fd4d9d1ad3cef206 (diff)
downloadrust-9e3f2391b8f9da831c8aa25ce8cdc4eb4dc300ef.tar.gz
rust-9e3f2391b8f9da831c8aa25ce8cdc4eb4dc300ef.zip
Emulate compare simd intrinsics
-rw-r--r--src/intrinsics.rs38
1 files changed, 38 insertions, 0 deletions
diff --git a/src/intrinsics.rs b/src/intrinsics.rs
index 8efeb0b4acc..3fd1d5fd6d4 100644
--- a/src/intrinsics.rs
+++ b/src/intrinsics.rs
@@ -156,6 +156,25 @@ fn simd_for_each_lane<'tcx, B: Backend>(
 }
 
 macro_rules! simd_binop {
+    ($fx:expr, $intrinsic:expr, icmp($cc:ident, $x:ident, $y:ident) -> $ret:ident) => {
+        simd_for_each_lane($fx, $intrinsic, $x, $y, $ret, |fx, _lane_layout, ret_lane_layout, x_lane, y_lane| {
+            let res_lane = fx.bcx.ins().icmp(IntCC::$cc, x_lane, y_lane);
+            let res_lane = fx.bcx.ins().bint(types::I8, res_lane);
+            CValue::by_val(res_lane, ret_lane_layout)
+        });
+    };
+    ($fx:expr, $intrinsic:expr, icmp($cc_u:ident|$cc_s:ident, $x:ident, $y:ident) -> $ret:ident) => {
+        simd_for_each_lane($fx, $intrinsic, $x, $y, $ret, |fx, lane_layout, ret_lane_layout, x_lane, y_lane| {
+            let res_lane = match lane_layout.ty.sty {
+                ty::Uint(_) => fx.bcx.ins().icmp(IntCC::$cc_u, x_lane, y_lane),
+                ty::Int(_) => fx.bcx.ins().icmp(IntCC::$cc_s, x_lane, y_lane),
+                _ => unreachable!("{:?}", lane_layout.ty),
+            };
+            let res_lane = fx.bcx.ins().bint(types::I8, res_lane);
+            CValue::by_val(res_lane, ret_lane_layout)
+        });
+    };
+
     ($fx:expr, $intrinsic:expr, $op:ident($x:ident, $y:ident) -> $ret:ident) => {
         simd_for_each_lane($fx, $intrinsic, $x, $y, $ret, |fx, _lane_layout, ret_lane_layout, x_lane, y_lane| {
             let res_lane = fx.bcx.ins().$op(x_lane, y_lane);
@@ -753,6 +772,25 @@ pub fn codegen_intrinsic_call<'a, 'tcx: 'a>(
             ret.write_cvalue(fx, x.unchecked_cast_to(ret.layout()));
         };
 
+        simd_eq, (c x, c y) {
+            simd_binop!(fx, intrinsic, icmp(Equal, x, y) -> ret);
+        };
+        simd_ne, (c x, c y) {
+            simd_binop!(fx, intrinsic, icmp(NotEqual, x, y) -> ret);
+        };
+        simd_lt, (c x, c y) {
+            simd_binop!(fx, intrinsic, icmp(UnsignedLessThan|SignedLessThan, x, y) -> ret);
+        };
+        simd_le, (c x, c y) {
+            simd_binop!(fx, intrinsic, icmp(UnsignedLessThanOrEqual|SignedLessThanOrEqual, x, y) -> ret);
+        };
+        simd_gt, (c x, c y) {
+            simd_binop!(fx, intrinsic, icmp(UnsignedGreaterThan|SignedGreaterThan, x, y) -> ret);
+        };
+        simd_ge, (c x, c y) {
+            simd_binop!(fx, intrinsic, icmp(UnsignedGreaterThanOrEqual|SignedGreaterThanOrEqual, x, y) -> ret);
+        };
+
         simd_add, (c x, c y) {
             simd_binop!(fx, intrinsic, iadd(x, y) -> ret);
         };