diff options
| author | Ralf Jung <post@ralfj.de> | 2019-06-09 00:41:20 +0200 |
|---|---|---|
| committer | Ralf Jung <post@ralfj.de> | 2019-06-09 00:41:20 +0200 |
| commit | 0012af695eb81f2ab5dfb787383df5415e8cfba1 (patch) | |
| tree | 1684814233ec6655066f41fe1e34163b1a1a04e5 | |
| parent | 0803d75eb6083111504e9bae4fa6baf9104928fe (diff) | |
| download | rust-0012af695eb81f2ab5dfb787383df5415e8cfba1.tar.gz rust-0012af695eb81f2ab5dfb787383df5415e8cfba1.zip | |
trait-ize binary_float_op
| -rw-r--r-- | src/librustc/mir/interpret/value.rs | 14 | ||||
| -rw-r--r-- | src/librustc_mir/interpret/operator.rs | 79 |
2 files changed, 49 insertions, 44 deletions
diff --git a/src/librustc/mir/interpret/value.rs b/src/librustc/mir/interpret/value.rs index 8d4d6176483..35663c4f014 100644 --- a/src/librustc/mir/interpret/value.rs +++ b/src/librustc/mir/interpret/value.rs @@ -132,6 +132,20 @@ impl<Tag> fmt::Display for Scalar<Tag> { } } +impl<Tag> From<Single> for Scalar<Tag> { + #[inline(always)] + fn from(f: Single) -> Self { + Scalar::from_f32(f) + } +} + +impl<Tag> From<Double> for Scalar<Tag> { + #[inline(always)] + fn from(f: Double) -> Self { + Scalar::from_f64(f) + } +} + impl<'tcx> Scalar<()> { #[inline(always)] fn check_data(data: u128, size: u8) { diff --git a/src/librustc_mir/interpret/operator.rs b/src/librustc_mir/interpret/operator.rs index fa4597c825a..dd04a8b3c30 100644 --- a/src/librustc_mir/interpret/operator.rs +++ b/src/librustc_mir/interpret/operator.rs @@ -43,7 +43,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tcx, M> bin_op: mir::BinOp, l: char, r: char, - ) -> InterpResult<'tcx, (Scalar<M::PointerTag>, bool)> { + ) -> (Scalar<M::PointerTag>, bool) { use rustc::mir::BinOp::*; let res = match bin_op { @@ -55,7 +55,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tcx, M> Ge => l >= r, _ => bug!("Invalid operation on char: {:?}", bin_op), }; - return Ok((Scalar::from_bool(res), false)); + return (Scalar::from_bool(res), false); } fn binary_bool_op( @@ -63,7 +63,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tcx, M> bin_op: mir::BinOp, l: bool, r: bool, - ) -> InterpResult<'tcx, (Scalar<M::PointerTag>, bool)> { + ) -> (Scalar<M::PointerTag>, bool) { use rustc::mir::BinOp::*; let res = match bin_op { @@ -78,44 +78,32 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tcx, M> BitXor => l ^ r, _ => bug!("Invalid operation on bool: {:?}", bin_op), }; - return Ok((Scalar::from_bool(res), false)); + return (Scalar::from_bool(res), false); } - fn binary_float_op( + fn binary_float_op<F: Float + Into<Scalar<M::PointerTag>>>( &self, bin_op: mir::BinOp, - fty: FloatTy, - // passing in raw bits - l: u128, - r: u128, - ) -> InterpResult<'tcx, (Scalar<M::PointerTag>, bool)> { + l: F, + r: F, + ) -> (Scalar<M::PointerTag>, bool) { use rustc::mir::BinOp::*; - macro_rules! float_math { - ($ty:path, $from_float:ident) => {{ - let l = <$ty>::from_bits(l); - let r = <$ty>::from_bits(r); - let val = match bin_op { - Eq => Scalar::from_bool(l == r), - Ne => Scalar::from_bool(l != r), - Lt => Scalar::from_bool(l < r), - Le => Scalar::from_bool(l <= r), - Gt => Scalar::from_bool(l > r), - Ge => Scalar::from_bool(l >= r), - Add => Scalar::$from_float((l + r).value), - Sub => Scalar::$from_float((l - r).value), - Mul => Scalar::$from_float((l * r).value), - Div => Scalar::$from_float((l / r).value), - Rem => Scalar::$from_float((l % r).value), - _ => bug!("invalid float op: `{:?}`", bin_op), - }; - return Ok((val, false)); - }}; - } - match fty { - FloatTy::F32 => float_math!(Single, from_f32), - FloatTy::F64 => float_math!(Double, from_f64), - } + let val = match bin_op { + Eq => Scalar::from_bool(l == r), + Ne => Scalar::from_bool(l != r), + Lt => Scalar::from_bool(l < r), + Le => Scalar::from_bool(l <= r), + Gt => Scalar::from_bool(l > r), + Ge => Scalar::from_bool(l >= r), + Add => (l + r).value.into(), + Sub => (l - r).value.into(), + Mul => (l * r).value.into(), + Div => (l / r).value.into(), + Rem => (l % r).value.into(), + _ => bug!("invalid float op: `{:?}`", bin_op), + }; + return (val, false); } fn binary_int_op( @@ -284,21 +272,24 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tcx, M> match left.layout.ty.sty { ty::Char => { assert_eq!(left.layout.ty, right.layout.ty); - let left = left.to_scalar()?.to_char()?; - let right = right.to_scalar()?.to_char()?; - self.binary_char_op(bin_op, left, right) + let left = left.to_scalar()?; + let right = right.to_scalar()?; + Ok(self.binary_char_op(bin_op, left.to_char()?, right.to_char()?)) } ty::Bool => { assert_eq!(left.layout.ty, right.layout.ty); - let left = left.to_scalar()?.to_bool()?; - let right = right.to_scalar()?.to_bool()?; - self.binary_bool_op(bin_op, left, right) + let left = left.to_scalar()?; + let right = right.to_scalar()?; + Ok(self.binary_bool_op(bin_op, left.to_bool()?, right.to_bool()?)) } ty::Float(fty) => { assert_eq!(left.layout.ty, right.layout.ty); - let left = left.to_bits()?; - let right = right.to_bits()?; - self.binary_float_op(bin_op, fty, left, right) + let left = left.to_scalar()?; + let right = right.to_scalar()?; + Ok(match fty { + FloatTy::F32 => self.binary_float_op(bin_op, left.to_f32()?, right.to_f32()?), + FloatTy::F64 => self.binary_float_op(bin_op, left.to_f64()?, right.to_f64()?), + }) } _ => { // Must be integer(-like) types. Don't forget about == on fn pointers. |
