[U-Boot] [PATCHv2] fsl_ddr: Don't use full 64-bit divides on32-bit PowerPC

Moffett, Kyle D Kyle.D.Moffett at boeing.com
Mon Mar 14 22:35:46 CET 2011


On Mar 14, 2011, at 16:22, York Sun wrote:
> On Wed, 2011-02-23 at 11:35 -0500, Kyle Moffett wrote:
>> +	 * Now divide by 5^12 and track the 32-bit remainder, then divide
>> +	 * by 2*(2^12) using shifts (and updating the remainder).
>> +	 */
>> +	clks_rem = do_div(clks, UL_5pow12);
>> +	clks_rem <<= 13;
> 
> Shouldn't this be clks_rem >>= 13 ?
>> 
>> +	clks_rem |= clks & (UL_2pow13-1);
>> +	clks >>= 13;
>> +
>> +	/* If we had a remainder, then round up */
>> +	if (clks_rem)
>> 		clks++;
>> -	}

Since I'm dividing a second time, the old remainder value represents the high bits of the new remainder value and therefore needs to be left-shifted, then the now-empty low bits of the remainder are taken from the bits of "clks" which get shifted away.

Example:

Say I want to divide 1999999999999 (IE: 2*10^^12 - 1) by 2000000000000 (2*10^^12).  Obviously the dividend is less than the divisor (by 1), so the result should be 0 and the remainder should be equal to the dividend.

So my initial value is:
  clks = 1999999999999;

Now I divide by 5^^12:
  clks_rem = do_div(clks, 244140625); /* This number is 5pow12 */

The results are:
  clks_rem == 244140624
  clks == 8191

Now I shift left:
  clks_rem <<= 13;

And get:
  clks_rem == 1999999991808

Finally, I copy the low bits of clks to clks_rem and shift them out of clks:
  clks_rem |= clks & (UL_2pow13-1);
  clks >>= 13

The result is as expected:
  clks_rem == 1999999999999;
  clks == 0;

Cheers,
Kyle Moffett



More information about the U-Boot mailing list