1. 07 Dec, 2006 1 commit
    • Nicolas Pitre's avatar
      [ARM] 3611/4: optimize do_div() when divisor is constant · fa4adc61
      Nicolas Pitre authored
      On ARM all divisions have to be performed "manually".  For 64-bit
      divisions that may take more than a hundred cycles in many cases.
      
      With 32-bit divisions gcc already use the recyprocal of constant
      divisors to perform a multiplication, but not with 64-bit divisions.
      
      Since the kernel is increasingly relying upon 64-bit divisions it is
      worth optimizing at least those cases where the divisor is a constant.
      This is what this patch does using plain C code that gets optimized away
      at compile time.
      
      For example, despite the amount of added C code, do_div(x, 10000) now
      produces the following assembly code (where x is assigned to r0-r1):
      
      	adr	r4, .L0
      	ldmia	r4, {r4-r5}
      	umull	r2, r3, r4, r0
      	mov	r2, #0
      	umlal	r3, r2, r5, r0
      	umlal	r3, r2, r4, r1
      	mov	r3, #0
      	umlal	r2, r3, r5, r1
      	mov	r0, r2, lsr #11
      	orr	r0, r0, r3, lsl #21
      	mov	r1, r3, lsr #11
      	...
      .L0:
      	.word	948328779
      	.word	879609302
      
      which is the fastest that can be done for any value of x in that case,
      many times faster than the __do_div64 code (except for the small x value
      space for which the result ends up being zero or a single bit).
      
      The fact that this code is generated inline produces a tiny increase in
      .text size, but not significant compared to the needed code around each
      __do_div64 call site this code is replacing.
      
      The algorithm used has been validated on a 16-bit scale for all possible
      values, and then recodified for 64-bit values.  Furthermore I've been
      running it with the final BUG_ON() uncommented for over two months now
      with no problem.
      
      Note that this new code is compiled with gcc versions 4.0 or later.
      Earlier gcc versions proved themselves too problematic and only the
      original code is used with them.
      Signed-off-by: default avatarNicolas Pitre <nico@cam.org>
      Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
      fa4adc61
  2. 29 Nov, 2006 22 commits
  3. 28 Nov, 2006 17 commits