Page 217 - ARM 64 Bit Assembly Language
P. 217
Integer mathematics 205
47 str x19, [sp, #16] // Push FP,LR,& Callee-saved
48
49 cmp x0, #0 // If dividend is negative
50 cneg x0, x0, lt // Complement
51 cset x19, lt // Set sign bit for result
52
53 cmp x1, #0 // If divisor is negative
54 cneg x1, x1, lt // Complement
55 eor x9, x19, #1
56 csel x19, x9, x19, lt // Complement sign bit
57
58 bl udiv64
59
60 cmp x19, #0 // Complement remainder if
61 cneg x0, x0, ne // sign bit is set
62 cneg x1, x1, ne
63
64 ldr x19, [sp, #16]
65 ldp x29, x30, [sp], #32 // Pop FP,LR,& Callee-saved
66 ret
67 .size sdiv64,(. - sdiv64)
68 ### ----------------------------------------------------------------
69 .global udiv128
70 .type udiv128, %function
71 /* udiv128 divides the dividend in x0:x1 by the divisor in
72 * x2:x3. It returns the 128 bit result in x0:x1 and the
73 * remainder in x2:x3. x2 is low order bits (i.e. lo:hi). */
74 udiv128:
75 orr x9, x2, x3
76 cbnz x9, endif3 // if (divisor == 0)
77 mov x0, #0 // return 0
78 mov x1, #0
79 ret
80 endif3:
81 mov x4, #0 // x4:x5 = quotient
82 mov x5, #0
83
84 ## Count leading zeroes
85 clz x6, x3 // count high order bits
86 cbnz x6, endif4 // if (divisorHigh == 0)
87 clz x6, x4 // count low order bits
88 add x6, x6, #64
89 endif4:
90 neg x7, x6 // x7 = -count
91 add x8, x6, #128 // x8 = 128 - count
92 add x9, x7, #64 // x9 = 64 - count
93 cmp x9, #0
94 csel x7, x8, x9, lt // x7 = (128 - count) % 64
95