|
1 | 1 | use rustc_middle::mir; |
2 | 2 | use rustc_span::Symbol; |
3 | | -use rustc_target::abi::Size; |
4 | 3 | use rustc_target::spec::abi::Abi; |
5 | 4 |
|
| 5 | +use super::{round_all, round_first}; |
6 | 6 | use crate::*; |
7 | 7 | use shims::foreign_items::EmulateForeignItemResult; |
8 | 8 |
|
@@ -283,86 +283,3 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>: |
283 | 283 | Ok(EmulateForeignItemResult::NeedsJumping) |
284 | 284 | } |
285 | 285 | } |
286 | | - |
287 | | -// Rounds the first element of `right` according to `rounding` |
288 | | -// and copies the remaining elements from `left`. |
289 | | -fn round_first<'tcx, F: rustc_apfloat::Float>( |
290 | | - this: &mut crate::MiriInterpCx<'_, 'tcx>, |
291 | | - left: &OpTy<'tcx, Provenance>, |
292 | | - right: &OpTy<'tcx, Provenance>, |
293 | | - rounding: &OpTy<'tcx, Provenance>, |
294 | | - dest: &PlaceTy<'tcx, Provenance>, |
295 | | -) -> InterpResult<'tcx, ()> { |
296 | | - let (left, left_len) = this.operand_to_simd(left)?; |
297 | | - let (right, right_len) = this.operand_to_simd(right)?; |
298 | | - let (dest, dest_len) = this.place_to_simd(dest)?; |
299 | | - |
300 | | - assert_eq!(dest_len, left_len); |
301 | | - assert_eq!(dest_len, right_len); |
302 | | - |
303 | | - let rounding = rounding_from_imm(this.read_scalar(rounding)?.to_i32()?)?; |
304 | | - |
305 | | - let op0: F = this.read_scalar(&this.project_index(&right, 0)?)?.to_float()?; |
306 | | - let res = op0.round_to_integral(rounding).value; |
307 | | - this.write_scalar( |
308 | | - Scalar::from_uint(res.to_bits(), Size::from_bits(F::BITS)), |
309 | | - &this.project_index(&dest, 0)?, |
310 | | - )?; |
311 | | - |
312 | | - for i in 1..dest_len { |
313 | | - this.copy_op( |
314 | | - &this.project_index(&left, i)?, |
315 | | - &this.project_index(&dest, i)?, |
316 | | - /*allow_transmute*/ false, |
317 | | - )?; |
318 | | - } |
319 | | - |
320 | | - Ok(()) |
321 | | -} |
322 | | - |
323 | | -// Rounds all elements of `op` according to `rounding`. |
324 | | -fn round_all<'tcx, F: rustc_apfloat::Float>( |
325 | | - this: &mut crate::MiriInterpCx<'_, 'tcx>, |
326 | | - op: &OpTy<'tcx, Provenance>, |
327 | | - rounding: &OpTy<'tcx, Provenance>, |
328 | | - dest: &PlaceTy<'tcx, Provenance>, |
329 | | -) -> InterpResult<'tcx, ()> { |
330 | | - let (op, op_len) = this.operand_to_simd(op)?; |
331 | | - let (dest, dest_len) = this.place_to_simd(dest)?; |
332 | | - |
333 | | - assert_eq!(dest_len, op_len); |
334 | | - |
335 | | - let rounding = rounding_from_imm(this.read_scalar(rounding)?.to_i32()?)?; |
336 | | - |
337 | | - for i in 0..dest_len { |
338 | | - let op: F = this.read_scalar(&this.project_index(&op, i)?)?.to_float()?; |
339 | | - let res = op.round_to_integral(rounding).value; |
340 | | - this.write_scalar( |
341 | | - Scalar::from_uint(res.to_bits(), Size::from_bits(F::BITS)), |
342 | | - &this.project_index(&dest, i)?, |
343 | | - )?; |
344 | | - } |
345 | | - |
346 | | - Ok(()) |
347 | | -} |
348 | | - |
349 | | -/// Gets equivalent `rustc_apfloat::Round` from rounding mode immediate of |
350 | | -/// `round.{ss,sd,ps,pd}` intrinsics. |
351 | | -fn rounding_from_imm<'tcx>(rounding: i32) -> InterpResult<'tcx, rustc_apfloat::Round> { |
352 | | - // The fourth bit of `rounding` only affects the SSE status |
353 | | - // register, which cannot be accessed from Miri (or from Rust, |
354 | | - // for that matter), so we can ignore it. |
355 | | - match rounding & !0b1000 { |
356 | | - // When the third bit is 0, the rounding mode is determined by the |
357 | | - // first two bits. |
358 | | - 0b000 => Ok(rustc_apfloat::Round::NearestTiesToEven), |
359 | | - 0b001 => Ok(rustc_apfloat::Round::TowardNegative), |
360 | | - 0b010 => Ok(rustc_apfloat::Round::TowardPositive), |
361 | | - 0b011 => Ok(rustc_apfloat::Round::TowardZero), |
362 | | - // When the third bit is 1, the rounding mode is determined by the |
363 | | - // SSE status register. Since we do not support modifying it from |
364 | | - // Miri (or Rust), we assume it to be at its default mode (round-to-nearest). |
365 | | - 0b100..=0b111 => Ok(rustc_apfloat::Round::NearestTiesToEven), |
366 | | - rounding => throw_unsup_format!("unsupported rounding mode 0x{rounding:02x}"), |
367 | | - } |
368 | | -} |
0 commit comments