mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 05:37:34 +00:00
UserspaceEmulator: Delegate rounding to the actual hardware
This also makes us a bit more accurate, due to better rounding of intermediate results. This also gives us the flush-to-zero and denormals-are-zero SSE settings for free! (Assuming UE is build with SSE)
This commit is contained in:
parent
56a31ab376
commit
6c41267dcf
5 changed files with 91 additions and 126 deletions
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include "Report.h"
|
||||
#include <AK/Concepts.h>
|
||||
#include <AK/FPControl.h>
|
||||
#include <AK/SIMD.h>
|
||||
#include <LibX86/Instruction.h>
|
||||
#include <LibX86/Interpreter.h>
|
||||
|
@ -17,6 +18,8 @@
|
|||
|
||||
namespace UserspaceEmulator {
|
||||
using namespace AK::SIMD;
|
||||
using AK::RoundingMode;
|
||||
|
||||
class Emulator;
|
||||
class SoftCPU;
|
||||
|
||||
|
@ -35,6 +38,7 @@ public:
|
|||
SoftFPU(Emulator& emulator, SoftCPU& cpu)
|
||||
: m_emulator(emulator)
|
||||
, m_cpu(cpu)
|
||||
, m_fpu_cw { 0x037F }
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -81,13 +85,6 @@ private:
|
|||
Empty = 0b11
|
||||
};
|
||||
|
||||
enum class RoundingMode : u8 {
|
||||
NEAREST = 0b00,
|
||||
DOWN = 0b01,
|
||||
UP = 0b10,
|
||||
TRUNC = 0b11
|
||||
};
|
||||
|
||||
void fpu_dump_env()
|
||||
{
|
||||
reportln("Exceptions: #I:{} #D:{} #Z:{} #O:{} #U:{} #P:{} #SF:{} Summary:{}",
|
||||
|
@ -100,12 +97,12 @@ private:
|
|||
m_fpu_error_stackfault,
|
||||
m_fpu_error_summary);
|
||||
reportln("Masks: #I:{} #D:{} #Z:{} #O:{} #U:{} #P:{}",
|
||||
m_fpu_mask_invalid,
|
||||
m_fpu_mask_denorm,
|
||||
m_fpu_mask_zero_div,
|
||||
m_fpu_mask_overflow,
|
||||
m_fpu_mask_underflow,
|
||||
m_fpu_mask_precision);
|
||||
m_fpu_cw.mask_invalid,
|
||||
m_fpu_cw.mask_denorm,
|
||||
m_fpu_cw.mask_zero_div,
|
||||
m_fpu_cw.mask_overflow,
|
||||
m_fpu_cw.mask_underflow,
|
||||
m_fpu_cw.mask_precision);
|
||||
reportln("C0:{} C1:{} C2:{} C3:{}", c0(), c1(), c2(), c3());
|
||||
reportln("fpu-stacktop: {}", m_fpu_stack_top);
|
||||
reportln("fpu-stack /w stacktop (real):");
|
||||
|
@ -261,18 +258,14 @@ private:
|
|||
|
||||
ALWAYS_INLINE RoundingMode fpu_get_round_mode() const
|
||||
{
|
||||
return RoundingMode(m_fpu_round_mode);
|
||||
return m_fpu_cw.rounding_control;
|
||||
}
|
||||
|
||||
template<Arithmetic T>
|
||||
T fpu_round(long double) const;
|
||||
template<Arithmetic T>
|
||||
T fpu_round_checked(long double);
|
||||
T round_checked(long double);
|
||||
|
||||
template<FloatingPoint T>
|
||||
T fpu_convert(long double) const;
|
||||
template<FloatingPoint T>
|
||||
T fpu_convert_checked(long double);
|
||||
T convert_checked(long double);
|
||||
|
||||
ALWAYS_INLINE void fpu_set_unordered()
|
||||
{
|
||||
|
@ -295,22 +288,7 @@ private:
|
|||
};
|
||||
} m_storage[8];
|
||||
|
||||
union {
|
||||
u16 m_fpu_cw { 0x037F };
|
||||
struct {
|
||||
u16 m_fpu_mask_invalid : 1;
|
||||
u16 m_fpu_mask_denorm : 1;
|
||||
u16 m_fpu_mask_zero_div : 1;
|
||||
u16 m_fpu_mask_overflow : 1;
|
||||
u16 m_fpu_mask_underflow : 1;
|
||||
u16 m_fpu_mask_precision : 1;
|
||||
u16 : 2; // unused
|
||||
u16 m_fpu_precission : 2;
|
||||
u16 m_fpu_round_mode : 2;
|
||||
u16 m_fpu_infinity_control : 1;
|
||||
u16 : 3; // unused
|
||||
};
|
||||
};
|
||||
AK::X87ControlWord m_fpu_cw;
|
||||
|
||||
union {
|
||||
u16 m_fpu_sw { 0 };
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue