1# S/390 __udiv_qrnnd 2 3#include <linux/linkage.h> 4 5# 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 13ENTRY(__udiv_qrnnd) 14 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 79