Add simd_cast intrinsic.

This commit is contained in:
Huon Wilson 2015-07-29 16:40:22 -07:00
parent f1d3b0271e
commit ecb3df5a91
3 changed files with 58 additions and 2 deletions

View File

@ -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");
}

View 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));

View File

@ -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) => {