1 /* SPDX-License-Identifier: GPL-2.0 */ !! 1 /* 2 /* !! 2 * Divide a 64-bit unsigned number by a 32-bit unsigned number. 3 * unsigned long __xdiv64_32(unsigned long lon !! 3 * This routine assumes that the top 32 bits of the dividend are >> 4 * non-zero to start with. >> 5 * On entry, r3 points to the dividend, which get overwritten with >> 6 * the 64-bit quotient, and r4 contains the divisor. >> 7 * On exit, r3 contains the remainder. >> 8 * >> 9 * Copyright (C) 2002 Paul Mackerras, IBM Corp. >> 10 * >> 11 * This program is free software; you can redistribute it and/or >> 12 * modify it under the terms of the GNU General Public License >> 13 * as published by the Free Software Foundation; either version >> 14 * 2 of the License, or (at your option) any later version. 4 */ 15 */ >> 16 #include <asm/ppc_asm.h> >> 17 #include <asm/processor.h> 5 18 6 #include <linux/linkage.h> !! 19 _GLOBAL(__div64_32) 7 !! 20 lwz r5,0(r3) # get the dividend into r5/r6 8 .text !! 21 lwz r6,4(r3) 9 ENTRY(__xdiv64_32) !! 22 cmplw r5,r4 10 #ifdef CONFIG_CPU_LITTLE_ENDIAN !! 23 li r7,0 11 mov r4, r0 !! 24 li r8,0 12 mov r5, r1 !! 25 blt 1f 13 #else !! 26 divwu r7,r5,r4 # if dividend.hi >= divisor, 14 mov r4, r1 !! 27 mullw r0,r7,r4 # quotient.hi = dividend.hi / divisor 15 mov r5, r0 !! 28 subf. r5,r0,r5 # dividend.hi %= divisor 16 #endif !! 29 beq 3f 17 cmp/hs r6, r1 !! 30 1: mr r11,r5 # here dividend.hi != 0 18 bf.s 1f !! 31 andis. r0,r5,0xc000 19 mov #0, r2 !! 32 bne 2f 20 !! 33 cntlzw r0,r5 # we are shifting the dividend right 21 mov r1, r2 !! 34 li r10,-1 # to make it < 2^32, and shifting 22 mov #0, r3 !! 35 srw r10,r10,r0 # the divisor right the same amount, 23 div0u !! 36 add r9,r4,r10 # rounding up (so the estimate cannot 24 .rept 32 !! 37 andc r11,r6,r10 # ever be too large, only too small) 25 rotcl r2 !! 38 andc r9,r9,r10 26 div1 r6, r3 !! 39 or r11,r5,r11 27 .endr !! 40 rotlw r9,r9,r0 28 rotcl r2 !! 41 rotlw r11,r11,r0 29 mul.l r6, r2 !! 42 divwu r11,r11,r9 # then we divide the shifted quantities 30 sts macl, r3 !! 43 2: mullw r10,r11,r4 # to get an estimate of the quotient, 31 sub r3, r1 !! 44 mulhwu r9,r11,r4 # multiply the estimate by the divisor, 32 1: !! 45 subfc r6,r10,r6 # take the product from the divisor, 33 div0u !! 46 add r8,r8,r11 # and add the estimate to the accumulated 34 .rept 32 !! 47 subfe. r5,r9,r5 # quotient 35 rotcl r0 !! 48 bne 1b 36 div1 r6, r1 !! 49 3: cmplw r6,r4 37 .endr !! 50 blt 4f 38 #ifdef CONFIG_CPU_LITTLE_ENDIAN !! 51 divwu r0,r6,r4 # perform the remaining 32-bit division 39 mov r2, r1 !! 52 mullw r10,r0,r4 # and get the remainder 40 rts !! 53 add r8,r8,r0 41 rotcl r0 !! 54 subf r6,r10,r6 42 #else !! 55 4: stw r7,0(r3) # return the quotient in *r3 43 rotcl r0 !! 56 stw r8,4(r3) 44 mov r0, r1 !! 57 mr r3,r6 # return the remainder in r3 45 rts !! 58 blr 46 mov r2, r0 << 47 #endif <<
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.