- let (lane_count, lane_ty) = a.layout().ty.simd_size_and_type(fx.tcx);
- let lane_ty = fx.clif_type(lane_ty).unwrap();
- assert!(lane_count <= 32);
-
- let mut res = fx.bcx.ins().iconst(types::I32, 0);
-
- for lane in (0..lane_count).rev() {
- let a_lane = a.value_lane(fx, lane).load_scalar(fx);
-
- // cast float to int
- let a_lane = match lane_ty {
- types::F32 => fx.bcx.ins().bitcast(types::I32, a_lane),
- types::F64 => fx.bcx.ins().bitcast(types::I64, a_lane),
- _ => a_lane,
- };
-
- // extract sign bit of an int
- let a_lane_sign = fx.bcx.ins().ushr_imm(a_lane, i64::from(lane_ty.bits() - 1));
-
- // shift sign bit into result
- let a_lane_sign = clif_intcast(fx, a_lane_sign, types::I32, false);
- res = fx.bcx.ins().ishl_imm(res, 1);
- res = fx.bcx.ins().bor(res, a_lane_sign);
- }
-
- let res = CValue::by_val(res, fx.layout_of(fx.tcx.types.i32));
- ret.write_cvalue(fx, res);
- }
- "llvm.x86.sse2.cmp.ps" | "llvm.x86.sse2.cmp.pd" => {
- let (x, y, kind) = match args {
- [x, y, kind] => (x, y, kind),
- _ => bug!("wrong number of args for intrinsic {intrinsic}"),
- };
- let x = codegen_operand(fx, x);
- let y = codegen_operand(fx, y);
- let kind = crate::constant::mir_operand_get_const_val(fx, kind)
- .expect("llvm.x86.sse2.cmp.* kind not const");
-
- let flt_cc = match kind
- .try_to_bits(Size::from_bytes(1))
- .unwrap_or_else(|| panic!("kind not scalar: {:?}", kind))
- {
- 0 => FloatCC::Equal,
- 1 => FloatCC::LessThan,
- 2 => FloatCC::LessThanOrEqual,
- 7 => FloatCC::Ordered,
- 3 => FloatCC::Unordered,
- 4 => FloatCC::NotEqual,
- 5 => FloatCC::UnorderedOrGreaterThanOrEqual,
- 6 => FloatCC::UnorderedOrGreaterThan,
- kind => unreachable!("kind {:?}", kind),
- };
-
- simd_pair_for_each_lane(fx, x, y, ret, &|fx, lane_ty, res_lane_ty, x_lane, y_lane| {
- let res_lane = match lane_ty.kind() {
- ty::Float(_) => fx.bcx.ins().fcmp(flt_cc, x_lane, y_lane),
- _ => unreachable!("{:?}", lane_ty),
- };
- bool_to_zero_or_max_uint(fx, res_lane_ty, res_lane)