Page 216 - ARM 64 Bit Assembly Language
P. 216

204 Chapter 7

                  Listing 7.4 AArch64 assembly implementation of signed and unsigned 64-bit and 128-bit
                                                  division functions
                1  ### ----------------------------------------------------------------
                2  ### divide.S
                3  ### Author: Larry Pyeatt with William Ughetta
                4  ### Date: 10/16/2014. Revised: 07/31/2018.
                5  ###
                6  ### Division functions in AArch64 assembly language
                7  ### ----------------------------------------------------------------
                8
                9         .text
                10        .align  2
                11        .global udiv64
                12        .type   udiv64, %function
                13  /* udiv64 divides the dividend in x0 by the divisor in x1. It
                14  * returns the quotient in x0 and the remainder in x1. */
                15  udiv64:
                16        cbnz    x1, endif1             // if (divisor == 0)
                17        mov     x0, #0                 //  return 0
                18        mov     x1, #0
                19        ret
                20  endif1:
                21        clz     x2, x1                 // x2 = count
                22        lsl     x1, x1, x2             // divisor <<= count
                23        mov     x3, #0                 // x3 = quotient
                24        add     x2, x2, #1             // x2 = count+1
                25  divloop:
                26        lsl     x3, x3, #1             // Shift 0 into quotient LSB
                27        cmp     x0, x1
                28        blo     endif2                 // if (dividend >= divisor)
                29        orr     x3, x3, #1             // Set LSB of quotient
                30        sub     x0, x0, x1             // dividend -= divisor
                31  endif2:
                32        sub     x2, x2, #1             // Decrement count
                33        lsr     x1, x1, #1             // Shift divisor right
                34        cbnz    x2, divloop            // while (count+1 != 0)
                35        mov     x1, x0                 // remainder is the dividend
                36        mov     x0, x3                 // return quotient
                37        ret
                38        .size   udiv64, (. - udiv64)
                39  ### ----------------------------------------------------------------
                40        .global sdiv64
                41        .type   sdiv64, %function
                42  /* sdiv64 divides a signed 64-bit dividend in x0 with a signed
                43  * 64-bit divisor in x1. Returns the quotient in x0 and the
                44  * remainder in x1. Uses udiv64 to do the real work. */
                45  sdiv64:
                46        stp     x29, x30, [sp, #-32]!
   211   212   213   214   215   216   217   218   219   220   221