James Cloos <cl...@jhcloos.com> 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. _______________________________________________ Freetype-devel mailing list Freetype-devel@nongnu.org http://lists.nongnu.org/mailman/listinfo/freetype-devel