]> git.lizzy.rs Git - rust.git/commitdiff
Add simd_cast intrinsic.
authorHuon Wilson <dbau.pp+github@gmail.com>
Wed, 29 Jul 2015 23:40:22 +0000 (16:40 -0700)
committerHuon Wilson <dbau.pp+github@gmail.com>
Mon, 17 Aug 2015 21:41:38 +0000 (14:41 -0700)
src/librustc_trans/trans/intrinsic.rs
src/librustc_trans/trans/type_of.rs
src/librustc_typeck/check/mod.rs

index 7c8deb9a791ebfb73c630727500da02a4574c81f..88a80076640c37fa3357efc380b415b35df7f32e 100644 (file)
@@ -1445,5 +1445,56 @@ macro_rules! require {
                  "SIMD insert intrinsic monomorphised with returned type not SIMD element type");
         return ExtractElement(bcx, llargs[0], llargs[1])
     }
+
+    if name == "simd_cast" {
+        require!(arg_tys[0].simd_size(tcx) == ret_ty.simd_size(tcx),
+                 "SIMD cast intrinsic monomorphised with input and \
+                  return types of different lengths");
+        // casting cares about nominal type, not just structural type
+        let in_ = arg_tys[0].simd_type(tcx);
+        let out = ret_ty.simd_type(tcx);
+
+        if in_ == out { return llargs[0]; }
+
+        match (&in_.sty, &out.sty) {
+            (&ty::TyInt(lhs), &ty::TyUint(rhs)) => {
+                match (lhs, rhs) {
+                    (ast::TyI8, ast::TyU8) |
+                    (ast::TyI16, ast::TyU16) |
+                    (ast::TyI32, ast::TyU32) |
+                    (ast::TyI64, ast::TyU64) => return llargs[0],
+                    _ => {},
+                }
+            }
+            (&ty::TyUint(lhs), &ty::TyInt(rhs)) => {
+                match (lhs, rhs) {
+                    (ast::TyU8, ast::TyI8) |
+                    (ast::TyU16, ast::TyI16) |
+                    (ast::TyU32, ast::TyI32) |
+                    (ast::TyU64, ast::TyI64) => return llargs[0],
+                    _ => {},
+                }
+            }
+            (&ty::TyInt(ast::TyI32), &ty::TyFloat(ast::TyF32)) |
+            (&ty::TyInt(ast::TyI64), &ty::TyFloat(ast::TyF64)) => {
+                return SIToFP(bcx, llargs[0], llret_ty)
+            }
+            (&ty::TyUint(ast::TyU32), &ty::TyFloat(ast::TyF32)) |
+            (&ty::TyUint(ast::TyU64), &ty::TyFloat(ast::TyF64)) => {
+                return UIToFP(bcx, llargs[0], llret_ty)
+            }
+
+            (&ty::TyFloat(ast::TyF32), &ty::TyInt(ast::TyI32)) |
+            (&ty::TyFloat(ast::TyF64), &ty::TyInt(ast::TyI64)) => {
+                return FPToSI(bcx, llargs[0], llret_ty)
+            }
+            (&ty::TyFloat(ast::TyF32), &ty::TyUint(ast::TyU32)) |
+            (&ty::TyFloat(ast::TyF64), &ty::TyUint(ast::TyU64)) => {
+                return FPToUI(bcx, llargs[0], llret_ty)
+            }
+            _ => {}
+        }
+        require!(false, "SIMD cast intrinsic monomorphised with incompatible cast");
+    }
     bcx.sess().span_bug(call_info.span, "unknown SIMD intrinsic");
 }
index 5991d61a1e4eed0475f83c3e66b4bb4b27bfca70..3edd4530ceb695836055edc5d09731915642062b 100644 (file)
@@ -182,6 +182,7 @@ pub fn sizing_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Typ
         None => ()
     }
 
+    debug!("sizing_type_of {:?}", t);
     let llsizingty = match t.sty {
         _ if !type_is_sized(cx.tcx(), t) => {
             Type::struct_(cx, &[Type::i8p(cx), Type::i8p(cx)], false)
@@ -240,6 +241,10 @@ pub fn sizing_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Typ
         ty::TySlice(_) | ty::TyTrait(..) | ty::TyStr => unreachable!()
     };
 
+    debug!("--> mapped t={:?} to llsizingty={}",
+            t,
+            cx.tn().type_to_string(llsizingty));
+
     cx.llsizingtypes().borrow_mut().insert(t, llsizingty);
     llsizingty
 }
@@ -426,8 +431,7 @@ pub fn in_memory_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) ->
       ty::TyError(..) => cx.sess().bug("type_of with TyError"),
     };
 
-    debug!("--> mapped t={:?} {:?} to llty={}",
-            t,
+    debug!("--> mapped t={:?} to llty={}",
             t,
             cx.tn().type_to_string(llty));
 
index 2821538a295361c81c65554a9c8020a078c1fcbe..742bd57a130e96810609b26b901d3fca4e615a61 100644 (file)
@@ -5346,6 +5346,7 @@ fn param<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, n: u32) -> Ty<'tcx> {
             }
             "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)),
             name if name.starts_with("simd_shuffle") => {
                 match name["simd_shuffle".len()..].parse() {
                     Ok(n) => {