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

Moffett, Kyle D Kyle.D.Moffett at boeing.com
Mon Mar 14 21:01:02 CET 2011


On Mar 14, 2011, at 15:41, York Sun wrote:
> Kyle,
> 
> On Mon, 2011-03-14 at 14:04 -0500, Moffett, Kyle D wrote:
>> On 64-bit this change is basically a no-op, because do_div() is implemented as a literal 64-bit divide operation and the instruction scheduling works out almost the same.
>> 
>> On 32-bit PowerPC a fully accurate 64/64 divide (__udivdi3 in libgcc) is 1.1kb of code and hundreds or thousands of dependent cycles to compute, all of which is linked in from libgcc.  Another 1.2kb of code comes in for __umoddi3.
>> 
>> The original reason I wrote this patch is that the native "libgcc" on my boards is hard-float and therefore generates warnings when linking to it from soft-float code.  The toolchain is the native Debian powerpc (or powerpcspe), and most other native PowerPC distributions are also hard-float-only.
>> 
>> When I combine this patch with the other patch I posted to create a minimal internal libgcc with a few 64-bit shift functions from the linux kernel, I can successfully build U-Boot on those native PowerPC systems.
>> 
> 
> Points taken. Can you explain your algorithm? I see you want to do
> clks/5^12/2^13, but I don't see when the clks is divided by 5^12. Did I
> miss some lines?

The "do_div()" macro is a bit confusing that way, it simultaneously performs an in-place division of the first argument and returns the remainder.  Unfortunately that's a clumsy interface that's been around in the Linux kernel for ages.

So this line here:
  clks_rem = do_div(clks, UL_5pow12);

It divides clks by UL_5pow12 and saves the remainder as clks_rem.

Then the 2^^13 divide and remainder is perform with shifts and masks.

Actually, it occurs to me that the one comment isn't quite right, the remainder is a 64-bit value (not a 32-bit one).

I feel relatively confident that this is the right technical direction to go, because almost all of the Linux kernel timekeeping and scheduling code uses 64-bit values and careful application of do_div() or shift+mask for efficiency.

Cheers,
Kyle Moffett


More information about the U-Boot mailing list