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 "ppc_asm.h"
0013 
0014     .globl __div64_32
0015 __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
0056 
0057 /*
0058  * Extended precision shifts.
0059  *
0060  * Updated to be valid for shift counts from 0 to 63 inclusive.
0061  * -- Gabriel
0062  *
0063  * R3/R4 has 64 bit value
0064  * R5    has shift count
0065  * result in R3/R4
0066  *
0067  *  ashrdi3: arithmetic right shift (sign propagation)  
0068  *  lshrdi3: logical right shift
0069  *  ashldi3: left shift
0070  */
0071     .globl __ashrdi3
0072 __ashrdi3:
0073     subfic  r6,r5,32
0074     srw r4,r4,r5    # LSW = count > 31 ? 0 : LSW >> count
0075     addi    r7,r5,32    # could be xori, or addi with -32
0076     slw r6,r3,r6    # t1 = count > 31 ? 0 : MSW << (32-count)
0077     rlwinm  r8,r7,0,32  # t3 = (count < 32) ? 32 : 0
0078     sraw    r7,r3,r7    # t2 = MSW >> (count-32)
0079     or  r4,r4,r6    # LSW |= t1
0080     slw r7,r7,r8    # t2 = (count < 32) ? 0 : t2
0081     sraw    r3,r3,r5    # MSW = MSW >> count
0082     or  r4,r4,r7    # LSW |= t2
0083     blr
0084 
0085     .globl __ashldi3
0086 __ashldi3:
0087     subfic  r6,r5,32
0088     slw r3,r3,r5    # MSW = count > 31 ? 0 : MSW << count
0089     addi    r7,r5,32    # could be xori, or addi with -32
0090     srw r6,r4,r6    # t1 = count > 31 ? 0 : LSW >> (32-count)
0091     slw r7,r4,r7    # t2 = count < 32 ? 0 : LSW << (count-32)
0092     or  r3,r3,r6    # MSW |= t1
0093     slw r4,r4,r5    # LSW = LSW << count
0094     or  r3,r3,r7    # MSW |= t2
0095     blr
0096 
0097     .globl __lshrdi3
0098 __lshrdi3:
0099     subfic  r6,r5,32
0100     srw r4,r4,r5    # LSW = count > 31 ? 0 : LSW >> count
0101     addi    r7,r5,32    # could be xori, or addi with -32
0102     slw r6,r3,r6    # t1 = count > 31 ? 0 : MSW << (32-count)
0103     srw r7,r3,r7    # t2 = count < 32 ? 0 : MSW >> (count-32)
0104     or  r4,r4,r6    # LSW |= t1
0105     srw r3,r3,r5    # MSW = MSW >> count
0106     or  r4,r4,r7    # LSW |= t2
0107     blr