Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/s390/lib/qrnnd.S
10817 views
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
24
0: 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
31
1: 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
40
2: # 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
46
3: lhi %r3,2
47
nr %r3,%r4 # test next to last bit of n
48
jz 4f
49
ahi %r0,1 # r += 1
50
4: 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
56
5: # divisor < 0x80000000
57
srdl %r0,1
58
dr %r0,%r2 # signed division
59
# now (n >> 1) = d * %r1 + %r0
60
6: 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
65
7: 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
72
8: # 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
79