[AD] ftofix optimisation

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


I have optimised a float to fix conversion routine for another project, and
I thought you might be interested. It's about 5-10 times faster than the
original ftofix (on a K6).

It does saturation even better than the original ftofix, and it can also do
rounding (it will be slightly faster without though). It is done for the
float type used in DJGPP (1 bit sign + 8 bits exp + 23 bits mantissa), if
float is composed in any other way it won't work. So it should be within
some kind of #ifdefs.

The big secret is to avoid the x87 FP coprocessor, which requires loads of
instructions to convert from float to integer. Manual conversion is very
much faster. Modern non-x87 FPUs may be better at float-to-int conversion,
so this routine might only be optimal on x86 CPUs.

Here is the code:

fixed ftofix(float f)
{
  fixed i;
  fixed sign;
  unsigned char shift;

  i = *(fixed*)&f;
  sign = i >> 31;
  i &= 0x7FFFFFFF;
  if (i >= 0x47000000)
  {
    *allegro_errno = ERANGE;
    return 0x7FFFFFFF - sign;
  }
  shift = 0x8d - (i >> 23);
#if you want rounding
  if (shift > 7)
    return ((((((i & 0x007FFFFF) | 0x00800000) << 7) + (1 << (shift - 1)))
>> shift) + sign) ^ sign;
  else
#endif
    return (((((i & 0x007FFFFF) | 0x00800000) << 7) >> shift) + sign) ^ sign;
}

Erik




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