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