Commit 7a1ce632 by Jan Hubicka Committed by Jan Hubicka

sreal.h (normalize, [...]): Add new_sig/new_exp parameters.


	* sreal.h (normalize, normalize_up, normalize_down): Add new_sig/new_exp
	parameters.
	(sreal constructor): Update.
	* sreal.c (sreal:operator+, sreal:operator-, sreal:operator*,
	sreal:operator/): Update.

From-SVN: r263952
parent 9ed6dbee
2018-08-29 Jan Hubicka <jh@suse.cz>
* sreal.h (normalize, normalize_up, normalize_down): Add new_sig/new_exp
parameters.
(sreal constructor): Update.
* sreal.c (sreal:operator+, sreal:operator-, sreal:operator*,
sreal:operator/): Update.
2018-08-29 Martin Liska <mliska@suse.cz> 2018-08-29 Martin Liska <mliska@suse.cz>
* tree-switch-conversion.c (switch_conversion::expand): * tree-switch-conversion.c (switch_conversion::expand):
......
...@@ -138,7 +138,8 @@ sreal ...@@ -138,7 +138,8 @@ sreal
sreal::operator+ (const sreal &other) const sreal::operator+ (const sreal &other) const
{ {
int dexp; int dexp;
sreal tmp, r; sreal tmp;
int64_t r_sig, r_exp;
const sreal *a_p = this, *b_p = &other, *bb; const sreal *a_p = this, *b_p = &other, *bb;
...@@ -146,10 +147,14 @@ sreal::operator+ (const sreal &other) const ...@@ -146,10 +147,14 @@ sreal::operator+ (const sreal &other) const
std::swap (a_p, b_p); std::swap (a_p, b_p);
dexp = a_p->m_exp - b_p->m_exp; dexp = a_p->m_exp - b_p->m_exp;
r.m_exp = a_p->m_exp; r_exp = a_p->m_exp;
if (dexp > SREAL_BITS) if (dexp > SREAL_BITS)
{ {
r.m_sig = a_p->m_sig; r_sig = a_p->m_sig;
sreal r;
r.m_sig = r_sig;
r.m_exp = r_exp;
return r; return r;
} }
...@@ -162,8 +167,8 @@ sreal::operator+ (const sreal &other) const ...@@ -162,8 +167,8 @@ sreal::operator+ (const sreal &other) const
bb = &tmp; bb = &tmp;
} }
r.m_sig = a_p->m_sig + bb->m_sig; r_sig = a_p->m_sig + bb->m_sig;
r.normalize (); sreal r (r_sig, r_exp);
return r; return r;
} }
...@@ -174,7 +179,8 @@ sreal ...@@ -174,7 +179,8 @@ sreal
sreal::operator- (const sreal &other) const sreal::operator- (const sreal &other) const
{ {
int dexp; int dexp;
sreal tmp, r; sreal tmp;
int64_t r_sig, r_exp;
const sreal *bb; const sreal *bb;
const sreal *a_p = this, *b_p = &other; const sreal *a_p = this, *b_p = &other;
...@@ -186,10 +192,14 @@ sreal::operator- (const sreal &other) const ...@@ -186,10 +192,14 @@ sreal::operator- (const sreal &other) const
} }
dexp = a_p->m_exp - b_p->m_exp; dexp = a_p->m_exp - b_p->m_exp;
r.m_exp = a_p->m_exp; r_exp = a_p->m_exp;
if (dexp > SREAL_BITS) if (dexp > SREAL_BITS)
{ {
r.m_sig = sign * a_p->m_sig; r_sig = sign * a_p->m_sig;
sreal r;
r.m_sig = r_sig;
r.m_exp = r_exp;
return r; return r;
} }
if (dexp == 0) if (dexp == 0)
...@@ -201,8 +211,8 @@ sreal::operator- (const sreal &other) const ...@@ -201,8 +211,8 @@ sreal::operator- (const sreal &other) const
bb = &tmp; bb = &tmp;
} }
r.m_sig = sign * (a_p->m_sig - bb->m_sig); r_sig = sign * ((int64_t) a_p->m_sig - bb->m_sig);
r.normalize (); sreal r (r_sig, r_exp);
return r; return r;
} }
...@@ -212,17 +222,14 @@ sreal ...@@ -212,17 +222,14 @@ sreal
sreal::operator* (const sreal &other) const sreal::operator* (const sreal &other) const
{ {
sreal r; sreal r;
if (absu_hwi (m_sig) < SREAL_MIN_SIG || absu_hwi (other.m_sig) < SREAL_MIN_SIG) if (absu_hwi (m_sig) < SREAL_MIN_SIG
|| absu_hwi (other.m_sig) < SREAL_MIN_SIG)
{ {
r.m_sig = 0; r.m_sig = 0;
r.m_exp = -SREAL_MAX_EXP; r.m_exp = -SREAL_MAX_EXP;
} }
else else
{ r.normalize (m_sig * (int64_t) other.m_sig, m_exp + other.m_exp);
r.m_sig = m_sig * other.m_sig;
r.m_exp = m_exp + other.m_exp;
r.normalize ();
}
return r; return r;
} }
...@@ -233,11 +240,9 @@ sreal ...@@ -233,11 +240,9 @@ sreal
sreal::operator/ (const sreal &other) const sreal::operator/ (const sreal &other) const
{ {
gcc_checking_assert (other.m_sig != 0); gcc_checking_assert (other.m_sig != 0);
sreal r; sreal r (SREAL_SIGN (m_sig)
r.m_sig * ((int64_t)SREAL_ABS (m_sig) << SREAL_PART_BITS) / other.m_sig,
= SREAL_SIGN (m_sig) * (SREAL_ABS (m_sig) << SREAL_PART_BITS) / other.m_sig; m_exp - other.m_exp - SREAL_PART_BITS);
r.m_exp = m_exp - other.m_exp - SREAL_PART_BITS;
r.normalize ();
return r; return r;
} }
......
...@@ -45,9 +45,9 @@ public: ...@@ -45,9 +45,9 @@ public:
sreal () : m_sig (-1), m_exp (-1) {} sreal () : m_sig (-1), m_exp (-1) {}
/* Construct a sreal. */ /* Construct a sreal. */
sreal (int64_t sig, int exp = 0) : m_sig (sig), m_exp (exp) sreal (int64_t sig, int exp = 0)
{ {
normalize (); normalize (sig, exp);
} }
void dump (FILE *) const; void dump (FILE *) const;
...@@ -130,9 +130,9 @@ public: ...@@ -130,9 +130,9 @@ public:
} }
private: private:
inline void normalize (); inline void normalize (int64_t new_sig, signed int new_exp);
inline void normalize_up (); inline void normalize_up (int64_t new_sig, signed int new_exp);
inline void normalize_down (); inline void normalize_down (int64_t new_sig, signed int new_exp);
void shift_right (int amount); void shift_right (int amount);
static sreal signedless_plus (const sreal &a, const sreal &b, bool negative); static sreal signedless_plus (const sreal &a, const sreal &b, bool negative);
static sreal signedless_minus (const sreal &a, const sreal &b, bool negative); static sreal signedless_minus (const sreal &a, const sreal &b, bool negative);
...@@ -199,23 +199,24 @@ inline sreal operator>> (const sreal &a, int exp) ...@@ -199,23 +199,24 @@ inline sreal operator>> (const sreal &a, int exp)
Make this separate method so inliner can handle hot path better. */ Make this separate method so inliner can handle hot path better. */
inline void inline void
sreal::normalize_up () sreal::normalize_up (int64_t new_sig, signed int new_exp)
{ {
unsigned HOST_WIDE_INT sig = absu_hwi (m_sig); unsigned HOST_WIDE_INT sig = absu_hwi (new_sig);
int shift = SREAL_PART_BITS - 2 - floor_log2 (sig); int shift = SREAL_PART_BITS - 2 - floor_log2 (sig);
gcc_checking_assert (shift > 0); gcc_checking_assert (shift > 0);
sig <<= shift; sig <<= shift;
m_exp -= shift; new_exp -= shift;
gcc_checking_assert (sig <= SREAL_MAX_SIG && sig >= SREAL_MIN_SIG); gcc_checking_assert (sig <= SREAL_MAX_SIG && sig >= SREAL_MIN_SIG);
/* Check underflow. */ /* Check underflow. */
if (m_exp < -SREAL_MAX_EXP) if (new_exp < -SREAL_MAX_EXP)
{ {
m_exp = -SREAL_MAX_EXP; new_exp = -SREAL_MAX_EXP;
sig = 0; sig = 0;
} }
if (SREAL_SIGN (m_sig) == -1) m_exp = new_exp;
if (SREAL_SIGN (new_sig) == -1)
m_sig = -sig; m_sig = -sig;
else else
m_sig = sig; m_sig = sig;
...@@ -226,16 +227,16 @@ sreal::normalize_up () ...@@ -226,16 +227,16 @@ sreal::normalize_up ()
Make this separate method so inliner can handle hot path better. */ Make this separate method so inliner can handle hot path better. */
inline void inline void
sreal::normalize_down () sreal::normalize_down (int64_t new_sig, signed int new_exp)
{ {
int last_bit; int last_bit;
unsigned HOST_WIDE_INT sig = absu_hwi (m_sig); unsigned HOST_WIDE_INT sig = absu_hwi (new_sig);
int shift = floor_log2 (sig) - SREAL_PART_BITS + 2; int shift = floor_log2 (sig) - SREAL_PART_BITS + 2;
gcc_checking_assert (shift > 0); gcc_checking_assert (shift > 0);
last_bit = (sig >> (shift-1)) & 1; last_bit = (sig >> (shift-1)) & 1;
sig >>= shift; sig >>= shift;
m_exp += shift; new_exp += shift;
gcc_checking_assert (sig <= SREAL_MAX_SIG && sig >= SREAL_MIN_SIG); gcc_checking_assert (sig <= SREAL_MAX_SIG && sig >= SREAL_MIN_SIG);
/* Round the number. */ /* Round the number. */
...@@ -243,16 +244,17 @@ sreal::normalize_down () ...@@ -243,16 +244,17 @@ sreal::normalize_down ()
if (sig > SREAL_MAX_SIG) if (sig > SREAL_MAX_SIG)
{ {
sig >>= 1; sig >>= 1;
m_exp++; new_exp++;
} }
/* Check overflow. */ /* Check overflow. */
if (m_exp > SREAL_MAX_EXP) if (new_exp > SREAL_MAX_EXP)
{ {
m_exp = SREAL_MAX_EXP; new_exp = SREAL_MAX_EXP;
sig = SREAL_MAX_SIG; sig = SREAL_MAX_SIG;
} }
if (SREAL_SIGN (m_sig) == -1) m_exp = new_exp;
if (SREAL_SIGN (new_sig) == -1)
m_sig = -sig; m_sig = -sig;
else else
m_sig = sig; m_sig = sig;
...@@ -261,16 +263,24 @@ sreal::normalize_down () ...@@ -261,16 +263,24 @@ sreal::normalize_down ()
/* Normalize *this; the hot path. */ /* Normalize *this; the hot path. */
inline void inline void
sreal::normalize () sreal::normalize (int64_t new_sig, signed int new_exp)
{ {
unsigned HOST_WIDE_INT sig = absu_hwi (m_sig); unsigned HOST_WIDE_INT sig = absu_hwi (new_sig);
if (sig == 0) if (sig == 0)
m_exp = -SREAL_MAX_EXP; {
m_sig = 0;
m_exp = -SREAL_MAX_EXP;
}
else if (sig > SREAL_MAX_SIG) else if (sig > SREAL_MAX_SIG)
normalize_down (); normalize_down (new_sig, new_exp);
else if (sig < SREAL_MIN_SIG) else if (sig < SREAL_MIN_SIG)
normalize_up (); normalize_up (new_sig, new_exp);
else
{
m_sig = new_sig;
m_exp = new_exp;
}
} }
#endif #endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment