Add simd_cast_ptr, simd_expose_addr, and simd_from_exposed_addr intrinsics

This commit is contained in:
Caleb Zulawski 2022-07-22 01:48:30 +00:00
parent 43347397f7
commit e2866c0a67
4 changed files with 120 additions and 1 deletions

View file

@ -1704,6 +1704,85 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#,
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(_) => {}
_ => return_error!("expected pointer, got `{}`", in_elem),
}
match out_elem.kind() {
ty::RawPtr(_) => {}
_ => 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());