Calculate sign in trans{,_checked}_int_binop instead of caller
This commit is contained in:
parent
32cb5b8c8e
commit
db071db95a
19
src/base.rs
19
src/base.rs
@ -261,40 +261,33 @@ fn trans_stmt<'a, 'tcx: 'a>(
|
||||
place.write_place_ref(fx, lval);
|
||||
}
|
||||
Rvalue::BinaryOp(bin_op, lhs, rhs) => {
|
||||
let ty = fx.monomorphize(&lhs.ty(fx.mir, fx.tcx));
|
||||
let lhs = trans_operand(fx, lhs);
|
||||
let rhs = trans_operand(fx, rhs);
|
||||
|
||||
let res = match ty.sty {
|
||||
let res = match lhs.layout().ty.sty {
|
||||
ty::Bool => crate::num::trans_bool_binop(fx, *bin_op, lhs, rhs),
|
||||
ty::Uint(_) => {
|
||||
crate::num::trans_int_binop(fx, *bin_op, lhs, rhs, lval.layout().ty, false)
|
||||
}
|
||||
ty::Int(_) => {
|
||||
crate::num::trans_int_binop(fx, *bin_op, lhs, rhs, lval.layout().ty, true)
|
||||
ty::Uint(_) | ty::Int(_ )=> {
|
||||
crate::num::trans_int_binop(fx, *bin_op, lhs, rhs, lval.layout().ty)
|
||||
}
|
||||
ty::Float(_) => crate::num::trans_float_binop(fx, *bin_op, lhs, rhs, lval.layout().ty),
|
||||
ty::Char => crate::num::trans_char_binop(fx, *bin_op, lhs, rhs, lval.layout().ty),
|
||||
ty::RawPtr(..) | ty::FnPtr(..) => {
|
||||
crate::num::trans_ptr_binop(fx, *bin_op, lhs, rhs, lval.layout().ty)
|
||||
}
|
||||
_ => unimplemented!("binop {:?} for {:?}", bin_op, ty),
|
||||
_ => unimplemented!("{:?}({:?}, {:?})", bin_op, lhs.layout().ty, rhs.layout().ty),
|
||||
};
|
||||
lval.write_cvalue(fx, res);
|
||||
}
|
||||
Rvalue::CheckedBinaryOp(bin_op, lhs, rhs) => {
|
||||
let ty = fx.monomorphize(&lhs.ty(fx.mir, fx.tcx));
|
||||
let lhs = trans_operand(fx, lhs);
|
||||
let rhs = trans_operand(fx, rhs);
|
||||
|
||||
let signed = type_sign(ty);
|
||||
|
||||
let res = if !fx.tcx.sess.overflow_checks() {
|
||||
let val = crate::num::trans_int_binop(fx, *bin_op, lhs, rhs, lhs.layout().ty, signed).load_scalar(fx);
|
||||
let val = crate::num::trans_int_binop(fx, *bin_op, lhs, rhs, lhs.layout().ty).load_scalar(fx);
|
||||
let is_overflow = fx.bcx.ins().iconst(types::I8, 0);
|
||||
CValue::by_val_pair(val, is_overflow, lval.layout())
|
||||
} else {
|
||||
crate::num::trans_checked_int_binop(fx, *bin_op, lhs, rhs, lval.layout().ty, signed)
|
||||
crate::num::trans_checked_int_binop(fx, *bin_op, lhs, rhs, lval.layout().ty)
|
||||
};
|
||||
|
||||
lval.write_cvalue(fx, res);
|
||||
|
@ -6,7 +6,6 @@ pub fn maybe_codegen<'a, 'tcx>(
|
||||
fx: &mut FunctionCx<'a, 'tcx, impl Backend>,
|
||||
bin_op: BinOp,
|
||||
checked: bool,
|
||||
is_signed: bool,
|
||||
lhs: CValue<'tcx>,
|
||||
rhs: CValue<'tcx>,
|
||||
out_ty: Ty<'tcx>,
|
||||
@ -18,6 +17,8 @@ pub fn maybe_codegen<'a, 'tcx>(
|
||||
let lhs_val = lhs.load_scalar(fx);
|
||||
let rhs_val = rhs.load_scalar(fx);
|
||||
|
||||
let is_signed = type_sign(lhs.layout().ty);
|
||||
|
||||
match bin_op {
|
||||
BinOp::BitAnd | BinOp::BitOr | BinOp::BitXor => {
|
||||
assert!(!checked);
|
||||
|
@ -446,28 +446,10 @@ pub fn codegen_intrinsic_call<'a, 'tcx: 'a>(
|
||||
"unchecked_shr" => BinOp::Shr,
|
||||
_ => unimplemented!("intrinsic {}", intrinsic),
|
||||
};
|
||||
let res = match ret.layout().ty.sty {
|
||||
ty::Uint(_) => crate::num::trans_int_binop(
|
||||
fx,
|
||||
bin_op,
|
||||
x,
|
||||
y,
|
||||
ret.layout().ty,
|
||||
false,
|
||||
),
|
||||
ty::Int(_) => crate::num::trans_int_binop(
|
||||
fx,
|
||||
bin_op,
|
||||
x,
|
||||
y,
|
||||
ret.layout().ty,
|
||||
true,
|
||||
),
|
||||
_ => panic!(),
|
||||
};
|
||||
let res = crate::num::trans_int_binop(fx, bin_op, x, y, ret.layout().ty);
|
||||
ret.write_cvalue(fx, res);
|
||||
};
|
||||
_ if intrinsic.ends_with("_with_overflow"), <T> (c x, c y) {
|
||||
_ if intrinsic.ends_with("_with_overflow"), (c x, c y) {
|
||||
assert_eq!(x.layout().ty, y.layout().ty);
|
||||
let bin_op = match intrinsic {
|
||||
"add_with_overflow" => BinOp::Add,
|
||||
@ -482,11 +464,10 @@ pub fn codegen_intrinsic_call<'a, 'tcx: 'a>(
|
||||
x,
|
||||
y,
|
||||
ret.layout().ty,
|
||||
type_sign(T),
|
||||
);
|
||||
ret.write_cvalue(fx, res);
|
||||
};
|
||||
_ if intrinsic.starts_with("overflowing_"), <T> (c x, c y) {
|
||||
_ if intrinsic.starts_with("overflowing_"), (c x, c y) {
|
||||
assert_eq!(x.layout().ty, y.layout().ty);
|
||||
let bin_op = match intrinsic {
|
||||
"overflowing_add" => BinOp::Add,
|
||||
@ -500,7 +481,6 @@ pub fn codegen_intrinsic_call<'a, 'tcx: 'a>(
|
||||
x,
|
||||
y,
|
||||
ret.layout().ty,
|
||||
type_sign(T),
|
||||
);
|
||||
ret.write_cvalue(fx, res);
|
||||
};
|
||||
@ -520,7 +500,6 @@ pub fn codegen_intrinsic_call<'a, 'tcx: 'a>(
|
||||
x,
|
||||
y,
|
||||
fx.tcx.mk_tup([T, fx.tcx.types.bool].into_iter()),
|
||||
signed,
|
||||
);
|
||||
|
||||
let (val, has_overflow) = checked_res.load_scalar_pair(fx);
|
||||
|
10
src/num.rs
10
src/num.rs
@ -78,7 +78,6 @@ pub fn trans_int_binop<'a, 'tcx: 'a>(
|
||||
lhs: CValue<'tcx>,
|
||||
rhs: CValue<'tcx>,
|
||||
out_ty: Ty<'tcx>,
|
||||
signed: bool,
|
||||
) -> CValue<'tcx> {
|
||||
if bin_op != BinOp::Shl && bin_op != BinOp::Shr {
|
||||
assert_eq!(
|
||||
@ -93,10 +92,12 @@ pub fn trans_int_binop<'a, 'tcx: 'a>(
|
||||
_ => 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, lhs, rhs, out_ty) {
|
||||
return res;
|
||||
}
|
||||
|
||||
let signed = type_sign(lhs.layout().ty);
|
||||
|
||||
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)
|
||||
@ -149,7 +150,6 @@ pub fn trans_checked_int_binop<'a, 'tcx: 'a>(
|
||||
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!(
|
||||
@ -162,10 +162,12 @@ pub fn trans_checked_int_binop<'a, 'tcx: 'a>(
|
||||
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, out_ty) {
|
||||
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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user