blob: d321329130eccb600056364afc1f9cee038fcec5 [file] [log] [blame]
Martin Schwidefsky31ee4b22007-02-05 21:18:31 +01001# S/390 __udiv_qrnnd
2
Jan Glauber144d6342011-07-24 10:48:19 +02003#include <linux/linkage.h>
4
Martin Schwidefsky31ee4b22007-02-05 21:18:31 +01005# r2 : &__r
6# r3 : upper half of 64 bit word n
7# r4 : lower half of 64 bit word n
8# r5 : divisor d
9# the reminder r of the division is to be stored to &__r and
10# the quotient q is to be returned
11
12 .text
Jan Glauber144d6342011-07-24 10:48:19 +020013ENTRY(__udiv_qrnnd)
Martin Schwidefsky31ee4b22007-02-05 21:18:31 +010014 st %r2,24(%r15) # store pointer to reminder for later
15 lr %r0,%r3 # reload n
16 lr %r1,%r4
17 ltr %r2,%r5 # reload and test divisor
18 jp 5f
19 # divisor >= 0x80000000
20 srdl %r0,2 # n/4
21 srl %r2,1 # d/2
22 slr %r1,%r2 # special case if last bit of d is set
23 brc 3,0f # (n/4) div (n/2) can overflow by 1
24 ahi %r0,-1 # trick: subtract n/2, then divide
250: dr %r0,%r2 # signed division
26 ahi %r1,1 # trick part 2: add 1 to the quotient
27 # now (n >> 2) = (d >> 1) * %r1 + %r0
28 lhi %r3,1
29 nr %r3,%r1 # test last bit of q
30 jz 1f
31 alr %r0,%r2 # add (d>>1) to r
321: srl %r1,1 # q >>= 1
33 # now (n >> 2) = (d&-2) * %r1 + %r0
34 lhi %r3,1
35 nr %r3,%r5 # test last bit of d
36 jz 2f
37 slr %r0,%r1 # r -= q
38 brc 3,2f # borrow ?
39 alr %r0,%r5 # r += d
40 ahi %r1,-1
412: # now (n >> 2) = d * %r1 + %r0
42 alr %r1,%r1 # q <<= 1
43 alr %r0,%r0 # r <<= 1
44 brc 12,3f # overflow on r ?
45 slr %r0,%r5 # r -= d
46 ahi %r1,1 # q += 1
473: lhi %r3,2
48 nr %r3,%r4 # test next to last bit of n
49 jz 4f
50 ahi %r0,1 # r += 1
514: clr %r0,%r5 # r >= d ?
52 jl 6f
53 slr %r0,%r5 # r -= d
54 ahi %r1,1 # q += 1
55 # now (n >> 1) = d * %r1 + %r0
56 j 6f
575: # divisor < 0x80000000
58 srdl %r0,1
59 dr %r0,%r2 # signed division
60 # now (n >> 1) = d * %r1 + %r0
616: alr %r1,%r1 # q <<= 1
62 alr %r0,%r0 # r <<= 1
63 brc 12,7f # overflow on r ?
64 slr %r0,%r5 # r -= d
65 ahi %r1,1 # q += 1
667: lhi %r3,1
67 nr %r3,%r4 # isolate last bit of n
68 alr %r0,%r3 # r += (n & 1)
69 clr %r0,%r5 # r >= d ?
70 jl 8f
71 slr %r0,%r5 # r -= d
72 ahi %r1,1 # q += 1
738: # now n = d * %r1 + %r0
74 l %r2,24(%r15)
75 st %r0,0(%r2)
76 lr %r2,%r1
77 br %r14
78 .end __udiv_qrnnd