1# S/390 __udiv_qrnnd
2
3# r2 : &__r
4# r3 : upper half of 64 bit word n
5# r4 : lower half of 64 bit word n
6# r5 : divisor d
7# the reminder r of the division is to be stored to &__r and
8# the quotient q is to be returned
9
10	.text
11	.globl __udiv_qrnnd
12__udiv_qrnnd:
13	st    %r2,24(%r15)	  # store pointer to reminder for later
14	lr    %r0,%r3		  # reload n
15	lr    %r1,%r4
16	ltr   %r2,%r5		  # reload and test divisor
17	jp    5f
18	# divisor >= 0x80000000
19	srdl  %r0,2		  # n/4
20	srl   %r2,1		  # d/2
21	slr   %r1,%r2		  # special case if last bit of d is set
22	brc   3,0f		  #  (n/4) div (n/2) can overflow by 1
23	ahi   %r0,-1		  #  trick: subtract n/2, then divide
240:	dr    %r0,%r2		  # signed division
25	ahi   %r1,1		  #  trick part 2: add 1 to the quotient
26	# now (n >> 2) = (d >> 1) * %r1 + %r0
27	lhi   %r3,1
28	nr    %r3,%r1		  # test last bit of q
29	jz    1f
30	alr   %r0,%r2		  # add (d>>1) to r
311:	srl   %r1,1		  # q >>= 1
32	# now (n >> 2) = (d&-2) * %r1 + %r0
33	lhi   %r3,1
34	nr    %r3,%r5		  # test last bit of d
35	jz    2f
36	slr   %r0,%r1		  # r -= q
37	brc   3,2f		  # borrow ?
38	alr   %r0,%r5		  # r += d
39	ahi   %r1,-1
402:	# now (n >> 2) = d * %r1 + %r0
41	alr   %r1,%r1		  # q <<= 1
42	alr   %r0,%r0		  # r <<= 1
43	brc   12,3f		  # overflow on r ?
44	slr   %r0,%r5		  # r -= d
45	ahi   %r1,1		  # q += 1
463:	lhi   %r3,2
47	nr    %r3,%r4		  # test next to last bit of n
48	jz    4f
49	ahi   %r0,1		  # r += 1
504:	clr   %r0,%r5		  # r >= d ?
51	jl    6f
52	slr   %r0,%r5		  # r -= d
53	ahi   %r1,1		  # q += 1
54	# now (n >> 1) = d * %r1 + %r0
55	j     6f
565:	# divisor < 0x80000000
57	srdl  %r0,1
58	dr    %r0,%r2		  # signed division
59	# now (n >> 1) = d * %r1 + %r0
606:	alr   %r1,%r1		  # q <<= 1
61	alr   %r0,%r0		  # r <<= 1
62	brc   12,7f		  # overflow on r ?
63	slr   %r0,%r5		  # r -= d
64	ahi   %r1,1		  # q += 1
657:	lhi   %r3,1
66	nr    %r3,%r4		  # isolate last bit of n
67	alr   %r0,%r3		  # r += (n & 1)
68	clr   %r0,%r5		  # r >= d ?
69	jl    8f
70	slr   %r0,%r5		  # r -= d
71	ahi   %r1,1		  # q += 1
728:	# now n = d * %r1 + %r0
73	l     %r2,24(%r15)
74	st    %r0,0(%r2)
75	lr    %r2,%r1
76	br    %r14
77	.end	__udiv_qrnnd
78