bitwise_red!(simd_reduce_all: vector_reduce_and, true);
bitwise_red!(simd_reduce_any: vector_reduce_or, true);
+ if name == sym::simd_cast_ptr {
+ require_simd!(ret_ty, "return");
+ let (out_len, out_elem) = ret_ty.simd_size_and_type(bx.tcx());
+ require!(
+ in_len == out_len,
+ "expected return type with length {} (same as input type `{}`), \
+ found `{}` with length {}",
+ in_len,
+ in_ty,
+ ret_ty,
+ out_len
+ );
+
+ match in_elem.kind() {
+ ty::RawPtr(p) => {
+ let (metadata, check_sized) = p.ty.ptr_metadata_ty(bx.tcx, |ty| {
+ bx.tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), ty)
+ });
+ assert!(!check_sized); // we are in codegen, so we shouldn't see these types
+ require!(metadata.is_unit(), "cannot cast fat pointer `{}`", in_elem)
+ }
+ _ => return_error!("expected pointer, got `{}`", in_elem),
+ }
+ match out_elem.kind() {
+ ty::RawPtr(p) => {
+ let (metadata, check_sized) = p.ty.ptr_metadata_ty(bx.tcx, |ty| {
+ bx.tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), ty)
+ });
+ assert!(!check_sized); // we are in codegen, so we shouldn't see these types
+ require!(metadata.is_unit(), "cannot cast to fat pointer `{}`", out_elem)
+ }
+ _ => return_error!("expected pointer, got `{}`", out_elem),
+ }
+
+ if in_elem == out_elem {
+ return Ok(args[0].immediate());
+ } else {
+ return Ok(bx.pointercast(args[0].immediate(), llret_ty));
+ }
+ }
+
+ if name == sym::simd_expose_addr {
+ require_simd!(ret_ty, "return");
+ let (out_len, out_elem) = ret_ty.simd_size_and_type(bx.tcx());
+ require!(
+ in_len == out_len,
+ "expected return type with length {} (same as input type `{}`), \
+ found `{}` with length {}",
+ in_len,
+ in_ty,
+ ret_ty,
+ out_len
+ );
+
+ match in_elem.kind() {
+ ty::RawPtr(_) => {}
+ _ => return_error!("expected pointer, got `{}`", in_elem),
+ }
+ match out_elem.kind() {
+ ty::Uint(ty::UintTy::Usize) => {}
+ _ => return_error!("expected `usize`, got `{}`", out_elem),
+ }
+
+ return Ok(bx.ptrtoint(args[0].immediate(), llret_ty));
+ }
+
+ if name == sym::simd_from_exposed_addr {
+ require_simd!(ret_ty, "return");
+ let (out_len, out_elem) = ret_ty.simd_size_and_type(bx.tcx());
+ require!(
+ in_len == out_len,
+ "expected return type with length {} (same as input type `{}`), \
+ found `{}` with length {}",
+ in_len,
+ in_ty,
+ ret_ty,
+ out_len
+ );
+
+ match in_elem.kind() {
+ ty::Uint(ty::UintTy::Usize) => {}
+ _ => return_error!("expected `usize`, got `{}`", in_elem),
+ }
+ match out_elem.kind() {
+ ty::RawPtr(_) => {}
+ _ => return_error!("expected pointer, got `{}`", out_elem),
+ }
+
+ return Ok(bx.inttoptr(args[0].immediate(), llret_ty));
+ }
+
if name == sym::simd_cast || name == sym::simd_as {
require_simd!(ret_ty, "return");
let (out_len, out_elem) = ret_ty.simd_size_and_type(bx.tcx());