]>
Commit | Line | Data |
---|---|---|
878ddf1f | 1 | TITLE Ia32math.asm: Generic math routines for EBC interpreter running on IA32 processor\r |
2 | \r | |
3 | ;------------------------------------------------------------------------------\r | |
4 | ;\r | |
5 | ; Copyright (c) 2006, Intel Corporation \r | |
6 | ; All rights reserved. This program and the accompanying materials \r | |
7 | ; are licensed and made available under the terms and conditions of the BSD License \r | |
8 | ; which accompanies this distribution. The full text of the license may be found at \r | |
9 | ; http://opensource.org/licenses/bsd-license.php \r | |
10 | ; \r | |
11 | ; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r | |
12 | ; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r | |
13 | ; \r | |
14 | ; Module Name:\r | |
15 | ;\r | |
16 | ; Ia32math.asm\r | |
17 | ; \r | |
18 | ; Abstract:\r | |
19 | ; \r | |
20 | ; Generic math routines for EBC interpreter running on IA32 processor\r | |
21 | ;\r | |
22 | ;------------------------------------------------------------------------------\r | |
23 | \r | |
24 | .686P\r | |
25 | .XMM\r | |
26 | .MODEL SMALL\r | |
27 | .CODE\r | |
28 | \r | |
29 | LeftShiftU64 PROTO C Operand: QWORD, CountIn: QWORD\r | |
30 | RightShiftU64 PROTO C Operand: QWORD, CountIn: QWORD\r | |
31 | ARightShift64 PROTO C Operand: QWORD, CountIn: QWORD\r | |
32 | MulU64x64 PROTO C Value1: QWORD, Value2: QWORD, ResultHigh: DWORD\r | |
33 | MulS64x64 PROTO C Value1: QWORD, Value2: QWORD, ResultHigh: DWORD\r | |
34 | DivU64x64 PROTO C Dividend: QWORD, Divisor: QWORD, Remainder: DWORD, Error: DWORD\r | |
35 | DivS64x64 PROTO C Dividend: QWORD, Divisor: QWORD, Remainder: DWORD, Error: DWORD\r | |
36 | \r | |
37 | \r | |
38 | LeftShiftU64 PROC C Operand: QWORD, CountIn: QWORD\r | |
39 | \r | |
40 | ;------------------------------------------------------------------------------\r | |
41 | ; UINT64\r | |
42 | ; LeftShiftU64 (\r | |
43 | ; IN UINT64 Operand,\r | |
44 | ; IN UINT64 CountIn\r | |
45 | ; )\r | |
46 | ;\r | |
47 | ; Routine Description:\r | |
48 | ; \r | |
49 | ; Left-shift a 64-bit value.\r | |
50 | ;\r | |
51 | ; Arguments:\r | |
52 | ;\r | |
53 | ; Operand - the value to shift\r | |
54 | ; Count - shift count\r | |
55 | ;\r | |
56 | ; Returns:\r | |
57 | ;\r | |
58 | ; Operand << Count\r | |
59 | ;------------------------------------------------------------------------------\r | |
60 | \r | |
61 | push ecx\r | |
62 | ;\r | |
63 | ; if (CountIn > 63) return 0;\r | |
64 | ;\r | |
65 | cmp dword ptr CountIn[4], 0\r | |
66 | jne _LeftShiftU64_Overflow\r | |
67 | mov ecx, dword ptr CountIn[0]\r | |
68 | cmp ecx, 63\r | |
69 | jbe _LeftShiftU64_Calc\r | |
70 | \r | |
71 | _LeftShiftU64_Overflow:\r | |
72 | xor eax, eax\r | |
73 | xor edx, edx\r | |
74 | jmp _LeftShiftU64_Done\r | |
75 | \r | |
76 | _LeftShiftU64_Calc:\r | |
77 | mov eax, dword ptr Operand[0]\r | |
78 | mov edx, dword ptr Operand[4]\r | |
79 | \r | |
80 | shld edx, eax, cl\r | |
81 | shl eax, cl\r | |
82 | cmp ecx, 32\r | |
83 | jc short _LeftShiftU64_Done\r | |
84 | \r | |
85 | mov edx, eax\r | |
86 | xor eax, eax\r | |
87 | \r | |
88 | _LeftShiftU64_Done:\r | |
89 | pop ecx\r | |
90 | ret\r | |
91 | \r | |
92 | LeftShiftU64 ENDP\r | |
93 | \r | |
94 | \r | |
95 | RightShiftU64 PROC C Operand: QWORD, CountIn: QWORD\r | |
96 | \r | |
97 | ;------------------------------------------------------------------------------\r | |
98 | ; UINT64\r | |
99 | ; RightShiftU64 (\r | |
100 | ; IN UINT64 Operand,\r | |
101 | ; IN UINT64 CountIn\r | |
102 | ; )\r | |
103 | ;\r | |
104 | ; Routine Description:\r | |
105 | ; \r | |
106 | ; Right-shift an unsigned 64-bit value.\r | |
107 | ;\r | |
108 | ; Arguments:\r | |
109 | ;\r | |
110 | ; Operand - the value to shift\r | |
111 | ; Count - shift count\r | |
112 | ;\r | |
113 | ; Returns:\r | |
114 | ;\r | |
115 | ; Operand >> Count\r | |
116 | ;------------------------------------------------------------------------------\r | |
117 | \r | |
118 | push ecx\r | |
119 | ;\r | |
120 | ; if (CountIn > 63) return 0;\r | |
121 | ;\r | |
122 | cmp dword ptr CountIn[4], 0\r | |
123 | jne _RightShiftU64_Overflow\r | |
124 | mov ecx, dword ptr CountIn[0]\r | |
125 | cmp ecx, 63\r | |
126 | jbe _RightShiftU64_Calc\r | |
127 | \r | |
128 | _RightShiftU64_Overflow:\r | |
129 | xor eax, eax\r | |
130 | xor edx, edx\r | |
131 | jmp _RightShiftU64_Done\r | |
132 | \r | |
133 | _RightShiftU64_Calc:\r | |
134 | mov eax, dword ptr Operand[0]\r | |
135 | mov edx, dword ptr Operand[4]\r | |
136 | \r | |
28c73f6e | 137 | shrd eax, edx, cl\r |
138 | shr edx, cl\r | |
878ddf1f | 139 | cmp ecx, 32\r |
140 | jc short _RightShiftU64_Done\r | |
141 | \r | |
142 | mov eax, edx\r | |
143 | xor edx, edx\r | |
144 | \r | |
145 | _RightShiftU64_Done:\r | |
146 | pop ecx\r | |
147 | ret\r | |
148 | \r | |
149 | RightShiftU64 ENDP\r | |
150 | \r | |
151 | \r | |
152 | ARightShift64 PROC C Operand: QWORD, CountIn: QWORD\r | |
153 | \r | |
154 | ;------------------------------------------------------------------------------\r | |
155 | ; INT64\r | |
156 | ; ARightShift64 (\r | |
157 | ; IN INT64 Operand,\r | |
158 | ; IN UINT64 CountIn\r | |
159 | ; )\r | |
160 | ;\r | |
161 | ; Routine Description:\r | |
162 | ; \r | |
163 | ; Arithmatic shift a 64 bit signed value.\r | |
164 | ;\r | |
165 | ; Arguments:\r | |
166 | ;\r | |
167 | ; Operand - the value to shift\r | |
168 | ; Count - shift count\r | |
169 | ;\r | |
170 | ; Returns:\r | |
171 | ;\r | |
172 | ; Operand >> Count\r | |
173 | ;------------------------------------------------------------------------------\r | |
174 | \r | |
175 | push ecx\r | |
176 | ;\r | |
177 | ; If they exceeded the max shift count, then return either 0 or all F's\r | |
178 | ; depending on the sign bit.\r | |
179 | ;\r | |
180 | cmp dword ptr CountIn[4], 0\r | |
181 | jne _ARightShiftU64_Overflow\r | |
182 | mov ecx, dword ptr CountIn[0]\r | |
183 | cmp ecx, 63\r | |
184 | jbe _ARightShiftU64_Calc\r | |
185 | \r | |
186 | _ARightShiftU64_Overflow:\r | |
187 | ;\r | |
188 | ; Check the sign bit of Operand\r | |
189 | ;\r | |
190 | bt dword ptr Operand[4], 31\r | |
191 | jnc _ARightShiftU64_Return_Zero\r | |
192 | ;\r | |
193 | ; return -1\r | |
194 | ;\r | |
195 | or eax, 0FFFFFFFFh\r | |
196 | or edx, 0FFFFFFFFh\r | |
197 | jmp _ARightShiftU64_Done\r | |
198 | \r | |
199 | _ARightShiftU64_Return_Zero:\r | |
200 | xor eax, eax\r | |
201 | xor edx, edx\r | |
202 | jmp _ARightShiftU64_Done\r | |
203 | \r | |
204 | _ARightShiftU64_Calc:\r | |
205 | mov eax, dword ptr Operand[0]\r | |
206 | mov edx, dword ptr Operand[4]\r | |
207 | \r | |
208 | shrd eax, edx, cl\r | |
209 | sar edx, cl\r | |
210 | cmp ecx, 32\r | |
211 | jc short _ARightShiftU64_Done\r | |
212 | \r | |
213 | ;\r | |
214 | ; if ecx >= 32, then eax = edx, and edx = sign bit\r | |
215 | ;\r | |
216 | mov eax, edx\r | |
217 | sar edx, 31\r | |
218 | \r | |
219 | _ARightShiftU64_Done:\r | |
220 | pop ecx\r | |
221 | ret\r | |
222 | \r | |
223 | ARightShift64 ENDP\r | |
224 | \r | |
225 | \r | |
226 | MulU64x64 PROC C Value1: QWORD, Value2: QWORD, ResultHigh: DWORD\r | |
227 | \r | |
228 | ;------------------------------------------------------------------------------\r | |
229 | ; UINT64 \r | |
230 | ; MulU64x64 (\r | |
231 | ; UINT64 Value1, \r | |
232 | ; UINT64 Value2, \r | |
233 | ; UINT64 *ResultHigh\r | |
234 | ; )\r | |
235 | ;\r | |
236 | ; Routine Description:\r | |
237 | ; \r | |
238 | ; Multiply two unsigned 64-bit values.\r | |
239 | ;\r | |
240 | ; Arguments:\r | |
241 | ;\r | |
242 | ; Value1 - first value to multiply\r | |
243 | ; Value2 - value to multiply by Value1\r | |
244 | ; ResultHigh - result to flag overflows\r | |
245 | ;\r | |
246 | ; Returns:\r | |
247 | ; \r | |
248 | ; Value1 * Value2\r | |
249 | ; The 128-bit result is the concatenation of *ResultHigh and the return value \r | |
250 | ;------------------------------------------------------------------------------\r | |
251 | \r | |
252 | push ebx\r | |
253 | push ecx\r | |
254 | mov ebx, ResultHigh ; ebx points to the high 4 words of result\r | |
255 | ;\r | |
256 | ; The result consists of four double-words.\r | |
257 | ; Here we assume their names from low to high: dw0, dw1, dw2, dw3\r | |
258 | ;\r | |
259 | mov eax, dword ptr Value1[0]\r | |
260 | mul dword ptr Value2[0]\r | |
261 | push eax ; eax contains final result of dw0, push it\r | |
262 | mov ecx, edx ; ecx contains partial result of dw1\r | |
263 | \r | |
264 | mov eax, dword ptr Value1[4]\r | |
265 | mul dword ptr Value2[0]\r | |
266 | add ecx, eax ; add eax to partial result of dw1\r | |
267 | adc edx, 0 \r | |
268 | mov dword ptr [ebx], edx ; lower double-word of ResultHigh contains partial result of dw2\r | |
269 | \r | |
270 | mov eax, dword ptr Value1[0]\r | |
271 | mul dword ptr Value2[4]\r | |
272 | add ecx, eax ; add eax to partial result of dw1\r | |
273 | push ecx ; ecx contains final result of dw1, push it\r | |
274 | adc edx, 0\r | |
275 | mov ecx, edx ; ecx contains partial result of dw2, together with ResultHigh\r | |
276 | \r | |
277 | mov eax, dword ptr Value1[4]\r | |
278 | mul dword ptr Value2[4]\r | |
279 | add ecx, eax ; add eax to partial result of dw2\r | |
280 | adc edx, 0\r | |
281 | add dword ptr [ebx], ecx ; lower double-word of ResultHigh contains final result of dw2\r | |
282 | adc edx, 0\r | |
283 | mov dword ptr [ebx + 4], edx ; high double-word of ResultHigh contains final result of dw3\r | |
284 | \r | |
285 | pop edx ; edx contains the final result of dw1\r | |
286 | pop eax ; edx contains the final result of dw0\r | |
287 | pop ecx\r | |
288 | pop ebx\r | |
289 | ret\r | |
290 | \r | |
291 | MulU64x64 ENDP\r | |
292 | \r | |
293 | \r | |
294 | MulS64x64 PROC C Value1: QWORD, Value2: QWORD, ResultHigh: DWORD\r | |
295 | \r | |
296 | ;------------------------------------------------------------------------------\r | |
297 | ; INT64\r | |
298 | ; MulS64x64 (\r | |
299 | ; INT64 Value1,\r | |
300 | ; INT64 Value2,\r | |
301 | ; INT64 *ResultHigh\r | |
302 | ; )\r | |
303 | ;\r | |
304 | ; Routine Description:\r | |
305 | ; \r | |
306 | ; Multiply two signed 64-bit values.\r | |
307 | ;\r | |
308 | ; Arguments:\r | |
309 | ;\r | |
310 | ; Value1 - first value to multiply\r | |
311 | ; Value2 - value to multiply by Value1\r | |
312 | ; ResultHigh - result to flag overflows\r | |
313 | ;\r | |
314 | ; Returns:\r | |
315 | ;\r | |
316 | ; Value1 * Value2\r | |
317 | ; The 128-bit result is the concatenation of *ResultHigh and the return value \r | |
318 | ;------------------------------------------------------------------------------\r | |
319 | \r | |
320 | push ebx\r | |
321 | push ecx\r | |
322 | mov ebx, ResultHigh ; ebx points to the high 4 words of result\r | |
323 | xor ecx, ecx ; the lowest bit of ecx flags the sign\r | |
324 | \r | |
325 | mov edx, dword ptr Value1[4]\r | |
326 | bt edx, 31\r | |
327 | jnc short _MulS64x64_A_Positive\r | |
328 | ;\r | |
329 | ; a is negative\r | |
330 | ;\r | |
331 | mov eax, dword ptr Value1[0]\r | |
332 | not edx\r | |
333 | not eax\r | |
334 | add eax, 1\r | |
335 | adc edx, 0\r | |
336 | mov dword ptr Value1[0], eax\r | |
337 | mov dword ptr Value1[4], edx\r | |
338 | btc ecx, 0\r | |
339 | \r | |
340 | _MulS64x64_A_Positive:\r | |
341 | mov edx, dword ptr Value2[4]\r | |
342 | bt edx, 31\r | |
343 | jnc short _MulS64x64_B_Positive\r | |
344 | ;\r | |
345 | ; b is negative\r | |
346 | ;\r | |
347 | mov eax, dword ptr Value2[0]\r | |
348 | not edx\r | |
349 | not eax\r | |
350 | add eax, 1\r | |
351 | adc edx, 0\r | |
352 | mov dword ptr Value2[0], eax\r | |
353 | mov dword ptr Value2[4], edx\r | |
354 | btc ecx, 0\r | |
355 | \r | |
356 | _MulS64x64_B_Positive:\r | |
357 | invoke MulU64x64, Value1, Value2, ResultHigh\r | |
358 | bt ecx, 0\r | |
359 | jnc short _MulS64x64_Done\r | |
360 | ;\r | |
361 | ;negate the result\r | |
362 | ;\r | |
363 | not eax\r | |
364 | not edx\r | |
365 | not dword ptr [ebx]\r | |
366 | not dword ptr [ebx + 4]\r | |
367 | add eax, 1\r | |
368 | adc edx, 0\r | |
369 | adc dword ptr [ebx], 0\r | |
370 | adc dword ptr [ebx + 4], 0\r | |
371 | \r | |
372 | _MulS64x64_Done:\r | |
373 | pop ecx\r | |
374 | pop ebx\r | |
375 | ret\r | |
376 | \r | |
377 | MulS64x64 ENDP\r | |
378 | \r | |
379 | \r | |
380 | DivU64x64 PROC C Dividend: QWORD, Divisor: QWORD, Remainder: DWORD, Error: DWORD, \r | |
381 | \r | |
382 | ;------------------------------------------------------------------------------\r | |
383 | ; UINT64\r | |
384 | ; DivU64x64 (\r | |
385 | ; IN UINT64 Dividend,\r | |
386 | ; IN UINT64 Divisor,\r | |
387 | ; OUT UINT64 *Remainder OPTIONAL,\r | |
388 | ; OUT UINT32 *Error\r | |
389 | ; )\r | |
390 | ;\r | |
391 | ; Routine Description:\r | |
392 | ; \r | |
393 | ; This routine allows a 64 bit value to be divided with a 64 bit value returns \r | |
394 | ; 64bit result and the Remainder\r | |
395 | ;\r | |
396 | ; Arguments:\r | |
397 | ;\r | |
398 | ; Dividend - dividend\r | |
399 | ; Divisor - divisor\r | |
400 | ; ResultHigh - result to flag overflows\r | |
401 | ; Error - flag for error\r | |
402 | ;\r | |
403 | ; Returns:\r | |
404 | ; \r | |
405 | ; Dividend / Divisor\r | |
406 | ; Remainder = Dividend mod Divisor\r | |
407 | ;------------------------------------------------------------------------------\r | |
408 | \r | |
409 | push ecx\r | |
410 | \r | |
411 | mov eax, Error\r | |
412 | mov dword ptr [eax], 0 \r | |
413 | \r | |
414 | cmp dword ptr Divisor[0], 0\r | |
415 | jne _DivU64x64_Valid\r | |
416 | cmp dword ptr Divisor[4], 0\r | |
417 | jne _DivU64x64_Valid\r | |
418 | ;\r | |
419 | ; the divisor is zero\r | |
420 | ;\r | |
421 | mov dword ptr [eax], 1 \r | |
422 | cmp Remainder, 0\r | |
423 | je _DivU64x64_Invalid_Return\r | |
424 | ;\r | |
425 | ; fill the remainder if the pointer is not null\r | |
426 | ;\r | |
427 | mov eax, Remainder\r | |
428 | mov dword ptr [eax], 0\r | |
429 | mov dword ptr [eax + 4], 80000000h\r | |
430 | \r | |
431 | _DivU64x64_Invalid_Return:\r | |
432 | xor eax, eax\r | |
433 | mov edx, 80000000h\r | |
434 | jmp _DivU64x64_Done\r | |
435 | \r | |
436 | _DivU64x64_Valid:\r | |
437 | ;\r | |
438 | ; let edx and eax contain the intermediate result of remainder\r | |
439 | ;\r | |
440 | xor edx, edx\r | |
441 | xor eax, eax\r | |
442 | mov ecx, 64\r | |
443 | \r | |
444 | _DivU64x64_Wend:\r | |
445 | ;\r | |
446 | ; shift dividend left one\r | |
447 | ;\r | |
448 | shl dword ptr Dividend[0], 1\r | |
449 | rcl dword ptr Dividend[4], 1 \r | |
450 | ;\r | |
451 | ; rotate intermediate result of remainder left one\r | |
452 | ;\r | |
453 | rcl eax, 1\r | |
454 | rcl edx, 1 \r | |
455 | \r | |
456 | cmp edx, dword ptr Divisor[4]\r | |
457 | ja _DivU64x64_Sub_Divisor\r | |
458 | jb _DivU64x64_Cont\r | |
459 | cmp eax, dword ptr Divisor[0]\r | |
460 | jb _DivU64x64_Cont\r | |
461 | \r | |
462 | _DivU64x64_Sub_Divisor:\r | |
463 | ;\r | |
464 | ; If intermediate result of remainder is larger than\r | |
465 | ; or equal to divisor, then set the lowest bit of dividend,\r | |
466 | ; and subtract divisor from intermediate remainder\r | |
467 | ;\r | |
468 | bts dword ptr Dividend[0], 0\r | |
469 | sub eax, dword ptr Divisor[0]\r | |
470 | sbb edx, dword ptr Divisor[4]\r | |
471 | \r | |
472 | _DivU64x64_Cont:\r | |
473 | loop _DivU64x64_Wend\r | |
474 | \r | |
475 | cmp Remainder, 0\r | |
476 | je _DivU64x64_Assign\r | |
477 | mov ecx, Remainder\r | |
478 | mov dword ptr [ecx], eax\r | |
479 | mov dword ptr [ecx + 4], edx\r | |
480 | \r | |
481 | _DivU64x64_Assign:\r | |
482 | mov eax, dword ptr Dividend[0]\r | |
483 | mov edx, dword ptr Dividend[4]\r | |
484 | \r | |
485 | _DivU64x64_Done:\r | |
486 | pop ecx\r | |
487 | ret\r | |
488 | \r | |
489 | DivU64x64 ENDP\r | |
490 | \r | |
491 | DivS64x64 PROC C Dividend: QWORD, Divisor: QWORD, Remainder: DWORD, Error: DWORD, \r | |
492 | \r | |
493 | ;------------------------------------------------------------------------------\r | |
494 | ; INT64\r | |
495 | ; DivU64x64 (\r | |
496 | ; IN INT64 Dividend,\r | |
497 | ; IN INT64 Divisor,\r | |
498 | ; OUT UINT64 *Remainder OPTIONAL,\r | |
499 | ; OUT UINT32 *Error\r | |
500 | ; )\r | |
501 | ;\r | |
502 | ; Routine Description:\r | |
503 | ; \r | |
504 | ; This routine allows a 64 bit signed value to be divided with a 64 bit \r | |
505 | ; signed value returns 64bit result and the Remainder.\r | |
506 | ;\r | |
507 | ; Arguments:\r | |
508 | ;\r | |
509 | ; Dividend - dividend\r | |
510 | ; Divisor - divisor\r | |
511 | ; ResultHigh - result to flag overflows\r | |
512 | ; Error - flag for error\r | |
513 | ;\r | |
514 | ; Returns:\r | |
515 | ; \r | |
516 | ; Dividend / Divisor\r | |
517 | ; Remainder = Dividend mod Divisor\r | |
518 | ;------------------------------------------------------------------------------\r | |
519 | \r | |
520 | push ecx\r | |
521 | \r | |
522 | mov eax, Error\r | |
523 | mov dword ptr [eax], 0 \r | |
524 | \r | |
525 | cmp dword ptr Divisor[0], 0\r | |
526 | jne _DivS64x64_Valid\r | |
527 | cmp dword ptr Divisor[4], 0\r | |
528 | jne _DivS64x64_Valid\r | |
529 | ;\r | |
530 | ; the divisor is zero\r | |
531 | ;\r | |
532 | mov dword ptr [eax], 1 \r | |
533 | cmp Remainder, 0\r | |
534 | je _DivS64x64_Invalid_Return\r | |
535 | ;\r | |
536 | ; fill the remainder if the pointer is not null\r | |
537 | ;\r | |
538 | mov eax, Remainder\r | |
539 | mov dword ptr [eax], 0\r | |
540 | mov dword ptr [eax + 4], 80000000h\r | |
541 | \r | |
542 | _DivS64x64_Invalid_Return:\r | |
543 | xor eax, eax\r | |
544 | mov edx, 80000000h\r | |
545 | jmp _DivS64x64_Done\r | |
546 | \r | |
547 | _DivS64x64_Valid:\r | |
548 | ;\r | |
549 | ; The lowest bit of ecx flags the sign of quotient,\r | |
550 | ; The seconde lowest bit flags the sign of remainder\r | |
551 | ;\r | |
552 | xor ecx, ecx \r | |
553 | \r | |
554 | mov edx, dword ptr Dividend[4]\r | |
555 | bt edx, 31\r | |
556 | jnc short _DivS64x64_Dividend_Positive\r | |
557 | ;\r | |
558 | ; dividend is negative\r | |
559 | ;\r | |
560 | mov eax, dword ptr Dividend[0]\r | |
561 | not edx\r | |
562 | not eax\r | |
563 | add eax, 1\r | |
564 | adc edx, 0\r | |
565 | mov dword ptr Dividend[0], eax\r | |
566 | mov dword ptr Dividend[4], edx\r | |
567 | ;\r | |
568 | ; set both the flags for signs of quotient and remainder\r | |
569 | ;\r | |
570 | btc ecx, 0\r | |
571 | btc ecx, 1\r | |
572 | \r | |
573 | _DivS64x64_Dividend_Positive:\r | |
574 | mov edx, dword ptr Divisor[4]\r | |
575 | bt edx, 31\r | |
576 | jnc short _DivS64x64_Divisor_Positive\r | |
577 | ;\r | |
578 | ; divisor is negative\r | |
579 | ;\r | |
580 | mov eax, dword ptr Divisor[0]\r | |
581 | not edx\r | |
582 | not eax\r | |
583 | add eax, 1\r | |
584 | adc edx, 0\r | |
585 | mov dword ptr Divisor[0], eax\r | |
586 | mov dword ptr Divisor[4], edx\r | |
587 | ;\r | |
588 | ; just complement the flag for sign of quotient\r | |
589 | ;\r | |
590 | btc ecx, 0\r | |
591 | \r | |
592 | _DivS64x64_Divisor_Positive:\r | |
593 | invoke DivU64x64, Dividend, Divisor, Remainder, Error\r | |
594 | bt ecx, 0\r | |
595 | jnc short _DivS64x64_Remainder\r | |
596 | ;\r | |
597 | ; negate the quotient\r | |
598 | ;\r | |
599 | not eax\r | |
600 | not edx\r | |
601 | add eax, 1\r | |
602 | adc edx, 0\r | |
603 | \r | |
604 | _DivS64x64_Remainder:\r | |
605 | bt ecx, 1\r | |
606 | jnc short _DivS64x64_Done\r | |
607 | ;\r | |
608 | ; negate the remainder\r | |
609 | ;\r | |
610 | mov ecx, remainder\r | |
611 | not dword ptr [ecx]\r | |
612 | not dword ptr [ecx + 4]\r | |
613 | add dword ptr [ecx], 1\r | |
614 | adc dword ptr [ecx + 4], 0\r | |
615 | \r | |
616 | _DivS64x64_Done:\r | |
617 | pop ecx\r | |
618 | ret\r | |
619 | \r | |
620 | DivS64x64 ENDP\r | |
621 | \r | |
622 | END |