Commit 7abdb8cceab1b8855548548c16e0ecc2136c3c33

Alexei Podtelezhnikov 2014-10-02T23:13:33

[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.

diff --git a/ChangeLog b/ChangeLog
index aed1784..4e17454 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2014-10-02  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[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  <darnold@adobe.com>
 
 	[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  <apodtele@gmail.com>
 
diff --git a/src/base/ftcalc.c b/src/base/ftcalc.c
index 502beb7..d0c43e0 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 )
       {