1 // This file is dual licensed under the MIT and the University of Illinois Open
2 // Source Licenses. See LICENSE.TXT for details.
4 #include "../assembly.h"
6 // di_int __divdi3(di_int a, di_int b);
9 // both inputs and the output are 64-bit signed integers.
10 // This will do whatever the underlying hardware is set to do on division by zero.
11 // No other exceptions are generated, as the divide cannot overflow.
13 // This is targeted at 32-bit x86 *only*, as this can be done directly in hardware
14 // on x86_64. The performance goal is ~40 cycles per divide, which is faster than
15 // currently possible via simulation of integer divides on the x87 unit.
17 // Stephen Canon, December 2008
23 DEFINE_COMPILERRT_FUNCTION(__divdi3)
25 /* This is currently implemented by wrapping the unsigned divide up in an absolute
26 value, then restoring the correct sign at the end of the computation. This could
27 certainly be improved upon. */
30 movl 20(%esp), %edx // high word of b
31 movl 16(%esp), %eax // low word of b
33 sarl $31, %ecx // (b < 0) ? -1 : 0
35 xorl %ecx, %edx // EDX:EAX = (b < 0) ? not(b) : b
37 sbbl %ecx, %edx // EDX:EAX = abs(b)
39 movl %eax, 16(%esp) // store abs(b) back to stack
40 movl %ecx, %esi // set aside sign of b
42 movl 12(%esp), %edx // high word of b
43 movl 8(%esp), %eax // low word of b
45 sarl $31, %ecx // (a < 0) ? -1 : 0
47 xorl %ecx, %edx // EDX:EAX = (a < 0) ? not(a) : a
49 sbbl %ecx, %edx // EDX:EAX = abs(a)
51 movl %eax, 8(%esp) // store abs(a) back to stack
52 xorl %ecx, %esi // sign of result = (sign of a) ^ (sign of b)
55 movl 24(%esp), %ebx // Find the index i of the leading bit in b.
56 bsrl %ebx, %ecx // If the high word of b is zero, jump to
57 jz 9f // the code to handle that special case [9].
59 /* High word of b is known to be non-zero on this branch */
61 movl 20(%esp), %eax // Construct bhi, containing bits [1+i:32+i] of b
63 shrl %cl, %eax // Practically, this means that bhi is given by:
65 notl %ecx // bhi = (high word of b) << (31 - i) |
66 shll %cl, %ebx // (low word of b) >> (1 + i)
68 movl 16(%esp), %edx // Load the high and low words of a, and jump
69 movl 12(%esp), %eax // to [1] if the high word is larger than bhi
70 cmpl %ebx, %edx // to avoid overflowing the upcoming divide.
73 /* High word of a is greater than or equal to (b >> (1 + i)) on this branch */
75 divl %ebx // eax <-- qs, edx <-- r such that ahi:alo = bs*qs + r
80 shrl %cl, %eax // q = qs >> (1 + i)
82 mull 24(%esp) // q*blo
84 movl 20(%esp), %ecx // ECX:EBX = a
86 sbbl %edx, %ecx // ECX:EBX = a - q*blo
88 imull %edi, %eax // q*bhi
89 subl %eax, %ecx // ECX:EBX = a - q*b
90 sbbl $0, %edi // decrement q if remainder is negative
94 addl %esi, %eax // Restore correct sign to result
98 popl %edi // Restore callee-save registers
104 1: /* High word of a is greater than or equal to (b >> (1 + i)) on this branch */
106 subl %ebx, %edx // subtract bhi from ahi so that divide will not
107 divl %ebx // overflow, and find q and r such that
109 // ahi:alo = (1:q)*bhi + r
111 // Note that q is a number in (31-i).(1+i)
117 orl $0x80000000, %eax
118 shrl %cl, %eax // q = (1:qs) >> (1 + i)
120 mull 24(%esp) // q*blo
122 movl 20(%esp), %ecx // ECX:EBX = a
124 sbbl %edx, %ecx // ECX:EBX = a - q*blo
126 imull %edi, %eax // q*bhi
127 subl %eax, %ecx // ECX:EBX = a - q*b
128 sbbl $0, %edi // decrement q if remainder is negative
132 addl %esi, %eax // Restore correct sign to result
136 popl %edi // Restore callee-save registers
142 9: /* High word of b is zero on this branch */
144 movl 16(%esp), %eax // Find qhi and rhi such that
145 movl 20(%esp), %ecx //
146 xorl %edx, %edx // ahi = qhi*b + rhi with 0 ≤ rhi < b
149 movl 12(%esp), %eax // Find qlo such that
151 movl %ebx, %edx // rhi:alo = qlo*b + rlo with 0 ≤ rlo < b
153 addl %esi, %eax // Restore correct sign to result
157 popl %ebx // Restore callee-save registers
160 END_COMPILERRT_FUNCTION(__divdi3)