mirror of
https://git.suyu.dev/suyu/dynarmic.git
synced 2026-01-03 21:24:38 +01:00
mantissa_util: Implement ResidualErrorOnRightShift
Accurately calculate residual error that is shifted out
This commit is contained in:
parent
52ed365158
commit
8087e8df05
4 changed files with 113 additions and 0 deletions
|
|
@ -18,6 +18,7 @@ add_library(dynarmic
|
|||
common/crc32.h
|
||||
common/fp/fpsr.h
|
||||
common/fp/info.h
|
||||
common/fp/mantissa_util.h
|
||||
common/fp/process_exception.cpp
|
||||
common/fp/process_exception.h
|
||||
common/fp/rounding_mode.h
|
||||
|
|
|
|||
48
src/common/fp/mantissa_util.h
Normal file
48
src/common/fp/mantissa_util.h
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
/* This file is part of the dynarmic project.
|
||||
* Copyright (c) 2018 MerryMage
|
||||
* This software may be used and distributed according to the terms of the GNU
|
||||
* General Public License version 2 or any later version.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/bit_util.h"
|
||||
#include "common/common_types.h"
|
||||
|
||||
namespace Dynarmic::FP {
|
||||
|
||||
enum class ResidualError {
|
||||
Zero,
|
||||
LessThanHalf,
|
||||
Half,
|
||||
GreaterThanHalf,
|
||||
};
|
||||
|
||||
template<typename MantissaT>
|
||||
ResidualError ResidualErrorOnRightShift(MantissaT mantissa, int shift_amount) {
|
||||
if (shift_amount <= 0 || mantissa == 0) {
|
||||
return ResidualError::Zero;
|
||||
}
|
||||
|
||||
if (shift_amount > static_cast<int>(Common::BitSize<MantissaT>())) {
|
||||
return Common::MostSignificantBit(mantissa) ? ResidualError::GreaterThanHalf : ResidualError::LessThanHalf;
|
||||
}
|
||||
|
||||
const size_t half_bit_position = static_cast<size_t>(shift_amount - 1);
|
||||
const MantissaT half = static_cast<MantissaT>(1) << half_bit_position;
|
||||
const MantissaT error_mask = Common::Ones<MantissaT>(static_cast<size_t>(shift_amount));
|
||||
const MantissaT error = mantissa & error_mask;
|
||||
|
||||
if (error == 0) {
|
||||
return ResidualError::Zero;
|
||||
}
|
||||
if (error < half) {
|
||||
return ResidualError::LessThanHalf;
|
||||
}
|
||||
if (error == half) {
|
||||
return ResidualError::Half;
|
||||
}
|
||||
return ResidualError::GreaterThanHalf;
|
||||
}
|
||||
|
||||
} // namespace Dynarmic::FP
|
||||
Loading…
Add table
Add a link
Reference in a new issue