Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-or-later */
0002 /*
0003  * Divide a 64-bit unsigned number by a 32-bit unsigned number.
0004  * This routine assumes that the top 32 bits of the dividend are
0005  * non-zero to start with.
0006  * On entry, r3 points to the dividend, which get overwritten with
0007  * the 64-bit quotient, and r4 contains the divisor.
0008  * On exit, r3 contains the remainder.
0009  *
0010  * Copyright (C) 2002 Paul Mackerras, IBM Corp.
0011  */
0012 #include <asm/ppc_asm.h>
0013 #include <asm/processor.h>
0014 
0015 _GLOBAL(__div64_32)
0016     lwz r5,0(r3)    # get the dividend into r5/r6
0017     lwz r6,4(r3)
0018     cmplw   r5,r4
0019     li  r7,0
0020     li  r8,0
0021     blt 1f
0022     divwu   r7,r5,r4    # if dividend.hi >= divisor,
0023     mullw   r0,r7,r4    # quotient.hi = dividend.hi / divisor
0024     subf.   r5,r0,r5    # dividend.hi %= divisor
0025     beq 3f
0026 1:  mr  r11,r5      # here dividend.hi != 0
0027     andis.  r0,r5,0xc000
0028     bne 2f
0029     cntlzw  r0,r5       # we are shifting the dividend right
0030     li  r10,-1      # to make it < 2^32, and shifting
0031     srw r10,r10,r0  # the divisor right the same amount,
0032     addc    r9,r4,r10   # rounding up (so the estimate cannot
0033     andc    r11,r6,r10  # ever be too large, only too small)
0034     andc    r9,r9,r10
0035     addze   r9,r9
0036     or  r11,r5,r11
0037     rotlw   r9,r9,r0
0038     rotlw   r11,r11,r0
0039     divwu   r11,r11,r9  # then we divide the shifted quantities
0040 2:  mullw   r10,r11,r4  # to get an estimate of the quotient,
0041     mulhwu  r9,r11,r4   # multiply the estimate by the divisor,
0042     subfc   r6,r10,r6   # take the product from the divisor,
0043     add r8,r8,r11   # and add the estimate to the accumulated
0044     subfe.  r5,r9,r5    # quotient
0045     bne 1b
0046 3:  cmplw   r6,r4
0047     blt 4f
0048     divwu   r0,r6,r4    # perform the remaining 32-bit division
0049     mullw   r10,r0,r4   # and get the remainder
0050     add r8,r8,r0
0051     subf    r6,r10,r6
0052 4:  stw r7,0(r3)    # return the quotient in *r3
0053     stw r8,4(r3)
0054     mr  r3,r6       # return the remainder in r3
0055     blr