use crate::prelude::*;
-macro_rules! binop_match {
- (@single $fx:expr, $bug_fmt:expr, $var:expr, $signed:expr, $lhs:expr, $rhs:expr, $ret_ty:expr, bug) => {
- bug!("binop {} on {} lhs: {:?} rhs: {:?}", stringify!($var), $bug_fmt, $lhs, $rhs)
- };
- (@single $fx:expr, $bug_fmt:expr, $var:expr, $signed:expr, $lhs:expr, $rhs:expr, $ret_ty:expr, icmp($cc:ident)) => {{
- assert_eq!($fx.tcx.types.bool, $ret_ty);
- let ret_layout = $fx.layout_of($ret_ty);
-
- let b = $fx.bcx.ins().icmp(IntCC::$cc, $lhs, $rhs);
- CValue::by_val($fx.bcx.ins().bint(types::I8, b), ret_layout)
- }};
- (@single $fx:expr, $bug_fmt:expr, $var:expr, $signed:expr, $lhs:expr, $rhs:expr, $ret_ty:expr, fcmp($cc:ident)) => {{
- assert_eq!($fx.tcx.types.bool, $ret_ty);
- let ret_layout = $fx.layout_of($ret_ty);
- let b = $fx.bcx.ins().fcmp(FloatCC::$cc, $lhs, $rhs);
- CValue::by_val($fx.bcx.ins().bint(types::I8, b), ret_layout)
- }};
- (@single $fx:expr, $bug_fmt:expr, $var:expr, $signed:expr, $lhs:expr, $rhs:expr, $ret_ty:expr, custom(|| $body:expr)) => {{
- $body
- }};
- (@single $fx:expr, $bug_fmt:expr, $var:expr, $signed:expr, $lhs:expr, $rhs:expr, $ret_ty:expr, $name:ident) => {{
- let ret_layout = $fx.layout_of($ret_ty);
- CValue::by_val($fx.bcx.ins().$name($lhs, $rhs), ret_layout)
- }};
- (
- $fx:expr, $bin_op:expr, $signed:expr, $lhs:expr, $rhs:expr, $ret_ty:expr, $bug_fmt:expr;
- $(
- $var:ident ($sign:pat) $name:tt $( ( $($next:tt)* ) )? ;
- )*
- ) => {{
- let lhs = $lhs.load_scalar($fx);
- let rhs = $rhs.load_scalar($fx);
- match ($bin_op, $signed) {
- $(
- (BinOp::$var, $sign) => binop_match!(@single $fx, $bug_fmt, $var, $signed, lhs, rhs, $ret_ty, $name $( ( $($next)* ) )?),
- )*
+pub(crate) fn bin_op_to_intcc(bin_op: BinOp, signed: bool) -> Option<IntCC> {
+ use BinOp::*;
+ use IntCC::*;
+ Some(match bin_op {
+ Eq => Equal,
+ Lt => {
+ if signed {
+ SignedLessThan
+ } else {
+ UnsignedLessThan
+ }
+ }
+ Le => {
+ if signed {
+ SignedLessThanOrEqual
+ } else {
+ UnsignedLessThanOrEqual
+ }
+ }
+ Ne => NotEqual,
+ Ge => {
+ if signed {
+ SignedGreaterThanOrEqual
+ } else {
+ UnsignedGreaterThanOrEqual
+ }
+ }
+ Gt => {
+ if signed {
+ SignedGreaterThan
+ } else {
+ UnsignedGreaterThan
+ }
+ }
+ _ => return None,
+ })
+}
+
+fn codegen_compare_bin_op<'tcx>(
+ fx: &mut FunctionCx<'_, 'tcx, impl Backend>,
+ bin_op: BinOp,
+ signed: bool,
+ lhs: Value,
+ rhs: Value,
+) -> CValue<'tcx> {
+ let intcc = crate::num::bin_op_to_intcc(bin_op, signed).unwrap();
+ let val = fx.bcx.ins().icmp(intcc, lhs, rhs);
+ let val = fx.bcx.ins().bint(types::I8, val);
+ CValue::by_val(val, fx.layout_of(fx.tcx.types.bool))
+}
+
+pub(crate) fn codegen_binop<'tcx>(
+ fx: &mut FunctionCx<'_, 'tcx, impl Backend>,
+ bin_op: BinOp,
+ in_lhs: CValue<'tcx>,
+ in_rhs: CValue<'tcx>,
+) -> CValue<'tcx> {
+ match bin_op {
+ BinOp::Eq | BinOp::Lt | BinOp::Le | BinOp::Ne | BinOp::Ge | BinOp::Gt => {
+ match in_lhs.layout().ty.kind {
+ ty::Bool | ty::Uint(_) | ty::Int(_) | ty::Char => {
+ let signed = type_sign(in_lhs.layout().ty);
+ let lhs = in_lhs.load_scalar(fx);
+ let rhs = in_rhs.load_scalar(fx);
+
+ let (lhs, rhs) = if (bin_op == BinOp::Eq || bin_op == BinOp::Ne)
+ && (in_lhs.layout().ty.kind == fx.tcx.types.i8.kind
+ || in_lhs.layout().ty.kind == fx.tcx.types.i16.kind)
+ {
+ // FIXME(CraneStation/cranelift#896) icmp_imm.i8/i16 with eq/ne for signed ints is implemented wrong.
+ (
+ fx.bcx.ins().sextend(types::I32, lhs),
+ fx.bcx.ins().sextend(types::I32, rhs),
+ )
+ } else {
+ (lhs, rhs)
+ };
+
+ return codegen_compare_bin_op(fx, bin_op, signed, lhs, rhs);
+ }
+ _ => {}
+ }
}
- }}
+ _ => {}
+ }
+
+ match in_lhs.layout().ty.kind {
+ ty::Bool => crate::num::trans_bool_binop(fx, bin_op, in_lhs, in_rhs),
+ ty::Uint(_) | ty::Int(_) => crate::num::trans_int_binop(fx, bin_op, in_lhs, in_rhs),
+ ty::Float(_) => crate::num::trans_float_binop(fx, bin_op, in_lhs, in_rhs),
+ ty::RawPtr(..) | ty::FnPtr(..) => crate::num::trans_ptr_binop(fx, bin_op, in_lhs, in_rhs),
+ _ => unreachable!(
+ "{:?}({:?}, {:?})",
+ bin_op,
+ in_lhs.layout().ty,
+ in_rhs.layout().ty
+ ),
+ }
}
-pub fn trans_bool_binop<'a, 'tcx: 'a>(
- fx: &mut FunctionCx<'a, 'tcx, impl Backend>,
+pub(crate) fn trans_bool_binop<'tcx>(
+ fx: &mut FunctionCx<'_, 'tcx, impl Backend>,
bin_op: BinOp,
- lhs: CValue<'tcx>,
- rhs: CValue<'tcx>,
+ in_lhs: CValue<'tcx>,
+ in_rhs: CValue<'tcx>,
) -> CValue<'tcx> {
- let res = binop_match! {
- fx, bin_op, false, lhs, rhs, fx.tcx.types.bool, "bool";
- Add (_) bug;
- Sub (_) bug;
- Mul (_) bug;
- Div (_) bug;
- Rem (_) bug;
- BitXor (_) bxor;
- BitAnd (_) band;
- BitOr (_) bor;
- Shl (_) bug;
- Shr (_) bug;
-
- Eq (_) icmp(Equal);
- Lt (_) icmp(UnsignedLessThan);
- Le (_) icmp(UnsignedLessThanOrEqual);
- Ne (_) icmp(NotEqual);
- Ge (_) icmp(UnsignedGreaterThanOrEqual);
- Gt (_) icmp(UnsignedGreaterThan);
-
- Offset (_) bug;
+ let lhs = in_lhs.load_scalar(fx);
+ let rhs = in_rhs.load_scalar(fx);
+
+ let b = fx.bcx.ins();
+ let res = match bin_op {
+ BinOp::BitXor => b.bxor(lhs, rhs),
+ BinOp::BitAnd => b.band(lhs, rhs),
+ BinOp::BitOr => b.bor(lhs, rhs),
+ // Compare binops handles by `codegen_binop`.
+ _ => unreachable!("{:?}({:?}, {:?})", bin_op, in_lhs, in_rhs),
};
- res
+ CValue::by_val(res, fx.layout_of(fx.tcx.types.bool))
}
-pub fn trans_int_binop<'a, 'tcx: 'a>(
- fx: &mut FunctionCx<'a, 'tcx, impl Backend>,
+pub(crate) fn trans_int_binop<'tcx>(
+ fx: &mut FunctionCx<'_, 'tcx, impl Backend>,
bin_op: BinOp,
- lhs: CValue<'tcx>,
- rhs: CValue<'tcx>,
- out_ty: Ty<'tcx>,
- signed: bool,
+ in_lhs: CValue<'tcx>,
+ in_rhs: CValue<'tcx>,
) -> CValue<'tcx> {
if bin_op != BinOp::Shl && bin_op != BinOp::Shr {
assert_eq!(
- lhs.layout().ty,
- rhs.layout().ty,
+ in_lhs.layout().ty,
+ in_rhs.layout().ty,
"int binop requires lhs and rhs of same type"
);
}
- match out_ty.sty {
- ty::Bool | ty::Uint(_) | ty::Int(_) => {}
- _ => unreachable!("Out ty {:?} is not an integer or bool", out_ty),
- }
-
- if let Some(res) = crate::codegen_i128::maybe_codegen(fx, bin_op, false, signed, lhs, rhs, out_ty) {
+ if let Some(res) = crate::codegen_i128::maybe_codegen(fx, bin_op, false, in_lhs, in_rhs) {
return res;
}
- let (lhs, rhs) = if
- (bin_op == BinOp::Eq || bin_op == BinOp::Ne)
- && (lhs.layout().ty.sty == fx.tcx.types.i8.sty || lhs.layout().ty.sty == fx.tcx.types.i16.sty)
- {
- // FIXME(CraneStation/cranelift#896) icmp_imm.i8/i16 with eq/ne for signed ints is implemented wrong.
- let lhs = lhs.load_scalar(fx);
- let rhs = rhs.load_scalar(fx);
- (
- CValue::by_val(fx.bcx.ins().sextend(types::I32, lhs), fx.layout_of(fx.tcx.types.i32)),
- CValue::by_val(fx.bcx.ins().sextend(types::I32, rhs), fx.layout_of(fx.tcx.types.i32)),
- )
- } else {
- (lhs, rhs)
+ let signed = type_sign(in_lhs.layout().ty);
+
+ let lhs = in_lhs.load_scalar(fx);
+ let rhs = in_rhs.load_scalar(fx);
+
+ let b = fx.bcx.ins();
+ let val = match bin_op {
+ BinOp::Add => b.iadd(lhs, rhs),
+ BinOp::Sub => b.isub(lhs, rhs),
+ BinOp::Mul => b.imul(lhs, rhs),
+ BinOp::Div => {
+ if signed {
+ b.sdiv(lhs, rhs)
+ } else {
+ b.udiv(lhs, rhs)
+ }
+ }
+ BinOp::Rem => {
+ if signed {
+ b.srem(lhs, rhs)
+ } else {
+ b.urem(lhs, rhs)
+ }
+ }
+ BinOp::BitXor => b.bxor(lhs, rhs),
+ BinOp::BitAnd => b.band(lhs, rhs),
+ BinOp::BitOr => b.bor(lhs, rhs),
+ BinOp::Shl => {
+ let lhs_ty = fx.bcx.func.dfg.value_type(lhs);
+ let rhs = clif_intcast(fx, rhs, lhs_ty, false);
+ fx.bcx.ins().ishl(lhs, rhs)
+ }
+ BinOp::Shr => {
+ let lhs_ty = fx.bcx.func.dfg.value_type(lhs);
+ let rhs = clif_intcast(fx, rhs, lhs_ty, false);
+ if signed {
+ fx.bcx.ins().sshr(lhs, rhs)
+ } else {
+ fx.bcx.ins().ushr(lhs, rhs)
+ }
+ }
+ // Compare binops handles by `codegen_binop`.
+ _ => unreachable!(
+ "{:?}({:?}, {:?})",
+ bin_op,
+ in_lhs.layout().ty,
+ in_rhs.layout().ty
+ ),
};
- binop_match! {
- fx, bin_op, signed, lhs, rhs, out_ty, "int/uint";
- Add (_) iadd;
- Sub (_) isub;
- Mul (_) imul;
- Div (false) udiv;
- Div (true) sdiv;
- Rem (false) urem;
- Rem (true) srem;
- BitXor (_) bxor;
- BitAnd (_) band;
- BitOr (_) bor;
- Shl (_) ishl;
- Shr (false) ushr;
- Shr (true) sshr;
-
- Eq (_) icmp(Equal);
- Lt (false) icmp(UnsignedLessThan);
- Lt (true) icmp(SignedLessThan);
- Le (false) icmp(UnsignedLessThanOrEqual);
- Le (true) icmp(SignedLessThanOrEqual);
- Ne (_) icmp(NotEqual);
- Ge (false) icmp(UnsignedGreaterThanOrEqual);
- Ge (true) icmp(SignedGreaterThanOrEqual);
- Gt (false) icmp(UnsignedGreaterThan);
- Gt (true) icmp(SignedGreaterThan);
-
- Offset (_) bug;
- }
+ CValue::by_val(val, in_lhs.layout())
}
-pub fn trans_checked_int_binop<'a, 'tcx: 'a>(
- fx: &mut FunctionCx<'a, 'tcx, impl Backend>,
+pub(crate) fn trans_checked_int_binop<'tcx>(
+ fx: &mut FunctionCx<'_, 'tcx, impl Backend>,
bin_op: BinOp,
in_lhs: CValue<'tcx>,
in_rhs: CValue<'tcx>,
- out_ty: Ty<'tcx>,
- signed: bool,
) -> CValue<'tcx> {
if bin_op != BinOp::Shl && bin_op != BinOp::Shr {
assert_eq!(
let lhs = in_lhs.load_scalar(fx);
let rhs = in_rhs.load_scalar(fx);
- if let Some(res) = crate::codegen_i128::maybe_codegen(fx, bin_op, true, signed, in_lhs, in_rhs, out_ty) {
+ if let Some(res) = crate::codegen_i128::maybe_codegen(fx, bin_op, true, in_lhs, in_rhs) {
return res;
}
+ let signed = type_sign(in_lhs.layout().ty);
+
let (res, has_overflow) = match bin_op {
BinOp::Add => {
/*let (val, c_out) = fx.bcx.ins().iadd_cout(lhs, rhs);
}
BinOp::Shl => {
let val = fx.bcx.ins().ishl(lhs, rhs);
- // TODO: check for overflow
- let has_overflow = fx.bcx.ins().bconst(types::B1, false);
+ let ty = fx.bcx.func.dfg.value_type(val);
+ let max_shift = i64::from(ty.bits()) - 1;
+ let has_overflow =
+ fx.bcx.ins().icmp_imm(IntCC::UnsignedGreaterThan, rhs, max_shift);
(val, has_overflow)
}
BinOp::Shr => {
} else {
fx.bcx.ins().sshr(lhs, rhs)
};
- // TODO: check for overflow
- let has_overflow = fx.bcx.ins().bconst(types::B1, false);
+ let ty = fx.bcx.func.dfg.value_type(val);
+ let max_shift = i64::from(ty.bits()) - 1;
+ let has_overflow =
+ fx.bcx.ins().icmp_imm(IntCC::UnsignedGreaterThan, rhs, max_shift);
(val, has_overflow)
}
_ => bug!(
};
let has_overflow = fx.bcx.ins().bint(types::I8, has_overflow);
- let out_place = CPlace::new_stack_slot(fx, out_ty);
+
+ // FIXME directly write to result place instead
+ let out_place = CPlace::new_stack_slot(
+ fx,
+ fx.layout_of(fx.tcx.mk_tup([in_lhs.layout().ty, fx.tcx.types.bool].iter())),
+ );
let out_layout = out_place.layout();
out_place.write_cvalue(fx, CValue::by_val_pair(res, has_overflow, out_layout));
out_place.to_cvalue(fx)
}
-pub fn trans_float_binop<'a, 'tcx: 'a>(
- fx: &mut FunctionCx<'a, 'tcx, impl Backend>,
+pub(crate) fn trans_float_binop<'tcx>(
+ fx: &mut FunctionCx<'_, 'tcx, impl Backend>,
bin_op: BinOp,
- lhs: CValue<'tcx>,
- rhs: CValue<'tcx>,
- ty: Ty<'tcx>,
+ in_lhs: CValue<'tcx>,
+ in_rhs: CValue<'tcx>,
) -> CValue<'tcx> {
- let res = binop_match! {
- fx, bin_op, false, lhs, rhs, ty, "float";
- Add (_) fadd;
- Sub (_) fsub;
- Mul (_) fmul;
- Div (_) fdiv;
- Rem (_) custom(|| {
- assert_eq!(lhs.layout().ty, ty);
- assert_eq!(rhs.layout().ty, ty);
- match ty.sty {
- ty::Float(FloatTy::F32) => fx.easy_call("fmodf", &[lhs, rhs], ty),
- ty::Float(FloatTy::F64) => fx.easy_call("fmod", &[lhs, rhs], ty),
- _ => bug!(),
- }
- });
- BitXor (_) bxor;
- BitAnd (_) band;
- BitOr (_) bor;
- Shl (_) bug;
- Shr (_) bug;
-
- Eq (_) fcmp(Equal);
- Lt (_) fcmp(LessThan);
- Le (_) fcmp(LessThanOrEqual);
- Ne (_) fcmp(NotEqual);
- Ge (_) fcmp(GreaterThanOrEqual);
- Gt (_) fcmp(GreaterThan);
-
- Offset (_) bug;
- };
+ assert_eq!(in_lhs.layout().ty, in_rhs.layout().ty);
- res
-}
+ let lhs = in_lhs.load_scalar(fx);
+ let rhs = in_rhs.load_scalar(fx);
-pub fn trans_char_binop<'a, 'tcx: 'a>(
- fx: &mut FunctionCx<'a, 'tcx, impl Backend>,
- bin_op: BinOp,
- lhs: CValue<'tcx>,
- rhs: CValue<'tcx>,
- ty: Ty<'tcx>,
-) -> CValue<'tcx> {
- let res = binop_match! {
- fx, bin_op, false, lhs, rhs, ty, "char";
- Add (_) bug;
- Sub (_) bug;
- Mul (_) bug;
- Div (_) bug;
- Rem (_) bug;
- BitXor (_) bug;
- BitAnd (_) bug;
- BitOr (_) bug;
- Shl (_) bug;
- Shr (_) bug;
-
- Eq (_) icmp(Equal);
- Lt (_) icmp(UnsignedLessThan);
- Le (_) icmp(UnsignedLessThanOrEqual);
- Ne (_) icmp(NotEqual);
- Ge (_) icmp(UnsignedGreaterThanOrEqual);
- Gt (_) icmp(UnsignedGreaterThan);
-
- Offset (_) bug;
+ let b = fx.bcx.ins();
+ let res = match bin_op {
+ BinOp::Add => b.fadd(lhs, rhs),
+ BinOp::Sub => b.fsub(lhs, rhs),
+ BinOp::Mul => b.fmul(lhs, rhs),
+ BinOp::Div => b.fdiv(lhs, rhs),
+ BinOp::Rem => {
+ let name = match in_lhs.layout().ty.kind {
+ ty::Float(FloatTy::F32) => "fmodf",
+ ty::Float(FloatTy::F64) => "fmod",
+ _ => bug!(),
+ };
+ return fx.easy_call(name, &[in_lhs, in_rhs], in_lhs.layout().ty);
+ }
+ BinOp::Eq | BinOp::Lt | BinOp::Le | BinOp::Ne | BinOp::Ge | BinOp::Gt => {
+ let fltcc = match bin_op {
+ BinOp::Eq => FloatCC::Equal,
+ BinOp::Lt => FloatCC::LessThan,
+ BinOp::Le => FloatCC::LessThanOrEqual,
+ BinOp::Ne => FloatCC::NotEqual,
+ BinOp::Ge => FloatCC::GreaterThanOrEqual,
+ BinOp::Gt => FloatCC::GreaterThan,
+ _ => unreachable!(),
+ };
+ let val = fx.bcx.ins().fcmp(fltcc, lhs, rhs);
+ let val = fx.bcx.ins().bint(types::I8, val);
+ return CValue::by_val(val, fx.layout_of(fx.tcx.types.bool));
+ }
+ _ => unreachable!("{:?}({:?}, {:?})", bin_op, in_lhs, in_rhs),
};
- res
+ CValue::by_val(res, in_lhs.layout())
}
-pub fn trans_ptr_binop<'a, 'tcx: 'a>(
- fx: &mut FunctionCx<'a, 'tcx, impl Backend>,
+pub(crate) fn trans_ptr_binop<'tcx>(
+ fx: &mut FunctionCx<'_, 'tcx, impl Backend>,
bin_op: BinOp,
- lhs: CValue<'tcx>,
- rhs: CValue<'tcx>,
- ret_ty: Ty<'tcx>,
+ in_lhs: CValue<'tcx>,
+ in_rhs: CValue<'tcx>,
) -> CValue<'tcx> {
- let not_fat = match lhs.layout().ty.sty {
- ty::RawPtr(TypeAndMut { ty, mutbl: _ }) => {
- ty.is_sized(fx.tcx.at(DUMMY_SP), ParamEnv::reveal_all())
- }
- ty::FnPtr(..) => true,
- _ => bug!("trans_ptr_binop on non ptr"),
- };
- if not_fat {
- if let BinOp::Offset = bin_op {
- let (base, offset) = (lhs, rhs.load_scalar(fx));
- let pointee_ty = base.layout().ty.builtin_deref(true).unwrap().ty;
- let pointee_size = fx.layout_of(pointee_ty).size.bytes();
- let ptr_diff = fx.bcx.ins().imul_imm(offset, pointee_size as i64);
- let base_val = base.load_scalar(fx);
- let res = fx.bcx.ins().iadd(base_val, ptr_diff);
- return CValue::by_val(res, base.layout());
- }
+ let is_thin_ptr = in_lhs.layout().ty.builtin_deref(true).map(|TypeAndMut { ty, mutbl: _}| {
+ !has_ptr_meta(fx.tcx, ty)
+ }).unwrap_or(true);
- binop_match! {
- fx, bin_op, false, lhs, rhs, ret_ty, "ptr";
- Add (_) bug;
- Sub (_) bug;
- Mul (_) bug;
- Div (_) bug;
- Rem (_) bug;
- BitXor (_) bug;
- BitAnd (_) bug;
- BitOr (_) bug;
- Shl (_) bug;
- Shr (_) bug;
-
- Eq (_) icmp(Equal);
- Lt (_) icmp(UnsignedLessThan);
- Le (_) icmp(UnsignedLessThanOrEqual);
- Ne (_) icmp(NotEqual);
- Ge (_) icmp(UnsignedGreaterThanOrEqual);
- Gt (_) icmp(UnsignedGreaterThan);
-
- Offset (_) bug; // Handled above
- }
+ if is_thin_ptr {
+ match bin_op {
+ BinOp::Eq | BinOp::Lt | BinOp::Le | BinOp::Ne | BinOp::Ge | BinOp::Gt => {
+ let lhs = in_lhs.load_scalar(fx);
+ let rhs = in_rhs.load_scalar(fx);
+
+ return codegen_compare_bin_op(fx, bin_op, false, lhs, rhs);
+ }
+ BinOp::Offset => {
+ let pointee_ty = in_lhs.layout().ty.builtin_deref(true).unwrap().ty;
+ let (base, offset) = (in_lhs, in_rhs.load_scalar(fx));
+ let pointee_size = fx.layout_of(pointee_ty).size.bytes();
+ let ptr_diff = fx.bcx.ins().imul_imm(offset, pointee_size as i64);
+ let base_val = base.load_scalar(fx);
+ let res = fx.bcx.ins().iadd(base_val, ptr_diff);
+ return CValue::by_val(res, base.layout());
+ }
+ _ => unreachable!("{:?}({:?}, {:?})", bin_op, in_lhs, in_rhs),
+ };
} else {
- let (lhs_ptr, lhs_extra) = lhs.load_scalar_pair(fx);
- let (rhs_ptr, rhs_extra) = rhs.load_scalar_pair(fx);
+ let (lhs_ptr, lhs_extra) = in_lhs.load_scalar_pair(fx);
+ let (rhs_ptr, rhs_extra) = in_rhs.load_scalar_pair(fx);
let res = match bin_op {
BinOp::Eq => {
BinOp::Lt | BinOp::Le | BinOp::Ge | BinOp::Gt => {
let ptr_eq = fx.bcx.ins().icmp(IntCC::Equal, lhs_ptr, rhs_ptr);
- let ptr_cmp = fx.bcx.ins().icmp(match bin_op {
- BinOp::Lt => IntCC::UnsignedLessThan,
- BinOp::Le => IntCC::UnsignedLessThanOrEqual,
- BinOp::Ge => IntCC::UnsignedGreaterThanOrEqual,
- BinOp::Gt => IntCC::UnsignedGreaterThan,
- _ => unreachable!(),
- }, lhs_ptr, rhs_ptr);
-
- let extra_cmp = fx.bcx.ins().icmp(match bin_op {
- BinOp::Lt => IntCC::UnsignedLessThan,
- BinOp::Le => IntCC::UnsignedLessThanOrEqual,
- BinOp::Ge => IntCC::UnsignedGreaterThanOrEqual,
- BinOp::Gt => IntCC::UnsignedGreaterThan,
- _ => unreachable!(),
- }, lhs_extra, rhs_extra);
+ let ptr_cmp =
+ fx.bcx
+ .ins()
+ .icmp(bin_op_to_intcc(bin_op, false).unwrap(), lhs_ptr, rhs_ptr);
+ let extra_cmp = fx.bcx.ins().icmp(
+ bin_op_to_intcc(bin_op, false).unwrap(),
+ lhs_extra,
+ rhs_extra,
+ );
fx.bcx.ins().select(ptr_eq, extra_cmp, ptr_cmp)
}
_ => panic!("bin_op {:?} on ptr", bin_op),
};
- assert_eq!(fx.tcx.types.bool, ret_ty);
- let ret_layout = fx.layout_of(ret_ty);
- CValue::by_val(fx.bcx.ins().bint(types::I8, res), ret_layout)
+ CValue::by_val(
+ fx.bcx.ins().bint(types::I8, res),
+ fx.layout_of(fx.tcx.types.bool),
+ )
}
}