diff --git a/src/librustc_trans/trans/intrinsic.rs b/src/librustc_trans/trans/intrinsic.rs index 88a80076640c..a31668ad2123 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 742bd57a130e..2f19d4d9ec23 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)),