Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Leap:42.2:Ports
aranym
nan-sign.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File nan-sign.patch of Package aranym
From 789f038532fc23c1e0bfc0b6d4b37790425a39c3 Mon Sep 17 00:00:00 2001 From: Andreas Schwab <schwab@linux-m68k.org> Date: Sat, 22 Aug 2015 13:28:40 +0200 Subject: [PATCH] Properly track sign bit of NaN in mpfr fpu emulator --- ChangeLog | 4 +++ src/uae_cpu/fpu/fpu_mpfr.cpp | 68 ++++++++++++++++++++++++++++++++++---------- src/uae_cpu/fpu/types.h | 1 + 3 files changed, 58 insertions(+), 15 deletions(-) Index: aranym-1.0.2/src/uae_cpu/fpu/fpu_mpfr.cpp =================================================================== --- aranym-1.0.2.orig/src/uae_cpu/fpu/fpu_mpfr.cpp +++ aranym-1.0.2/src/uae_cpu/fpu/fpu_mpfr.cpp @@ -112,10 +112,17 @@ get_cur_prec () #define DEFAULT_NAN_BITS 0xffffffffffffffffULL static void -set_nan (fpu_register ®, uae_u64 nan_bits) +set_nan (fpu_register ®, uae_u64 nan_bits, int nan_sign) { mpfr_set_nan (reg.f); reg.nan_bits = nan_bits; + reg.nan_sign = nan_sign; +} + +static void +set_nan (fpu_register ®) +{ + set_nan (reg, DEFAULT_NAN_BITS, 0); } static bool fpu_inited; @@ -189,7 +196,7 @@ fpu_reset () fpu.instruction_address = 0; for (int i = 0; i < 8; i++) - set_nan (fpu.registers[i], DEFAULT_NAN_BITS); + set_nan (fpu.registers[i]); } fpu_register::operator long double () @@ -267,7 +274,7 @@ set_from_single (fpu_register &value, ua { if (!(m & 0x400000)) cur_exceptions |= FPSR_EXCEPTION_SNAN; - set_nan (value, (uae_u64) (m | 0xc00000) << (32 + 8)); + set_nan (value, (uae_u64) (m | 0xc00000) << (32 + 8), s); } else mpfr_set_inf (value.f, 0); @@ -300,7 +307,7 @@ set_from_double (fpu_register &value, ua if (!(m & 0x80000)) cur_exceptions |= FPSR_EXCEPTION_SNAN; set_nan (value, (((uae_u64) (m | 0x180000) << (32 + 11)) - | ((uae_u64) words[1] << 11))); + | ((uae_u64) words[1] << 11)), s); } else mpfr_set_inf (value.f, 0); @@ -336,7 +343,7 @@ set_from_extended (fpu_register &value, cur_exceptions |= FPSR_EXCEPTION_SNAN; words[1] |= 0x40000000; } - set_nan (value, ((uae_u64) words[1] << 32) | words[2]); + set_nan (value, ((uae_u64) words[1] << 32) | words[2], s); } else mpfr_set_inf (value.f, 0); @@ -367,7 +374,8 @@ set_from_packed (fpu_register &value, ua { if ((words[1] & 0x40000000) == 0) cur_exceptions |= FPSR_EXCEPTION_SNAN; - set_nan (value, ((uae_u64) (words[1] | 0x40000000) << 32) | words[2]); + set_nan (value, ((uae_u64) (words[1] | 0x40000000) << 32) | words[2], + sm); } else mpfr_set_inf (value.f, 0); @@ -410,6 +418,7 @@ get_fp_value (uae_u32 opcode, uae_u32 ex { mpfr_set (value.f, fpu.registers[(extra >> 10) & 7].f, MPFR_RNDN); value.nan_bits = fpu.registers[(extra >> 10) & 7].nan_bits; + value.nan_sign = fpu.registers[(extra >> 10) & 7].nan_sign; /* Check for SNaN. */ if (mpfr_nan_p (value.f) && (value.nan_bits & (1ULL << 62)) == 0) { @@ -572,12 +581,13 @@ update_exceptions () } static void -set_fp_register (int reg, mpfr_t value, uae_u64 nan_bits, +set_fp_register (int reg, mpfr_t value, uae_u64 nan_bits, int nan_sign, int t, mpfr_rnd_t rnd, bool do_flags) { mpfr_subnormalize (value, t, rnd); mpfr_set (fpu.registers[reg].f, value, rnd); fpu.registers[reg].nan_bits = nan_bits; + fpu.registers[reg].nan_sign = nan_sign; if (do_flags) { uae_u32 flags = 0; @@ -594,6 +604,20 @@ set_fp_register (int reg, mpfr_t value, } } +static void +set_fp_register (int reg, mpfr_t value, int t, mpfr_rnd_t rnd, bool do_flags) +{ + set_fp_register (reg, value, DEFAULT_NAN_BITS, 0, t, rnd, do_flags); +} + +static void +set_fp_register (int reg, fpu_register &value, int t, mpfr_rnd_t rnd, + bool do_flags) +{ + set_fp_register (reg, value.f, value.nan_bits, value.nan_sign, t, rnd, + do_flags); +} + static uae_u32 extract_to_single (fpu_register &value) { @@ -619,6 +643,8 @@ extract_to_single (fpu_register &value) cur_exceptions |= FPSR_EXCEPTION_SNAN; } word = 0x7f800000 | ((value.nan_bits >> (32 + 8)) & 0x7fffff); + if (value.nan_sign) + word |= 0x80000000; } else if (mpfr_zero_p (single)) word = 0; @@ -679,6 +705,8 @@ extract_to_double (fpu_register &value, } words[0] = 0x7ff00000 | ((value.nan_bits >> (32 + 11)) & 0xfffff); words[1] = value.nan_bits >> 11; + if (value.nan_sign) + words[0] |= 0x80000000; } else if (mpfr_zero_p (dbl)) { @@ -730,6 +758,8 @@ extract_to_extended (fpu_register &value words[0] = 0x7fff0000; words[1] = value.nan_bits >> 32; words[2] = value.nan_bits; + if (value.nan_sign) + words[0] |= 0x80000000; } else if (mpfr_zero_p (value.f)) { @@ -781,6 +811,8 @@ extract_to_packed (fpu_register &value, words[0] = 0x7fff0000; words[1] = value.nan_bits >> 32; words[2] = value.nan_bits; + if (value.nan_sign) + words[0] |= 0x80000000; } else if (mpfr_zero_p (value.f)) { @@ -1471,6 +1503,7 @@ fpuop_general (uae_u32 opcode, uae_u32 e mpfr_init2 (value.f, prec); value.nan_bits = DEFAULT_NAN_BITS; + value.nan_sign = 0; mpfr_clear_flags (); set_format (prec); @@ -1486,7 +1519,7 @@ fpuop_general (uae_u32 opcode, uae_u32 e t = mpfr_set (value.f, fpu_constant_rom[rom_index - 32], rnd); else mpfr_set_zero (value.f, 0); - set_fp_register (reg, value.f, value.nan_bits, t, rnd, true); + set_fp_register (reg, value, t, rnd, true); } else if (extra & 0x40) { @@ -1580,7 +1613,7 @@ fpuop_general (uae_u32 opcode, uae_u32 e t = mpfr_sub (value2, fpu.registers[reg].f, value.f, rnd); break; } - set_fp_register (reg, value2, value.nan_bits, t, rnd, true); + set_fp_register (reg, value2, t, rnd, true); } else if ((extra & 0x30) == 0x30) { @@ -1605,8 +1638,8 @@ fpuop_general (uae_u32 opcode, uae_u32 e cur_exceptions |= FPSR_EXCEPTION_OPERR; t = mpfr_sin_cos (value.f, value2, value.f, rnd); if (reg2 != reg) - set_fp_register (reg2, value2, value.nan_bits, t >> 2, rnd, false); - set_fp_register (reg, value.f, value.nan_bits, t & 3, rnd, true); + set_fp_register (reg2, value2, t >> 2, rnd, false); + set_fp_register (reg, value, t & 3, rnd, true); } else if ((extra & 15) == 8) // FCMP @@ -1727,12 +1760,14 @@ fpuop_general (uae_u32 opcode, uae_u32 e break; case 24: // FABS t = mpfr_abs (value.f, value.f, rnd); + value.nan_sign = 0; break; case 25: // FCOSH t = mpfr_cosh (value.f, value.f, rnd); break; case 26: // FNEG t = mpfr_neg (value.f, value.f, rnd); + value.nan_sign = !value.nan_sign; break; case 28: // FACOS if (mpfr_cmpabs (value.f, FPU_CONSTANT_ONE) > 0) @@ -1820,7 +1855,7 @@ fpuop_general (uae_u32 opcode, uae_u32 e t = mpfr_sub (value.f, fpu.registers[reg].f, value.f, rnd); break; } - set_fp_register (reg, value.f, value.nan_bits, t, rnd, true); + set_fp_register (reg, value, t, rnd, true); } update_exceptions (); ret = true; Index: aranym-1.0.2/src/uae_cpu/fpu/types.h =================================================================== --- aranym-1.0.2.orig/src/uae_cpu/fpu/types.h +++ aranym-1.0.2/src/uae_cpu/fpu/types.h @@ -166,6 +166,7 @@ typedef uae_f32 fpu_single; struct fpu_register { mpfr_t f; uae_u64 nan_bits; + int nan_sign; operator long double (); };
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor