xref: /openbmc/linux/arch/powerpc/lib/div64.S (revision 75bf465f0bc33e9b776a46d6a1b9b990f5fb7c37)
1*2874c5fdSThomas Gleixner/* SPDX-License-Identifier: GPL-2.0-or-later */
214cf11afSPaul Mackerras/*
314cf11afSPaul Mackerras * Divide a 64-bit unsigned number by a 32-bit unsigned number.
414cf11afSPaul Mackerras * This routine assumes that the top 32 bits of the dividend are
514cf11afSPaul Mackerras * non-zero to start with.
614cf11afSPaul Mackerras * On entry, r3 points to the dividend, which get overwritten with
714cf11afSPaul Mackerras * the 64-bit quotient, and r4 contains the divisor.
814cf11afSPaul Mackerras * On exit, r3 contains the remainder.
914cf11afSPaul Mackerras *
1014cf11afSPaul Mackerras * Copyright (C) 2002 Paul Mackerras, IBM Corp.
1114cf11afSPaul Mackerras */
1214cf11afSPaul Mackerras#include <asm/ppc_asm.h>
1314cf11afSPaul Mackerras#include <asm/processor.h>
1414cf11afSPaul Mackerras
1514cf11afSPaul Mackerras_GLOBAL(__div64_32)
1614cf11afSPaul Mackerras	lwz	r5,0(r3)	# get the dividend into r5/r6
1714cf11afSPaul Mackerras	lwz	r6,4(r3)
1814cf11afSPaul Mackerras	cmplw	r5,r4
1914cf11afSPaul Mackerras	li	r7,0
2014cf11afSPaul Mackerras	li	r8,0
2114cf11afSPaul Mackerras	blt	1f
2214cf11afSPaul Mackerras	divwu	r7,r5,r4	# if dividend.hi >= divisor,
2314cf11afSPaul Mackerras	mullw	r0,r7,r4	# quotient.hi = dividend.hi / divisor
2414cf11afSPaul Mackerras	subf.	r5,r0,r5	# dividend.hi %= divisor
2514cf11afSPaul Mackerras	beq	3f
2614cf11afSPaul Mackerras1:	mr	r11,r5		# here dividend.hi != 0
2714cf11afSPaul Mackerras	andis.	r0,r5,0xc000
2814cf11afSPaul Mackerras	bne	2f
2914cf11afSPaul Mackerras	cntlzw	r0,r5		# we are shifting the dividend right
3014cf11afSPaul Mackerras	li	r10,-1		# to make it < 2^32, and shifting
3114cf11afSPaul Mackerras	srw	r10,r10,r0	# the divisor right the same amount,
32344480b9SPaul Mackerras	addc	r9,r4,r10	# rounding up (so the estimate cannot
3314cf11afSPaul Mackerras	andc	r11,r6,r10	# ever be too large, only too small)
3414cf11afSPaul Mackerras	andc	r9,r9,r10
35344480b9SPaul Mackerras	addze	r9,r9
3614cf11afSPaul Mackerras	or	r11,r5,r11
3714cf11afSPaul Mackerras	rotlw	r9,r9,r0
3814cf11afSPaul Mackerras	rotlw	r11,r11,r0
3914cf11afSPaul Mackerras	divwu	r11,r11,r9	# then we divide the shifted quantities
4014cf11afSPaul Mackerras2:	mullw	r10,r11,r4	# to get an estimate of the quotient,
4114cf11afSPaul Mackerras	mulhwu	r9,r11,r4	# multiply the estimate by the divisor,
4214cf11afSPaul Mackerras	subfc	r6,r10,r6	# take the product from the divisor,
4314cf11afSPaul Mackerras	add	r8,r8,r11	# and add the estimate to the accumulated
4414cf11afSPaul Mackerras	subfe.	r5,r9,r5	# quotient
4514cf11afSPaul Mackerras	bne	1b
4614cf11afSPaul Mackerras3:	cmplw	r6,r4
4714cf11afSPaul Mackerras	blt	4f
4814cf11afSPaul Mackerras	divwu	r0,r6,r4	# perform the remaining 32-bit division
4914cf11afSPaul Mackerras	mullw	r10,r0,r4	# and get the remainder
5014cf11afSPaul Mackerras	add	r8,r8,r0
5114cf11afSPaul Mackerras	subf	r6,r10,r6
5214cf11afSPaul Mackerras4:	stw	r7,0(r3)	# return the quotient in *r3
5314cf11afSPaul Mackerras	stw	r8,4(r3)
5414cf11afSPaul Mackerras	mr	r3,r6		# return the remainder in r3
5514cf11afSPaul Mackerras	blr
56