diff options
| author | Huon Wilson <dbau.pp+github@gmail.com> | 2015-07-29 16:40:22 -0700 |
|---|---|---|
| committer | Huon Wilson <dbau.pp+github@gmail.com> | 2015-08-17 14:41:38 -0700 |
| commit | ecb3df5a91b71e31e242737d9203b2798bd489de (patch) | |
| tree | 278555f6cd710143bb47bf982a90b3bb37d51299 /src | |
| parent | f1d3b0271ef62e52e65962744701861c32534114 (diff) | |
| download | rust-ecb3df5a91b71e31e242737d9203b2798bd489de.tar.gz rust-ecb3df5a91b71e31e242737d9203b2798bd489de.zip | |
Add simd_cast intrinsic.
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustc_trans/trans/intrinsic.rs | 51 | ||||
| -rw-r--r-- | src/librustc_trans/trans/type_of.rs | 8 | ||||
| -rw-r--r-- | src/librustc_typeck/check/mod.rs | 1 |
3 files changed, 58 insertions, 2 deletions
diff --git a/src/librustc_trans/trans/intrinsic.rs b/src/librustc_trans/trans/intrinsic.rs index 7c8deb9a791..88a80076640 100644 --- a/src/librustc_trans/trans/intrinsic.rs +++ b/src/librustc_trans/trans/intrinsic.rs @@ -1445,5 +1445,56 @@ fn generic_simd_intrinsic<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, "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"); } diff --git a/src/librustc_trans/trans/type_of.rs b/src/librustc_trans/trans/type_of.rs index 5991d61a1e4..3edd4530ceb 100644 --- a/src/librustc_trans/trans/type_of.rs +++ b/src/librustc_trans/trans/type_of.rs @@ -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)); diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 2821538a295..742bd57a130 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -5346,6 +5346,7 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &ast::ForeignItem) { } "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) => { |
