Update contrib.
1 // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of the License "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // e32\common\x86\x86hlp.inl
19 #include "x86hlp_gcc.inl"
22 /**** MSVC helpers ****/
24 /*static void DivisionByZero()
29 #pragma warning ( disable : 4414 ) // short jump to function converted to near
32 __NAKED__ void _allmul()
34 // Multiply two 64 bit integers returning a 64 bit result
36 // [esp+4], [esp+8] = arg 1
37 // [esp+12], [esp+16] = arg 1
38 // Return result in edx:eax
39 // Remove arguments from stack
42 _asm mov eax, [esp+4] // eax = low1
43 _asm mul dword ptr [esp+16] // edx:eax = low1*high2
44 _asm mov ecx, eax // keep low 32 bits of product
45 _asm mov eax, [esp+8] // eax = high1
46 _asm mul dword ptr [esp+12] // edx:eax = high1*low2
47 _asm add ecx, eax // accumulate low 32 bits of product
48 _asm mov eax, [esp+4] // eax = low1
49 _asm mul dword ptr [esp+12] // edx:eax = low1*low2
50 _asm add edx, ecx // add cross terms to high 32 bits
56 _asm int 0 // division by zero exception
60 __NAKED__ void UDiv64()
62 // unsigned divide edx:eax by edi:esi
63 // quotient in ebx:eax, remainder in edi:edx
64 // ecx, ebp, esi also modified
66 _asm jnz short UDiv64a // branch if divisor >= 2^32
68 // _ASM_j(z,DivisionByZero) // if divisor=0, branch to error routine
70 _asm mov ebx, eax // ebx=dividend low
71 _asm mov eax, edx // eax=dividend high
72 _asm xor edx, edx // edx=0
73 _asm div esi // quotient high now in eax
74 _asm xchg eax, ebx // quotient high in ebx, dividend low in eax
75 _asm div esi // quotient now in ebx:eax, remainder in edi:edx
78 _asm xor eax, eax // set result to 0xFFFFFFFF
80 _asm jmp short UDiv64f
82 _asm js short UDiv64b // skip if divisor msb set
83 _asm bsr ecx, edi // ecx=bit number of divisor msb - 32
85 _asm push edi // save divisor high
86 _asm push esi // save divisor low
87 _asm shrd esi, edi, cl // shift divisor right so that msb is bit 31
88 _asm mov ebx, edx // dividend into ebx:ebp
90 _asm shrd eax, edx, cl // shift dividend right same number of bits
92 _asm cmp edx, esi // check if approx quotient will be 2^32
93 _asm jae short UDiv64e // if so, true result must be 0xFFFFFFFF
94 _asm div esi // approximate quotient now in eax
96 _asm mov ecx, eax // into ecx
97 _asm mul edi // multiply approx. quotient by divisor high
98 _asm mov esi, eax // ls dword into esi, ms into edi
100 _asm mov eax, ecx // approx. quotient into eax
101 _asm mul dword ptr [esp] // multiply approx. quotient by divisor low
102 _asm add edx, esi // edi:edx:eax now equals approx. quotient * divisor
105 _asm sub ebp, eax // subtract dividend - approx. quotient *divisor
108 _asm jnc short UDiv64c // if no borrow, result OK
109 _asm dec ecx // else result is one too big
110 _asm add ebp, [esp] // and add divisor to get correct remainder
111 _asm adc ebx, [esp+4]
113 _asm mov eax, ecx // result into ebx:eax, remainder into edi:edx
117 _asm add esp, 8 // remove temporary values from stack
121 _asm sub eax, esi // subtract divisor from dividend
123 _asm jnc short UDiv64d // if no borrow, result=1, remainder in edx:eax
124 _asm add eax, esi // else add back
126 _asm dec ebx // and decrement quotient
128 _asm mov edi, edx // remainder into edi:edx
130 _asm mov eax, ebx // result in ebx:eax
135 __NAKED__ void _aulldvrm()
137 // Divide two 64 bit unsigned integers, returning a 64 bit result
138 // and a 64 bit remainder
141 // [esp+4], [esp+8] = dividend
142 // [esp+12], [esp+16] = divisor
144 // Return (dividend / divisor) in edx:eax
145 // Return (dividend % divisor) in ebx:ecx
147 // Remove arguments from stack
153 _asm mov eax, [esp+16]
154 _asm mov edx, [esp+20]
155 _asm mov esi, [esp+24]
156 _asm mov edi, [esp+28]
167 __NAKED__ void _alldvrm()
169 // Divide two 64 bit signed integers, returning a 64 bit result
170 // and a 64 bit remainder
173 // [esp+4], [esp+8] = dividend
174 // [esp+12], [esp+16] = divisor
176 // Return (dividend / divisor) in edx:eax
177 // Return (dividend % divisor) in ebx:ecx
179 // Remove arguments from stack
185 _asm mov eax, [esp+16]
186 _asm mov edx, [esp+20]
187 _asm mov esi, [esp+24]
188 _asm mov edi, [esp+28]
190 _asm jns dividend_nonnegative
194 dividend_nonnegative:
196 _asm jns divisor_nonnegative
202 _asm mov ebp, [esp+20]
204 _asm xor ebp, [esp+28]
207 _asm jns quotient_nonnegative
211 quotient_nonnegative:
212 _asm cmp dword ptr [esp+20], 0
213 _asm jns rem_nonnegative
224 __NAKED__ void _aulldiv()
226 // Divide two 64 bit unsigned integers returning a 64 bit result
228 // [esp+4], [esp+8] = dividend
229 // [esp+12], [esp+16] = divisor
230 // Return result in edx:eax
231 // Remove arguments from stack
238 _asm mov eax, [esp+20]
239 _asm mov edx, [esp+24]
240 _asm mov esi, [esp+28]
241 _asm mov edi, [esp+32]
251 __NAKED__ void _alldiv()
253 // Divide two 64 bit signed integers returning a 64 bit result
255 // [esp+4], [esp+8] = dividend
256 // [esp+12], [esp+16] = divisor
257 // Return result in edx:eax
258 // Remove arguments from stack
265 _asm mov eax, [esp+20]
266 _asm mov edx, [esp+24]
267 _asm mov esi, [esp+28]
268 _asm mov edi, [esp+32]
270 _asm jns dividend_nonnegative
274 dividend_nonnegative:
276 _asm jns divisor_nonnegative
282 _asm mov ecx, [esp+24]
284 _asm xor ecx, [esp+32]
285 _asm jns quotient_nonnegative
289 quotient_nonnegative:
297 __NAKED__ void _aullrem()
299 // Divide two 64 bit unsigned integers and return 64 bit remainder
301 // [esp+4], [esp+8] = dividend
302 // [esp+12], [esp+16] = divisor
303 // Return result in edx:eax
304 // Remove arguments from stack
311 _asm mov eax, [esp+20]
312 _asm mov edx, [esp+24]
313 _asm mov esi, [esp+28]
314 _asm mov edi, [esp+32]
325 __NAKED__ void _allrem()
327 // Divide two 64 bit signed integers and return 64 bit remainder
329 // [esp+4], [esp+8] = dividend
330 // [esp+12], [esp+16] = divisor
331 // Return result in edx:eax
332 // Remove arguments from stack
339 _asm mov eax, [esp+20]
340 _asm mov edx, [esp+24]
341 _asm mov esi, [esp+28]
342 _asm mov edi, [esp+32]
344 _asm jns dividend_nonnegative
348 dividend_nonnegative:
350 _asm jns divisor_nonnegative
358 _asm cmp dword ptr [esp+24], 0
359 _asm jns rem_nonnegative
371 __NAKED__ void _allshr()
373 // Arithmetic shift right EDX:EAX by CL
377 _asm jae asr_count_ge_64
379 _asm jae asr_count_ge_32
380 _asm shrd eax, edx, cl
395 __NAKED__ void _allshl()
397 // shift left EDX:EAX by CL
401 _asm jae lsl_count_ge_64
403 _asm jae lsl_count_ge_32
404 _asm shld edx, eax, cl
419 __NAKED__ void _aullshr()
421 // Logical shift right EDX:EAX by CL
425 _asm jae lsr_count_ge_64
427 _asm jae lsr_count_ge_32
428 _asm shrd eax, edx, cl