Implement a couple more platform intrinsics

This commit is contained in:
bjorn3 2023-05-12 17:07:31 +00:00
parent ecbb33a71b
commit 899d193c9d
2 changed files with 85 additions and 9 deletions

View File

@ -48,7 +48,6 @@ rm tests/ui/proc-macro/allowed-signatures.rs
rm tests/ui/sse2.rs # cpuid not supported, so sse2 not detected
rm tests/ui/intrinsics/const-eval-select-x86_64.rs # requires x86_64 vendor intrinsics
rm tests/ui/simd/array-type.rs # "Index argument for `simd_insert` is not a constant"
rm tests/ui/simd/intrinsic/float-math-pass.rs # simd_fcos unimplemented
# exotic linkages
rm tests/ui/issues/issue-33992.rs # unsupported linkages

View File

@ -434,8 +434,36 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
});
}
sym::simd_round => {
intrinsic_args!(fx, args => (a); intrinsic);
sym::simd_fpow => {
intrinsic_args!(fx, args => (a, b); intrinsic);
if !a.layout().ty.is_simd() {
report_simd_type_validation_error(fx, intrinsic, span, a.layout().ty);
return;
}
simd_pair_for_each_lane(fx, a, b, ret, &|fx, lane_ty, _ret_lane_ty, a_lane, b_lane| {
match lane_ty.kind() {
ty::Float(FloatTy::F32) => fx.lib_call(
"powf",
vec![AbiParam::new(types::F32), AbiParam::new(types::F32)],
vec![AbiParam::new(types::F32)],
&[a_lane, b_lane],
)[0],
ty::Float(FloatTy::F64) => fx.lib_call(
"pow",
vec![AbiParam::new(types::F64), AbiParam::new(types::F64)],
vec![AbiParam::new(types::F64)],
&[a_lane, b_lane],
)[0],
_ => unreachable!("{:?}", lane_ty),
}
});
}
sym::simd_fpowi => {
intrinsic_args!(fx, args => (a, exp); intrinsic);
let exp = exp.load_scalar(fx);
if !a.layout().ty.is_simd() {
report_simd_type_validation_error(fx, intrinsic, span, a.layout().ty);
@ -448,22 +476,71 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
ret,
&|fx, lane_ty, _ret_lane_ty, lane| match lane_ty.kind() {
ty::Float(FloatTy::F32) => fx.lib_call(
"roundf",
"__powisf2", // compiler-builtins
vec![AbiParam::new(types::F32), AbiParam::new(types::I32)],
vec![AbiParam::new(types::F32)],
vec![AbiParam::new(types::F32)],
&[lane],
&[lane, exp],
)[0],
ty::Float(FloatTy::F64) => fx.lib_call(
"round",
"__powidf2", // compiler-builtins
vec![AbiParam::new(types::F64), AbiParam::new(types::I32)],
vec![AbiParam::new(types::F64)],
vec![AbiParam::new(types::F64)],
&[lane],
&[lane, exp],
)[0],
_ => unreachable!("{:?}", lane_ty),
},
);
}
sym::simd_fsin
| sym::simd_fcos
| sym::simd_fexp
| sym::simd_fexp2
| sym::simd_flog
| sym::simd_flog10
| sym::simd_flog2
| sym::simd_round => {
intrinsic_args!(fx, args => (a); intrinsic);
if !a.layout().ty.is_simd() {
report_simd_type_validation_error(fx, intrinsic, span, a.layout().ty);
return;
}
simd_for_each_lane(fx, a, ret, &|fx, lane_ty, _ret_lane_ty, lane| {
let lane_ty = match lane_ty.kind() {
ty::Float(FloatTy::F32) => types::F32,
ty::Float(FloatTy::F64) => types::F64,
_ => unreachable!("{:?}", lane_ty),
};
let name = match (intrinsic, lane_ty) {
(sym::simd_fsin, types::F32) => "sinf",
(sym::simd_fsin, types::F64) => "sin",
(sym::simd_fcos, types::F32) => "cosf",
(sym::simd_fcos, types::F64) => "cos",
(sym::simd_fexp, types::F32) => "expf",
(sym::simd_fexp, types::F64) => "exp",
(sym::simd_fexp2, types::F32) => "exp2f",
(sym::simd_fexp2, types::F64) => "exp2",
(sym::simd_flog, types::F32) => "logf",
(sym::simd_flog, types::F64) => "log",
(sym::simd_flog10, types::F32) => "log10f",
(sym::simd_flog10, types::F64) => "log10",
(sym::simd_flog2, types::F32) => "log2f",
(sym::simd_flog2, types::F64) => "log2",
(sym::simd_round, types::F32) => "roundf",
(sym::simd_round, types::F64) => "round",
_ => unreachable!("{:?}", intrinsic),
};
fx.lib_call(
name,
vec![AbiParam::new(lane_ty)],
vec![AbiParam::new(lane_ty)],
&[lane],
)[0]
});
}
sym::simd_fabs | sym::simd_fsqrt | sym::simd_ceil | sym::simd_floor | sym::simd_trunc => {
intrinsic_args!(fx, args => (a); intrinsic);