diff --git a/ChangeLog b/ChangeLog index aed178405..4e174549d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2014-10-02 Alexei Podtelezhnikov + + [base] Significant optimization of `ft_div64by32' + + We shift as many bits as we can into the high register, perform + 32-bit division with modulo there, then work through the remaining + bits with long division. This optimization is especially noticeable + for smaller dividends that barely use the high register. + + * src/base/ftcalc.c (ft_div64by32): Updated. + 2014-10-02 Dave Arnold [cff] Fix Savannah bug #43271. @@ -70,7 +81,7 @@ Fix Savannah bug #43153. * src/psaux/psconv.c (PS_Conv_ToFixed): Add protection against - overflow in `divider'. + overflow in `divider'. 2014-09-03 Alexei Podtelezhnikov diff --git a/src/base/ftcalc.c b/src/base/ftcalc.c index 502beb7bc..d0c43e02c 100644 --- a/src/base/ftcalc.c +++ b/src/base/ftcalc.c @@ -304,17 +304,24 @@ FT_Int i; - q = 0; - r = hi; - - if ( r >= y ) + if ( hi >= y ) return (FT_UInt32)0x7FFFFFFFL; - i = 32; + /* We shift as many bits as we can into the high register, perform */ + /* 32-bit division with modulo there, then work through the remaining */ + /* bits with long division. This optimization is especially noticeable */ + /* for smaller dividends that barely use the high register. */ + + i = 31 - FT_MSB( hi ); + r = ( hi << i ) | ( lo >> ( 32 - i ) ); lo <<= i; /* left 64-bit shift */ + q = r / y; + r -= q * y; /* remainder */ + + i = 32 - i; /* bits remaining in low register */ do { q <<= 1; - r = ( r << 1 ) | ( lo >> 31 ); lo <<= 1; /* left 64-bit shift */ + r = ( r << 1 ) | ( lo >> 31 ); lo <<= 1; if ( r >= y ) {