Update contrib.
2 * Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
4 * This component and the accompanying materials are made available
5 * under the terms of the License "Eclipse Public License v1.0"
6 * which accompanies this distribution, and is available
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
9 * Initial Contributors:
10 * Nokia Corporation - initial contribution.
15 * e32\nklib\x86\vchelp.cpp
21 #define __NAKED__ __declspec(naked)
26 #pragma warning ( disable : 4414 ) // short jump to function converted to near
29 __NAKED__ void _allmul()
31 // Multiply two 64 bit integers returning a 64 bit result
33 // [esp+4], [esp+8] = arg 1
34 // [esp+12], [esp+16] = arg 1
35 // Return result in edx:eax
36 // Remove arguments from stack
39 _asm mov eax, [esp+4] // eax = low1
40 _asm mul dword ptr [esp+16] // edx:eax = low1*high2
41 _asm mov ecx, eax // keep low 32 bits of product
42 _asm mov eax, [esp+8] // eax = high1
43 _asm mul dword ptr [esp+12] // edx:eax = high1*low2
44 _asm add ecx, eax // accumulate low 32 bits of product
45 _asm mov eax, [esp+4] // eax = low1
46 _asm mul dword ptr [esp+12] // edx:eax = low1*low2
47 _asm add edx, ecx // add cross terms to high 32 bits
53 _asm int 0 // division by zero exception
57 __NAKED__ void UDiv64()
59 // unsigned divide edx:eax by edi:esi
60 // quotient in ebx:eax, remainder in edi:edx
61 // ecx, ebp, esi also modified
63 _asm jnz short UDiv64a // branch if divisor >= 2^32
65 // _ASM_j(z,DivisionByZero) // if divisor=0, branch to error routine
67 _asm mov ebx, eax // ebx=dividend low
68 _asm mov eax, edx // eax=dividend high
69 _asm xor edx, edx // edx=0
70 _asm div esi // quotient high now in eax
71 _asm xchg eax, ebx // quotient high in ebx, dividend low in eax
72 _asm div esi // quotient now in ebx:eax, remainder in edi:edx
75 _asm xor eax, eax // set result to 0xFFFFFFFF
77 _asm jmp short UDiv64f
79 _asm js short UDiv64b // skip if divisor msb set
80 _asm bsr ecx, edi // ecx=bit number of divisor msb - 32
82 _asm push edi // save divisor high
83 _asm push esi // save divisor low
84 _asm shrd esi, edi, cl // shift divisor right so that msb is bit 31
85 _asm mov ebx, edx // dividend into ebx:ebp
87 _asm shrd eax, edx, cl // shift dividend right same number of bits
89 _asm cmp edx, esi // check if approx quotient will be 2^32
90 _asm jae short UDiv64e // if so, true result must be 0xFFFFFFFF
91 _asm div esi // approximate quotient now in eax
93 _asm mov ecx, eax // into ecx
94 _asm mul edi // multiply approx. quotient by divisor high
95 _asm mov esi, eax // ls dword into esi, ms into edi
97 _asm mov eax, ecx // approx. quotient into eax
98 _asm mul dword ptr [esp] // multiply approx. quotient by divisor low
99 _asm add edx, esi // edi:edx:eax now equals approx. quotient * divisor
102 _asm sub ebp, eax // subtract dividend - approx. quotient *divisor
105 _asm jnc short UDiv64c // if no borrow, result OK
106 _asm dec ecx // else result is one too big
107 _asm add ebp, [esp] // and add divisor to get correct remainder
108 _asm adc ebx, [esp+4]
110 _asm mov eax, ecx // result into ebx:eax, remainder into edi:edx
114 _asm add esp, 8 // remove temporary values from stack
118 _asm sub eax, esi // subtract divisor from dividend
120 _asm jnc short UDiv64d // if no borrow, result=1, remainder in edx:eax
121 _asm add eax, esi // else add back
123 _asm dec ebx // and decrement quotient
125 _asm mov edi, edx // remainder into edi:edx
127 _asm mov eax, ebx // result in ebx:eax
132 __NAKED__ void _aulldiv()
134 // Divide two 64 bit unsigned integers returning a 64 bit result
136 // [esp+4], [esp+8] = dividend
137 // [esp+12], [esp+16] = divisor
138 // Return result in edx:eax
139 // Remove arguments from stack
146 _asm mov eax, [esp+20]
147 _asm mov edx, [esp+24]
148 _asm mov esi, [esp+28]
149 _asm mov edi, [esp+32]
159 __NAKED__ void _alldiv()
161 // Divide two 64 bit signed integers returning a 64 bit result
163 // [esp+4], [esp+8] = dividend
164 // [esp+12], [esp+16] = divisor
165 // Return result in edx:eax
166 // Remove arguments from stack
173 _asm mov eax, [esp+20]
174 _asm mov edx, [esp+24]
175 _asm mov esi, [esp+28]
176 _asm mov edi, [esp+32]
178 _asm jns dividend_nonnegative
182 dividend_nonnegative:
184 _asm jns divisor_nonnegative
190 _asm mov ecx, [esp+24]
192 _asm xor ecx, [esp+32]
193 _asm jns quotient_nonnegative
197 quotient_nonnegative:
205 __NAKED__ void _aullrem()
207 // Divide two 64 bit unsigned integers and return 64 bit remainder
209 // [esp+4], [esp+8] = dividend
210 // [esp+12], [esp+16] = divisor
211 // Return result in edx:eax
212 // Remove arguments from stack
219 _asm mov eax, [esp+20]
220 _asm mov edx, [esp+24]
221 _asm mov esi, [esp+28]
222 _asm mov edi, [esp+32]
233 __NAKED__ void _allrem()
235 // Divide two 64 bit signed integers and return 64 bit remainder
237 // [esp+4], [esp+8] = dividend
238 // [esp+12], [esp+16] = divisor
239 // Return result in edx:eax
240 // Remove arguments from stack
247 _asm mov eax, [esp+20]
248 _asm mov edx, [esp+24]
249 _asm mov esi, [esp+28]
250 _asm mov edi, [esp+32]
252 _asm jns dividend_nonnegative
256 dividend_nonnegative:
258 _asm jns divisor_nonnegative
266 _asm cmp dword ptr [esp+24], 0
267 _asm jns rem_nonnegative
279 __NAKED__ void _allshr()
281 // Arithmetic shift right EDX:EAX by ECX
285 _asm jae asr_count_ge_64
287 _asm jae asr_count_ge_32
288 _asm shrd eax, edx, cl
303 __NAKED__ void _allshl()
305 // shift left EDX:EAX by ECX
309 _asm jae lsl_count_ge_64
311 _asm jae lsl_count_ge_32
312 _asm shld edx, eax, cl
327 __NAKED__ void _aullshr()
329 // Logical shift right EDX:EAX by ECX
333 _asm jae lsr_count_ge_64
335 _asm jae lsr_count_ge_32
336 _asm shrd eax, edx, cl