/*
 * 5799-WZQ (C) COPYRIGHT IBM CORPORATION 1986
 * LICENSED MATERIALS - PROPERTY OF IBM
 * REFER TO COPYRIGHT INSTRUCTIONS FORM NUMBER G120-2083
 */
/* $Header:uldiv.s 12.0$ */
/* $ACIS:uldiv.s 12.0$ */
/* $Source: /ibm/acis/usr/src/lib/libc/ca/gen/RCS/uldiv.s,v $ */

	.data
rcsid:	.asciz	"$Header:uldiv.s 12.0$"
	.text

#include "LINKG.h"

 #	Unsigned divide of two 32 bit integers (quotient = dividend / divisor)
 #		quotient = uldiv$$(dividend, divisor);
 #
 #	NONSTANDARD LINKAGE:
 #
 #		On entry,	r0 MAY NOT be set: nonstandard linkage.
 #				r2 = dividend
 #				r3 = divisor
 #				r15= link 
 #		On return,	r0 = quotient, for pcc
 #				r2 = quotient, for other compilers
 #				r3 = remainder, for other compilers
 #
 #	Unsigned remainder:
 #		remainder = (ulrem$$(dividend, divisor);
 #
 #		Same entry conditions, same exit except r0 = r2 = remainder.
 #
 
.set mq	,	r10			#multiplier quotient system control reg

	.globl	uldiv$$
uldiv$$:
ENTRY(uldiv$$)
	cli	r3,1
	je	divby1			# (wjb) special-case division by 1
	mts	%mq,r2

 #check for a divisor >= 2**31 which the divide-step treats as negative.

	cis	r3,0			
	jnh	bigdiv			#divisor == 0  or > 2**31 - 1 (negative)

 # (ef) 11/29/85 I don't understand this, but don't think it needs to be done
 #      before the call to bigdiv (it used to be)
	lis	r2,0			#most significant 32 bits of dividend
 
	d	r2,r3	
	d	r2,r3	
	d	r2,r3	
	d	r2,r3	
	d	r2,r3	
	d	r2,r3	
	d	r2,r3	
	d	r2,r3	

	d	r2,r3	
	d	r2,r3	
	d	r2,r3	
	d	r2,r3	
	d	r2,r3	
	d	r2,r3	
	d	r2,r3	
	d	r2,r3	

	d	r2,r3	
	d	r2,r3	
	d	r2,r3	
	d	r2,r3	
	d	r2,r3	
	d	r2,r3	
	d	r2,r3	
	d	r2,r3	

	d	r2,r3	
	d	r2,r3	
	d	r2,r3	
	d	r2,r3	
	d	r2,r3	
	d	r2,r3	
	d	r2,r3	
	d	r2,r3	
 
 
 #fix up remainder, according to the following table.
 #
 #    carry  overflow quotient	remainder
 #
 #	0	0	ok	+ divisor
 #	0	1	ok	+ divisor
 #	1	0	ok	ok
 #	1	1	ok	ok
 
	bc0x	return			#jump if carry indicator is on
	mfs	%mq,r0			#copy quotient from the mq
	a	r2,r3			#carry = 0, overflow = ?
 
 #return to the calling routine
 
return: mr	r3,r2			# remainder to r3
	brx	r15
	mr	r2,r0			# quotient to r2 and r0

 # divisor = 1

divby1:	lis	r0,0			# quotient = dividend = r2
	berx	r15
	lis	r3,0			# remainder = 0

 #divisor >= 2**31. there are two cases to consider. note that the
 #dividend and divisor must be treated as 32 bit unsigned numbers.
 #
 # dividend < divisor:	quotient = 0, remainder = dividend
 #
 # dividend >= divisor:	quotient = 1, remainder = dividend - divisor
 
bigdiv: je	trap			#division by zero
 #	mr	r2,r0	 		#copy dividend into remainder
	lis	r0,0			#assume dividend < divisor
	cl	r2,r3			#if dividend < divisor
	jl	return			#then jump to return sequence
 
	s	r2,r3			#else decr by divisor (sign is ok !)
	lis	r0,1			#and set quotient to one
	j	return
 

 # divisor is zero. this should trap.
 # NOTE:
 #	This trap instruction is very specific!  When the kernel
 #	receives a trap, it checks for this exact instruction to
 #	distinguish a division by zero from a break-point.  See
 #	code in trap.c, and be sure to fix if this ever changes!
 #
trap:	ti	2,r3,0		# trap on equal
	lis	r2,1		# one quotient
	mr	r0,r2		# pcc quotient
	brx	r15
	lis	r3,0		# remainder = 0
 
	.globl	ulrem$$
ulrem$$:
ENTRY(ulrem$$)
	st	r15,REG_OFFSET+60(r1)
	bali	r15,uldiv$$
	l	r15,REG_OFFSET+60(r1)
	mr	r2,r3
	brx	r15
	mr	r0,r3
	
	TTNOFRM
