about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorHuon Wilson <dbau.pp+github@gmail.com>2015-07-31 11:23:12 -0700
committerHuon Wilson <dbau.pp+github@gmail.com>2015-08-17 14:41:38 -0700
commit8d8b489bc93b2f8754a0de386bd4e960b05a5b47 (patch)
treecfa8a3ea71868dee34bd1855a0e1da21c5b45237 /src
parentecb3df5a91b71e31e242737d9203b2798bd489de (diff)
downloadrust-8d8b489bc93b2f8754a0de386bd4e960b05a5b47.tar.gz
rust-8d8b489bc93b2f8754a0de386bd4e960b05a5b47.zip
Add intrinsics for SIMD arithmetic.
Diffstat (limited to 'src')
-rw-r--r--src/librustc_trans/trans/intrinsic.rs30
-rw-r--r--src/librustc_typeck/check/mod.rs5
2 files changed, 35 insertions, 0 deletions
diff --git a/src/librustc_trans/trans/intrinsic.rs b/src/librustc_trans/trans/intrinsic.rs
index 88a80076640..a31668ad212 100644
--- a/src/librustc_trans/trans/intrinsic.rs
+++ b/src/librustc_trans/trans/intrinsic.rs
@@ -1496,5 +1496,35 @@ fn generic_simd_intrinsic<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
         }
         require!(false, "SIMD cast intrinsic monomorphised with incompatible cast");
     }
+    macro_rules! arith {
+        ($($name: ident: $($($p: ident),* => $call: expr),*;)*) => {
+            $(
+                if name == stringify!($name) {
+                    let in_ = arg_tys[0].simd_type(tcx);
+                    match in_.sty {
+                        $(
+                            $(ty::$p(_))|* => {
+                                return $call(bcx, llargs[0], llargs[1], call_debug_location)
+                            }
+                            )*
+                        _ => {},
+                    }
+                    require!(false,
+                             "{} intrinsic monomorphised with invalid type",
+                             name)
+                })*
+        }
+    }
+    arith! {
+        simd_add: TyUint, TyInt => Add, TyFloat => FAdd;
+        simd_sub: TyUint, TyInt => Sub, TyFloat => FSub;
+        simd_mul: TyUint, TyInt => Mul, TyFloat => FMul;
+        simd_div: TyFloat => FDiv;
+        simd_shl: TyUint, TyInt => Shl;
+        simd_shr: TyUint => LShr, TyInt => AShr;
+        simd_and: TyUint, TyInt => And;
+        simd_or: TyUint, TyInt => Or;
+        simd_xor: TyUint, TyInt => Xor;
+    }
     bcx.sess().span_bug(call_info.span, "unknown SIMD intrinsic");
 }
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 742bd57a130..2f19d4d9ec2 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -5344,6 +5344,11 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &ast::ForeignItem) {
             "simd_eq" | "simd_ne" | "simd_lt" | "simd_le" | "simd_gt" | "simd_ge" => {
                 (2, vec![param(ccx, 0), param(ccx, 0)], param(ccx, 1))
             }
+            "simd_add" | "simd_sub" | "simd_mul" |
+            "simd_div" | "simd_shl" | "simd_shr" |
+            "simd_and" | "simd_or" | "simd_xor" => {
+                (1, vec![param(ccx, 0), param(ccx, 0)], param(ccx, 0))
+            }
             "simd_insert" => (2, vec![param(ccx, 0), tcx.types.u32, param(ccx, 1)], param(ccx, 0)),
             "simd_extract" => (2, vec![param(ccx, 0), tcx.types.u32], param(ccx, 1)),
             "simd_cast" => (2, vec![param(ccx, 0)], param(ccx, 1)),