freetype-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [ft-devel] FT_MulFix assembly


From: Miles Bader
Subject: Re: [ft-devel] FT_MulFix assembly
Date: Wed, 08 Sep 2010 11:28:00 +0900

James Cloos <address@hidden> writes:
> Since FT's C version uses longs, though, this:
>
> int another (long a, long b) {
>     long r = (long)a * (long)b;
>     long s = r >> 31;
>     return (r + s + 0x8000) >> 16;
> }

That's not correct though, is it?  The variable "s" should be the "all
sign" portion of the multiplication, but since the two inputs have 32
significant bits (never mind the types), the product will have 64
significant bits.  So "r >> 31" won't be all-sign, it'll be a bunch of
... other bits. :)

However, changing the shift to 63:

   FT_Long
   FT_MulFix_C_new2( FT_Long  a,
                     FT_Long  b )
   {
     FT_Int64 prod = (FT_Int64)a * (FT_Int64)b;
     FT_Int64 sign = prod >> 63;
     return ((prod + sign + 0x8000) >> 16);
   }

... does seem to yield correct results:

   $ ./t 0x7AFA8000 0xFFFFFFFF
   0x7afa8000 x 0xffffffff =>
       C: 0xffff8505
   C_new: 0xffff8505
   C_nw2: 0xffff8505
   C_ano: 0xffff8505
     asm: 0xffff8505

"C" is the old C, "C_new" was my previous attempt, "C_nw2" is the above
"FT_MulFix_C_new2" function, "C_ano" is the "another" function, and
"asm" was your final asm version.

["another" yields misleadingly correct results in this case, because of
the particular argument values given; in other cases, it gives
incorrect results.]

-miles

-- 
Discriminate, v.i. To note the particulars in which one person or thing is,
if possible, more objectionable than another.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]