Re: [AD] 4.2 final cleanup

[ Thread Index | Date Index | More lists.liballeg.org/allegro-developers Archives ]


On 2005-09-24, Elias Pschernig <elias@xxxxxxxxxx> wrote:
> On Sat, 2005-09-24 at 19:10 +0100, Peter Hull wrote:
> 
> > 
> > Also, is this one (pivot_sprite, turned out to be something to do with 
> > the fixed point arithmetic) fixed: 
> > http://www.allegro.cc/forums/view_thread.php?_id=525743#target
> > 
> 
> Oh, I remember, I made a very simple fix for that.. but it seems the
> real problem was in some change that was made to fixed point routines,
> so I didn't commit it. If there's no other news, I'll commit that fix
> (just use a double instead of a fixed), since it shouldn't have any ba
> consequences.

The documentation for fixmul specifically talks about overflow, so we
need to restore that behaviour, or change the semantics and update the
documentation.

The following patch:

1. For Intel machines (and compilers without long long) revert to the
original implementation of fixmul (i.e. fixmulf).  I don't know how to
detect an overflow with only 32-bit registers, and when I checked it
again fixmulf was faster (on my P4) than fixmuli anyway!

2. For everything else, I made fixmull detect overflows.  It's much
slower as a result, but still faster than fixmulf on an AMD64.

Peter
Index: include/allegro/inline/fmaths.inl
===================================================================
RCS file: /cvsroot/alleg/allegro/include/allegro/inline/fmaths.inl,v
retrieving revision 1.9
diff -u -p -r1.9 fmaths.inl
--- include/allegro/inline/fmaths.inl	1 Jul 2005 02:52:16 -0000	1.9
+++ include/allegro/inline/fmaths.inl	25 Sep 2005 04:37:00 -0000
@@ -109,34 +109,37 @@ AL_INLINE(fixed, fixsub, (fixed x, fixed
  * Results varied with other compilers, optimisation levels, etc.
  * so this is not optimal, though a tenable compromise.
  *
+ * Note that the following implementation are NOT what were benchmarked.
+ * We had forgotten to put in overflow detection in those versions.
+ * If you don't need overflow detection then previous versions in the
+ * CVS tree might be worth looking at.
+ *
  * PS. Don't move the #ifs inside the AL_INLINE; BCC doesn't like it.
  */
 #if (defined ALLEGRO_I386) || (!defined LONG_LONG)
    AL_INLINE(fixed, fixmul, (fixed x, fixed y),
    {
-      fixed sign = (x^y) & 0x80000000;
-      int mask_x = x >> 31;
-      int mask_y = y >> 31;
-      int mask_result = sign >> 31;
-      fixed result;
-
-      x = (x^mask_x) - mask_x;
-      y = (y^mask_y) - mask_y;
-
-      result = ((y >> 8)*(x >> 8) +
-		(((y >> 8)*(x&0xff)) >> 8) +
-		(((x >> 8)*(y&0xff)) >> 8));
-
-      return (result^mask_result) - mask_result;
+      return ftofix(fixtof(x) * fixtof(y));
    })
 #else
    AL_INLINE(fixed, fixmul, (fixed x, fixed y),
    {
       LONG_LONG lx = x;
       LONG_LONG ly = y;
-      LONG_LONG lres = (lx*ly)>>16;
-      int res = lres;
-      return res;
+      LONG_LONG lres = (lx*ly);
+
+      if (lres > 0x7FFFFFFF0000LL) {
+	 *allegro_errno = ERANGE;
+	 return 0x7FFFFFFF;
+      }
+      else if (lres < -0x7FFFFFFF0000LL) {
+	 *allegro_errno = ERANGE;
+	 return 0x80000000;
+      }
+      else {
+	 int res = lres >> 16;
+	 return res;
+      }
    })
 #endif	    /* fixmul() C implementations */
 

Attachment: fixtime.c.gz
Description: application/gunzip



Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/