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/ |