2020-09-23 13:13:49 +00:00
|
|
|
//! Emulate LLVM intrinsics
|
|
|
|
|
2019-07-30 12:37:20 +00:00
|
|
|
use crate::intrinsics::*;
|
2019-08-31 17:28:09 +00:00
|
|
|
use crate::prelude::*;
|
2019-07-28 07:54:57 +00:00
|
|
|
|
2020-03-31 11:20:19 +00:00
|
|
|
use rustc_middle::ty::subst::SubstsRef;
|
2019-07-28 07:54:57 +00:00
|
|
|
|
2020-03-27 11:14:45 +00:00
|
|
|
pub(crate) fn codegen_llvm_intrinsic_call<'tcx>(
|
2021-03-05 18:12:59 +00:00
|
|
|
fx: &mut FunctionCx<'_, '_, 'tcx>,
|
2019-07-28 07:54:57 +00:00
|
|
|
intrinsic: &str,
|
2022-12-14 18:30:46 +00:00
|
|
|
substs: SubstsRef<'tcx>,
|
2019-07-28 09:24:33 +00:00
|
|
|
args: &[mir::Operand<'tcx>],
|
2022-04-16 13:27:54 +00:00
|
|
|
ret: CPlace<'tcx>,
|
|
|
|
target: Option<BasicBlock>,
|
2019-07-28 07:54:57 +00:00
|
|
|
) {
|
2022-12-14 18:30:46 +00:00
|
|
|
if intrinsic.starts_with("llvm.aarch64") {
|
|
|
|
return llvm_aarch64::codegen_aarch64_llvm_intrinsic_call(
|
|
|
|
fx, intrinsic, substs, args, ret, target,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
if intrinsic.starts_with("llvm.x86") {
|
|
|
|
return llvm_x86::codegen_x86_llvm_intrinsic_call(fx, intrinsic, substs, args, ret, target);
|
|
|
|
}
|
2022-10-23 14:22:55 +00:00
|
|
|
|
2022-12-14 18:30:46 +00:00
|
|
|
match intrinsic {
|
|
|
|
_ if intrinsic.starts_with("llvm.ctlz.v") => {
|
2022-07-26 16:53:46 +00:00
|
|
|
intrinsic_args!(fx, args => (a); intrinsic);
|
|
|
|
|
2022-12-14 18:30:46 +00:00
|
|
|
simd_for_each_lane(fx, a, ret, &|fx, _lane_ty, _res_lane_ty, lane| {
|
|
|
|
fx.bcx.ins().clz(lane)
|
2019-07-30 12:37:20 +00:00
|
|
|
});
|
2022-07-26 16:53:46 +00:00
|
|
|
}
|
|
|
|
|
2022-12-14 18:30:46 +00:00
|
|
|
_ if intrinsic.starts_with("llvm.ctpop.v") => {
|
|
|
|
intrinsic_args!(fx, args => (a); intrinsic);
|
2022-07-26 16:53:46 +00:00
|
|
|
|
2022-12-14 18:30:46 +00:00
|
|
|
simd_for_each_lane(fx, a, ret, &|fx, _lane_ty, _res_lane_ty, lane| {
|
|
|
|
fx.bcx.ins().popcnt(lane)
|
2020-08-15 18:55:03 +00:00
|
|
|
});
|
2022-07-26 16:53:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
_ => {
|
|
|
|
fx.tcx
|
|
|
|
.sess
|
|
|
|
.warn(&format!("unsupported llvm intrinsic {}; replacing with trap", intrinsic));
|
|
|
|
crate::trap::trap_unimplemented(fx, intrinsic);
|
2022-08-24 16:40:58 +00:00
|
|
|
return;
|
2022-07-26 16:53:46 +00:00
|
|
|
}
|
2019-07-29 10:43:24 +00:00
|
|
|
}
|
2019-07-28 07:54:57 +00:00
|
|
|
|
2022-04-16 13:27:54 +00:00
|
|
|
let dest = target.expect("all llvm intrinsics used by stdlib should return");
|
2022-03-20 15:55:21 +00:00
|
|
|
let ret_block = fx.get_block(dest);
|
|
|
|
fx.bcx.ins().jump(ret_block, &[]);
|
2019-07-28 07:54:57 +00:00
|
|
|
}
|