+2014-12-17 Jan Hubicka <hubicka@ucw.cz>
+
+ * sreal.h (sreal::normalize): Implement inline.
+ (sreal::normalize_up): New function.
+ (sreal::normalize_down): New function.
+ * sreal.c (sreal::normalize): Remove.
+
2014-12-17 James Greenhalgh <james.greenhalgh@arm.com>
* config/aarch64/aarch64.md (generic_sched): Delete it.
m_sig >>= s;
}
-/* Normalize *this. */
-
-void
-sreal::normalize ()
-{
- int64_t s = m_sig < 0 ? -1 : 1;
- unsigned HOST_WIDE_INT sig = absu_hwi (m_sig);
-
- if (sig == 0)
- {
- m_exp = -SREAL_MAX_EXP;
- }
- else if (sig < SREAL_MIN_SIG)
- {
- do
- {
- sig <<= 1;
- m_exp--;
- }
- while (sig < SREAL_MIN_SIG);
-
- /* Check underflow. */
- if (m_exp < -SREAL_MAX_EXP)
- {
- m_exp = -SREAL_MAX_EXP;
- sig = 0;
- }
- }
- else if (sig > SREAL_MAX_SIG)
- {
- int last_bit;
- do
- {
- last_bit = sig & 1;
- sig >>= 1;
- m_exp++;
- }
- while (sig > SREAL_MAX_SIG);
-
- /* Round the number. */
- sig += last_bit;
- if (sig > SREAL_MAX_SIG)
- {
- sig >>= 1;
- m_exp++;
- }
-
- /* Check overflow. */
- if (m_exp > SREAL_MAX_EXP)
- {
- m_exp = SREAL_MAX_EXP;
- sig = SREAL_MAX_SIG;
- }
- }
-
- m_sig = s * sig;
-}
-
/* Return integer value of *this. */
int64_t
}
private:
- void normalize ();
+ inline void normalize ();
+ inline void normalize_up ();
+ inline void normalize_down ();
void shift_right (int amount);
static sreal signedless_plus (const sreal &a, const sreal &b, bool negative);
static sreal signedless_minus (const sreal &a, const sreal &b, bool negative);
return a.shift (-exp);
}
+/* Make significant to be >= SREAL_MIN_SIG.
+
+ Make this separate method so inliner can handle hot path better. */
+
+inline void
+sreal::normalize_up ()
+{
+ int64_t s = m_sig < 0 ? -1 : 1;
+ unsigned HOST_WIDE_INT sig = absu_hwi (m_sig);
+ int shift = SREAL_PART_BITS - 2 - floor_log2 (sig);
+
+ gcc_checking_assert (shift > 0);
+ sig <<= shift;
+ m_exp -= shift;
+ gcc_checking_assert (sig <= SREAL_MAX_SIG && sig >= SREAL_MIN_SIG);
+
+ /* Check underflow. */
+ if (m_exp < -SREAL_MAX_EXP)
+ {
+ m_exp = -SREAL_MAX_EXP;
+ sig = 0;
+ }
+ if (s == -1)
+ m_sig = -sig;
+ else
+ m_sig = sig;
+}
+
+/* Make significant to be <= SREAL_MAX_SIG.
+
+ Make this separate method so inliner can handle hot path better. */
+
+inline void
+sreal::normalize_down ()
+{
+ int64_t s = m_sig < 0 ? -1 : 1;
+ int last_bit;
+ unsigned HOST_WIDE_INT sig = absu_hwi (m_sig);
+ int shift = floor_log2 (sig) - SREAL_PART_BITS + 2;
+
+ gcc_checking_assert (shift > 0);
+ last_bit = (sig >> (shift-1)) & 1;
+ sig >>= shift;
+ m_exp += shift;
+ gcc_checking_assert (sig <= SREAL_MAX_SIG && sig >= SREAL_MIN_SIG);
+
+ /* Round the number. */
+ sig += last_bit;
+ if (sig > SREAL_MAX_SIG)
+ {
+ sig >>= 1;
+ m_exp++;
+ }
+
+ /* Check overflow. */
+ if (m_exp > SREAL_MAX_EXP)
+ {
+ m_exp = SREAL_MAX_EXP;
+ sig = SREAL_MAX_SIG;
+ }
+ if (s == -1)
+ m_sig = -sig;
+ else
+ m_sig = sig;
+}
+
+/* Normalize *this; the hot path. */
+
+inline void
+sreal::normalize ()
+{
+ unsigned HOST_WIDE_INT sig = absu_hwi (m_sig);
+
+ if (sig == 0)
+ m_exp = -SREAL_MAX_EXP;
+ else if (sig > SREAL_MAX_SIG)
+ normalize_down ();
+ else if (sig < SREAL_MIN_SIG)
+ normalize_up ();
+}
+
#endif