# Mesa (master): mesa: Sparc's IROUND() optimization is invalid.

Brian Paul brianp at kemper.freedesktop.org
Sat Feb 28 08:43:07 PST 2009

Module: Mesa
Branch: master
Commit: ae5c06b9ce1191afaa95dd784d7315f25ec729ff
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=ae5c06b9ce1191afaa95dd784d7315f25ec729ff

Author: David Miller <davem at davemloft.net>
Date:   Fri Feb 27 23:34:41 2009 -0800

mesa: Sparc's IROUND() optimization is invalid.

We can't use the "fstoi" instruction like this.

Unlike other floating point instructions, "fstoi" always rounds
towards zero no matter what rounding mode the FPU has been set to.

This was validated using the following test program:

--------------------
static inline int iround(float f)
{
int r;
__asm__ ("fstoi %1, %0" : "=f" (r) : "f" (f));
return r;
}
#define IROUND(x)  iround(x)

#define IROUND_REF(f)  ((int) (((f) >= 0.0F) ? ((f) + 0.5F) : ((f) - 0.5F)))

int main(void)
{
float f = -2.0;

while (f < 3.0f) {
int sparc_val = IROUND(f);
int ref_val = IROUND_REF(f);

if (sparc_val != ref_val)
printf("DIFFERENT[%f]: REF==%d SPARC==%d\n",
f, ref_val, sparc_val);
f += 0.1f;
}

return 0;
}
--------------------

which prints out things like:

--------------------
DIFFERENT[-1.900000]: REF==-2 SPARC==-1
DIFFERENT[-1.800000]: REF==-2 SPARC==-1
DIFFERENT[-1.700000]: REF==-2 SPARC==-1
DIFFERENT[-1.600000]: REF==-2 SPARC==-1
DIFFERENT[-1.000000]: REF==-1 SPARC==0
DIFFERENT[-0.900000]: REF==-1 SPARC==0
DIFFERENT[-0.800000]: REF==-1 SPARC==0
DIFFERENT[-0.700000]: REF==-1 SPARC==0
DIFFERENT[-0.600000]: REF==-1 SPARC==0
DIFFERENT[0.500000]: REF==1 SPARC==0
DIFFERENT[0.600000]: REF==1 SPARC==0
...
--------------------

So we have to remove Sparc's IROUND() definition, it's wrong.

Signed-off-by: David S. Miller <davem at davemloft.net>

---

src/mesa/main/imports.h |   10 +---------
1 files changed, 1 insertions(+), 9 deletions(-)

diff --git a/src/mesa/main/imports.h b/src/mesa/main/imports.h
index 4192f03..7b61e22 100644
--- a/src/mesa/main/imports.h
+++ b/src/mesa/main/imports.h
@@ -256,15 +256,7 @@ static INLINE int GET_FLOAT_BITS( float x )
/***
*** IROUND: return (as an integer) float rounded to nearest integer
***/
-#if defined(USE_SPARC_ASM) && defined(__GNUC__) && defined(__sparc__)
-static INLINE int iround(float f)
-{
-   int r;
-   __asm__ ("fstoi %1, %0" : "=f" (r) : "f" (f));
-   return r;
-}
-#define IROUND(x)  iround(x)
-#elif defined(USE_X86_ASM) && defined(__GNUC__) && defined(__i386__) && \
+#if defined(USE_X86_ASM) && defined(__GNUC__) && defined(__i386__) && \
(!(defined(__BEOS__) || defined(__HAIKU__))  || \
(__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95)))
static INLINE int iround(float f)