|
1 | 1 | use rustc::mir;
|
2 | 2 | use rustc::ty::Ty;
|
| 3 | +use rustc_const_math::ConstFloat; |
| 4 | +use syntax::ast::FloatTy; |
| 5 | +use std::cmp::Ordering; |
3 | 6 |
|
4 | 7 | use super::{EvalResult, EvalContext, Lvalue, Machine, ValTy};
|
5 | 8 |
|
@@ -103,27 +106,6 @@ macro_rules! int_shift {
|
103 | 106 | })
|
104 | 107 | }
|
105 | 108 |
|
106 |
| -macro_rules! float_arithmetic { |
107 |
| - ($from_bytes:ident, $to_bytes:ident, $float_op:tt, $l:expr, $r:expr) => ({ |
108 |
| - let l = $from_bytes($l); |
109 |
| - let r = $from_bytes($r); |
110 |
| - let bytes = $to_bytes(l $float_op r); |
111 |
| - PrimVal::Bytes(bytes) |
112 |
| - }) |
113 |
| -} |
114 |
| - |
115 |
| -macro_rules! f32_arithmetic { |
116 |
| - ($float_op:tt, $l:expr, $r:expr) => ( |
117 |
| - float_arithmetic!(bytes_to_f32, f32_to_bytes, $float_op, $l, $r) |
118 |
| - ) |
119 |
| -} |
120 |
| - |
121 |
| -macro_rules! f64_arithmetic { |
122 |
| - ($float_op:tt, $l:expr, $r:expr) => ( |
123 |
| - float_arithmetic!(bytes_to_f64, f64_to_bytes, $float_op, $l, $r) |
124 |
| - ) |
125 |
| -} |
126 |
| - |
127 | 109 | impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
|
128 | 110 | /// Returns the result of the specified operation and whether it overflowed.
|
129 | 111 | pub fn binary_op(
|
@@ -173,32 +155,35 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
|
173 | 155 | return err!(Unimplemented(msg));
|
174 | 156 | }
|
175 | 157 |
|
| 158 | + let float_op = |op, l, r, ty| { |
| 159 | + let l = ConstFloat { |
| 160 | + bits: l, |
| 161 | + ty, |
| 162 | + }; |
| 163 | + let r = ConstFloat { |
| 164 | + bits: r, |
| 165 | + ty, |
| 166 | + }; |
| 167 | + match op { |
| 168 | + Eq => PrimVal::from_bool(l.try_cmp(r).unwrap() == Ordering::Equal), |
| 169 | + Ne => PrimVal::from_bool(l.try_cmp(r).unwrap() != Ordering::Equal), |
| 170 | + Lt => PrimVal::from_bool(l.try_cmp(r).unwrap() == Ordering::Less), |
| 171 | + Le => PrimVal::from_bool(l.try_cmp(r).unwrap() != Ordering::Greater), |
| 172 | + Gt => PrimVal::from_bool(l.try_cmp(r).unwrap() == Ordering::Greater), |
| 173 | + Ge => PrimVal::from_bool(l.try_cmp(r).unwrap() != Ordering::Less), |
| 174 | + Add => PrimVal::Bytes((l + r).unwrap().bits), |
| 175 | + Sub => PrimVal::Bytes((l - r).unwrap().bits), |
| 176 | + Mul => PrimVal::Bytes((l * r).unwrap().bits), |
| 177 | + Div => PrimVal::Bytes((l / r).unwrap().bits), |
| 178 | + Rem => PrimVal::Bytes((l % r).unwrap().bits), |
| 179 | + _ => bug!("invalid float op: `{:?}`", op), |
| 180 | + } |
| 181 | + }; |
| 182 | + |
176 | 183 | let val = match (bin_op, left_kind) {
|
177 |
| - (Eq, F32) => PrimVal::from_bool(bytes_to_f32(l) == bytes_to_f32(r)), |
178 |
| - (Ne, F32) => PrimVal::from_bool(bytes_to_f32(l) != bytes_to_f32(r)), |
179 |
| - (Lt, F32) => PrimVal::from_bool(bytes_to_f32(l) < bytes_to_f32(r)), |
180 |
| - (Le, F32) => PrimVal::from_bool(bytes_to_f32(l) <= bytes_to_f32(r)), |
181 |
| - (Gt, F32) => PrimVal::from_bool(bytes_to_f32(l) > bytes_to_f32(r)), |
182 |
| - (Ge, F32) => PrimVal::from_bool(bytes_to_f32(l) >= bytes_to_f32(r)), |
183 |
| - |
184 |
| - (Eq, F64) => PrimVal::from_bool(bytes_to_f64(l) == bytes_to_f64(r)), |
185 |
| - (Ne, F64) => PrimVal::from_bool(bytes_to_f64(l) != bytes_to_f64(r)), |
186 |
| - (Lt, F64) => PrimVal::from_bool(bytes_to_f64(l) < bytes_to_f64(r)), |
187 |
| - (Le, F64) => PrimVal::from_bool(bytes_to_f64(l) <= bytes_to_f64(r)), |
188 |
| - (Gt, F64) => PrimVal::from_bool(bytes_to_f64(l) > bytes_to_f64(r)), |
189 |
| - (Ge, F64) => PrimVal::from_bool(bytes_to_f64(l) >= bytes_to_f64(r)), |
190 |
| - |
191 |
| - (Add, F32) => f32_arithmetic!(+, l, r), |
192 |
| - (Sub, F32) => f32_arithmetic!(-, l, r), |
193 |
| - (Mul, F32) => f32_arithmetic!(*, l, r), |
194 |
| - (Div, F32) => f32_arithmetic!(/, l, r), |
195 |
| - (Rem, F32) => f32_arithmetic!(%, l, r), |
196 |
| - |
197 |
| - (Add, F64) => f64_arithmetic!(+, l, r), |
198 |
| - (Sub, F64) => f64_arithmetic!(-, l, r), |
199 |
| - (Mul, F64) => f64_arithmetic!(*, l, r), |
200 |
| - (Div, F64) => f64_arithmetic!(/, l, r), |
201 |
| - (Rem, F64) => f64_arithmetic!(%, l, r), |
| 184 | + (_, F32) => float_op(bin_op, l, r, FloatTy::F32), |
| 185 | + (_, F64) => float_op(bin_op, l, r, FloatTy::F64), |
| 186 | + |
202 | 187 |
|
203 | 188 | (Eq, _) => PrimVal::from_bool(l == r),
|
204 | 189 | (Ne, _) => PrimVal::from_bool(l != r),
|
|
0 commit comments