Page 218 - ARM 64 Bit Assembly Language
P. 218
206 Chapter 7
96 ## shift divisor x2:x3 << count
97 lsl x3, x3, x6 // divisorHigh <<= count
98 lsr x9, x2, x7 // tmp=Low >> (128-count)%64
99 orr x3, x3, x9 // divisorHigh |= tmp
100 lsl x2, x2, x6 // divisorLow <<= count
101
102 add x6, x6, #1 // x6 = count+1
103 divloop128:
104 lsl x5, x5, #1 // Shift 0 into quotient LSB
105 lsr x9, x4, #63 // tmp = Low >> 63
106 orr x5, x5, x9
107 lsl x4, x4, #1
108
109 cmp x1, x3
110 bne endif5
111 cmp x0, x2
112 endif5:
113 blo endif6 // if (dividend >= divisor)
114 orr x4, x4, #1 // Set LSB of quotient
115 sub x0, x0, x2 // dividend -= divisor
116 sub x1, x1, x3
117 endif6:
118 sub x6, x6, #1 // Decrement count
119 lsr x2, x2, #1 // Shift divisor right
120 lsl x9, x3, #63
121 orr x2, x2, x9
122 lsr x3, x3, #1
123 cbnz x6, divloop128 // while (count+1 != 0)
124 mov x2, x0 // remainder is the dividend
125 mov x3, x1
126 mov x0, x4 // return quotient
127 mov x1, x5
128 ret
129 .size udiv128,(. - udiv128)
130 ### ----------------------------------------------------------------
131
132 /* sdiv128 divides the signed dividend in x0:x1 by the signed
133 * divisor in x2:x3. It returns the 128 bit result in x0:x1
134 * and the remainder in x2:x3. Uses udiv128. */
135 .global sdiv128
136 .type sdiv128, %function
137 sdiv128:
138 stp x29, x30, [sp, #-32]!
139 str x19, [sp, #16]
140 cmp x1, #0 // If dividendHigh < 0
141 bge endif7
142 mvn x0, x0 // Bitwise NOT
143 mvn x1, x1
144 adds x0, x0, #1 // Add 1 for 2’s complement