VirtualBox

source: vbox/trunk/include/iprt/asm-watcom-x86-16.h@ 69010

Last change on this file since 69010 was 68606, checked in by vboxsync, 7 years ago

iprt/asm*: Made the code safe to use with 16-bit code models employing near data pointers (i.e. adding RT_FAR to all pointers).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 21.6 KB
Line 
1/** @file
2 * IPRT - Assembly Functions, x86 16-bit Watcom C/C++ pragma aux.
3 */
4
5/*
6 * Copyright (C) 2006-2016 Oracle Corporation
7 *
8 * This file is part of VirtualBox Open Source Edition (OSE), as
9 * available from http://www.virtualbox.org. This file is free software;
10 * you can redistribute it and/or modify it under the terms of the GNU
11 * General Public License (GPL) as published by the Free Software
12 * Foundation, in version 2 as it comes in the "COPYING" file of the
13 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
15 *
16 * The contents of this file may alternatively be used under the terms
17 * of the Common Development and Distribution License Version 1.0
18 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
19 * VirtualBox OSE distribution, in which case the provisions of the
20 * CDDL are applicable instead of those of the GPL.
21 *
22 * You may elect to license modified versions of this file under the
23 * terms and conditions of either the GPL or the CDDL or both.
24 */
25
26#ifndef ___iprt_asm_h
27# error "Don't include this header directly."
28#endif
29#ifndef ___iprt_asm_watcom_x86_16_h
30#define ___iprt_asm_watcom_x86_16_h
31
32
33/*
34 * Turns out we cannot use 'ds' for segment stuff here because the compiler
35 * seems to insists on loading the DGROUP segment into 'ds' before calling
36 * stuff when using -ecc. Using 'es' instead as this seems to work fine.
37 *
38 * Note! The #undef that preceds the #pragma aux statements is for undoing
39 * the mangling, because the symbol in #pragma aux [symbol] statements
40 * doesn't get subjected to preprocessing. This is also why we include
41 * the watcom header at the top rather than at the bottom of the
42 * asm-amd64-x86.h file.
43 */
44
45#undef ASMCompilerBarrier
46#if 0 /* overkill version. */
47# pragma aux ASMCompilerBarrier = \
48 "nop" \
49 parm [] \
50 modify exact [ax bx cx dx es ds];
51#else
52# pragma aux ASMCompilerBarrier = \
53 "" \
54 parm [] \
55 modify exact [];
56#endif
57
58#undef ASMNopPause
59#pragma aux ASMNopPause = \
60 ".686p" \
61 ".xmm2" \
62 "pause" \
63 parm [] nomemory \
64 modify exact [] nomemory;
65
66#undef ASMAtomicXchgU8
67#pragma aux ASMAtomicXchgU8 = \
68 "xchg es:[bx], al" \
69 parm [es bx] [al] \
70 value [al] \
71 modify exact [al];
72
73#undef ASMAtomicXchgU16
74#pragma aux ASMAtomicXchgU16 = \
75 "xchg es:[bx], ax" \
76 parm [es bx] [ax] \
77 value [ax] \
78 modify exact [ax];
79
80#undef ASMAtomicXchgU32
81#pragma aux ASMAtomicXchgU32 = \
82 ".386" \
83 "shl ecx, 16" \
84 "mov cx, ax" \
85 "xchg es:[bx], ecx" \
86 "mov eax, ecx" \
87 "shr ecx, 16" \
88 parm [es bx] [ax cx] \
89 value [ax cx] \
90 modify exact [ax cx];
91
92#undef ASMAtomicXchgU64
93#pragma aux ASMAtomicXchgU64 = \
94 ".586" \
95 "shl eax, 16" \
96 "mov ax, bx" /* eax = high dword */ \
97 "shl ecx, 16" \
98 "mov cx, dx" /* ecx = low dword */ \
99 "mov ebx, ecx" /* ebx = low */ \
100 "mov ecx, eax" /* ecx = high */ \
101 "try_again:" \
102 "lock cmpxchg8b es:[si]" \
103 "jnz try_again" \
104 "xchg eax, edx" \
105 "mov ebx, eax" \
106 "shr eax, 16" \
107 "mov ecx, edx" \
108 "shr ecx, 16" \
109 parm [es si] [dx cx bx ax] \
110 value [dx cx bx ax] \
111 modify exact [dx cx bx ax];
112
113#undef ASMAtomicCmpXchgU8
114#pragma aux ASMAtomicCmpXchgU8 = \
115 ".486" \
116 "lock cmpxchg es:[bx], cl" \
117 "setz al" \
118 parm [es bx] [cl] [al] \
119 value [al] \
120 modify exact [al];
121
122#undef ASMAtomicCmpXchgU16
123#pragma aux ASMAtomicCmpXchgU16 = \
124 ".486" \
125 "lock cmpxchg es:[bx], cx" \
126 "setz al" \
127 parm [es bx] [cx] [ax] \
128 value [al] \
129 modify exact [ax];
130
131#undef ASMAtomicCmpXchgU32
132#pragma aux ASMAtomicCmpXchgU32 = \
133 ".486" \
134 "shl ecx, 16" \
135 "mov cx, dx" \
136 "shl eax, 16" \
137 "mov ax, di" \
138 "rol eax, 16" \
139 "lock cmpxchg es:[bx], ecx" \
140 "setz al" \
141 parm [es bx] [cx dx] [ax di] \
142 value [al] \
143 modify exact [ax cx];
144
145/* ASMAtomicCmpXchgU64: External assembly implementation, too few registers for parameters. */
146/* ASMAtomicCmpXchgExU32: External assembly implementation, too few registers for parameters. */
147/* ASMAtomicCmpXchgExU64: External assembly implementation, too few registers for parameters. */
148
149#undef ASMSerializeInstructionCpuId
150#pragma aux ASMSerializeInstructionCpuId = \
151 ".586" \
152 "xor eax, eax" \
153 "cpuid" \
154 parm [] \
155 modify exact [ax bx cx dx];
156
157#undef ASMSerializeInstructionIRet
158#pragma aux ASMSerializeInstructionIRet = \
159 "pushf" \
160 "push cs" \
161 "call foo" /* 'push offset done' doesn't work */ \
162 "jmp done" \
163 "foo:" \
164 "iret" \
165 "done:" \
166 parm [] \
167 modify exact [];
168
169#undef ASMSerializeInstructionRdTscp
170#pragma aux ASMSerializeInstructionRdTscp = \
171 0x0f 0x01 0xf9 \
172 parm [] \
173 modify exact [ax dx cx];
174
175#undef ASMAtomicReadU64
176#pragma aux ASMAtomicReadU64 = \
177 ".586" \
178 "xor eax, eax" \
179 "xor edx, edx" \
180 "xor ebx, ebx" \
181 "xor ecx, ecx" \
182 "lock cmpxchg8b es:[si]" \
183 "xchg eax, edx" \
184 "mov ebx, eax" \
185 "shr eax, 16" \
186 "mov ecx, edx" \
187 "shr ecx, 16" \
188 parm [es si] \
189 value [dx cx bx ax] \
190 modify exact [dx cx bx ax];
191
192#undef ASMAtomicUoReadU64
193#pragma aux ASMAtomicUoReadU64 = \
194 ".586" \
195 "xor eax, eax" \
196 "xor edx, edx" \
197 "xor ebx, ebx" \
198 "xor ecx, ecx" \
199 "lock cmpxchg8b es:[si]" \
200 "xchg eax, edx" \
201 "mov ebx, eax" \
202 "shr eax, 16" \
203 "mov ecx, edx" \
204 "shr ecx, 16" \
205 parm [es si] \
206 value [dx cx bx ax] \
207 modify exact [dx cx bx ax];
208
209#undef ASMAtomicAddU16
210#pragma aux ASMAtomicAddU16 = \
211 ".486" \
212 "lock xadd es:[bx], ax" \
213 parm [es bx] [ax] \
214 value [ax] \
215 modify exact [ax];
216
217#undef ASMAtomicAddU32
218#pragma aux ASMAtomicAddU32 = \
219 ".486" \
220 "shl edx, 16" \
221 "mov dx, ax" \
222 "lock xadd es:[bx], edx" \
223 "mov ax, dx" \
224 "shr edx, 16" \
225 parm [es bx] [ax dx] \
226 value [ax dx] \
227 modify exact [ax dx];
228
229#undef ASMAtomicIncU16
230#pragma aux ASMAtomicIncU16 = \
231 ".486" \
232 "mov ax, 1" \
233 "lock xadd es:[bx], ax" \
234 "inc ax" \
235 parm [es bx] \
236 value [ax] \
237 modify exact [ax];
238
239#undef ASMAtomicIncU32
240#pragma aux ASMAtomicIncU32 = \
241 ".486" \
242 "mov edx, 1" \
243 "lock xadd es:[bx], edx" \
244 "inc edx" \
245 "mov ax, dx" \
246 "shr edx, 16" \
247 parm [es bx] \
248 value [ax dx] \
249 modify exact [ax dx];
250
251/* ASMAtomicIncU64: Should be done by C inline or in external file. */
252
253#undef ASMAtomicDecU16
254#pragma aux ASMAtomicDecU16 = \
255 ".486" \
256 "mov ax, 0ffffh" \
257 "lock xadd es:[bx], ax" \
258 "dec ax" \
259 parm [es bx] \
260 value [ax] \
261 modify exact [ax];
262
263#undef ASMAtomicDecU32
264#pragma aux ASMAtomicDecU32 = \
265 ".486" \
266 "mov edx, 0ffffffffh" \
267 "lock xadd es:[bx], edx" \
268 "dec edx" \
269 "mov ax, dx" \
270 "shr edx, 16" \
271 parm [es bx] \
272 value [ax dx] \
273 modify exact [ax dx];
274
275/* ASMAtomicDecU64: Should be done by C inline or in external file. */
276
277#undef ASMAtomicOrU32
278#pragma aux ASMAtomicOrU32 = \
279 ".386" \
280 "shl edx, 16" \
281 "mov dx, ax" \
282 "lock or es:[bx], edx" \
283 parm [es bx] [ax dx] \
284 modify exact [dx];
285
286/* ASMAtomicOrU64: Should be done by C inline or in external file. */
287
288#undef ASMAtomicAndU32
289#pragma aux ASMAtomicAndU32 = \
290 ".386" \
291 "shl edx, 16" \
292 "mov dx, ax" \
293 "lock and es:[bx], edx" \
294 parm [es bx] [ax dx] \
295 modify exact [dx];
296
297/* ASMAtomicAndU64: Should be done by C inline or in external file. */
298
299#undef ASMAtomicUoOrU32
300#pragma aux ASMAtomicUoOrU32 = \
301 ".386" \
302 "shl edx, 16" \
303 "mov dx, ax" \
304 "or es:[bx], edx" \
305 parm [es bx] [ax dx] \
306 modify exact [dx];
307
308/* ASMAtomicUoOrU64: Should be done by C inline or in external file. */
309
310#undef ASMAtomicUoAndU32
311#pragma aux ASMAtomicUoAndU32 = \
312 ".386" \
313 "shl edx, 16" \
314 "mov dx, ax" \
315 "and es:[bx], edx" \
316 parm [es bx] [ax dx] \
317 modify exact [dx];
318
319/* ASMAtomicUoAndU64: Should be done by C inline or in external file. */
320
321#undef ASMAtomicUoIncU32
322#pragma aux ASMAtomicUoIncU32 = \
323 ".486" \
324 "mov edx, 1" \
325 "xadd es:[bx], edx" \
326 "inc edx" \
327 "mov ax, dx" \
328 "shr edx, 16" \
329 parm [es bx] \
330 value [ax dx] \
331 modify exact [ax dx];
332
333#undef ASMAtomicUoDecU32
334#pragma aux ASMAtomicUoDecU32 = \
335 ".486" \
336 "mov edx, 0ffffffffh" \
337 "xadd es:[bx], edx" \
338 "dec edx" \
339 "mov ax, dx" \
340 "shr edx, 16" \
341 parm [es bx] \
342 value [ax dx] \
343 modify exact [ax dx];
344
345#undef ASMMemZeroPage
346#if defined(__SW_0) || defined(__SW_1) || defined(__SW_2)
347# pragma aux ASMMemZeroPage = \
348 "mov cx, 2048" \
349 "xor ax, ax" \
350 "rep stosw" \
351 parm [es di] \
352 modify exact [ax cx di];
353#else
354# pragma aux ASMMemZeroPage = \
355 "mov ecx, 1024" \
356 "xor eax, eax" \
357 "rep stosd" \
358 parm [es di] \
359 modify exact [ax cx di];
360#endif
361
362#undef ASMMemZero32
363#if defined(__SW_0) || defined(__SW_1) || defined(__SW_2)
364# pragma aux ASMMemZero32 = \
365 "xor ax, ax" \
366 "shr cx, 1" \
367 "shr cx, 1" \
368 "rep stosw" \
369 parm [es di] [cx] \
370 modify exact [ax dx cx di];
371#else
372# pragma aux ASMMemZero32 = \
373 "and ecx, 0ffffh" /* probably not necessary, lazy bird should check... */ \
374 "shr ecx, 2" \
375 "xor eax, eax" \
376 "rep stosd" \
377 parm [es di] [cx] \
378 modify exact [ax cx di];
379#endif
380
381#undef ASMMemFill32
382#if defined(__SW_0) || defined(__SW_1) || defined(__SW_2)
383# pragma aux ASMMemFill32 = \
384 " shr cx, 1" \
385 " shr cx, 1" \
386 " jz done" \
387 "again:" \
388 " stosw" \
389 " xchg ax, dx" \
390 " stosw" \
391 " xchg ax, dx" \
392 " dec cx" \
393 " jnz again" \
394 "done:" \
395 parm [es di] [cx] [ax dx]\
396 modify exact [cx di];
397#else
398# pragma aux ASMMemFill32 = \
399 "and ecx, 0ffffh" /* probably not necessary, lazy bird should check... */ \
400 "shr ecx, 2" \
401 "shl eax, 16" \
402 "mov ax, dx" \
403 "rol eax, 16" \
404 "rep stosd" \
405 parm [es di] [cx] [ax dx]\
406 modify exact [ax cx di];
407#endif
408
409#undef ASMProbeReadByte
410#pragma aux ASMProbeReadByte = \
411 "mov al, es:[bx]" \
412 parm [es bx] \
413 value [al] \
414 modify exact [al];
415
416#undef ASMBitSet
417#if defined(__SW_0) || defined(__SW_1) || defined(__SW_2)
418# pragma aux ASMBitSet = \
419 " mov ch, cl" /* Only the three lowest bits are relevant due to 64KB segments */ \
420 " mov cl, 5" \
421 " shl ch, cl" \
422 " add bh, ch" /* Adjust the pointer. */ \
423 " mov cl, al" \
424 " shr ax, 1" /* convert to byte offset */ \
425 " shr ax, 1" \
426 " shr ax, 1" \
427 " add bx, ax" /* adjust pointer again */\
428 " and cl, 7" \
429 " mov al, 1" \
430 " shl al, cl" /* al=bitmask */ \
431 " or es:[bx], al" \
432 parm [es bx] [ax cx] \
433 modify exact [ax bx cx];
434#else
435# pragma aux ASMBitSet = \
436 "shl edx, 16" \
437 "mov dx, ax" \
438 "bts es:[bx], edx" \
439 parm [es bx] [ax dx] \
440 modify exact [dx];
441#endif
442
443#undef ASMAtomicBitSet
444#pragma aux ASMAtomicBitSet = \
445 ".386" \
446 "shl edx, 16" \
447 "mov dx, ax" \
448 "lock bts es:[bx], edx" \
449 parm [es bx] [ax dx] \
450 modify exact [dx];
451
452#undef ASMBitClear
453#if defined(__SW_0) || defined(__SW_1) || defined(__SW_2)
454# pragma aux ASMBitClear = \
455 " mov ch, cl" /* Only the three lowest bits are relevant due to 64KB segments */ \
456 " mov cl, 5" \
457 " shl ch, cl" \
458 " add bh, ch" /* Adjust the pointer. */ \
459 " mov cl, al" \
460 " shr ax, 1" /* convert to byte offset */ \
461 " shr ax, 1" \
462 " shr ax, 1" \
463 " add bx, ax" /* adjust pointer again */\
464 " and cl, 7" \
465 " mov al, 1" \
466 " shl al, cl" \
467 " not al" /* al=bitmask */ \
468 " and es:[bx], al" \
469 parm [es bx] [ax cx] \
470 modify exact [ax bx cx];
471#else
472# pragma aux ASMBitClear = \
473 "shl edx, 16" \
474 "mov dx, ax" \
475 "btr es:[bx], edx" \
476 parm [es bx] [ax dx] \
477 modify exact [dx];
478#endif
479
480#undef ASMAtomicBitClear
481#pragma aux ASMAtomicBitClear = \
482 ".386" \
483 "shl edx, 16" \
484 "mov dx, ax" \
485 "lock btr es:[bx], edx" \
486 parm [es bx] [ax dx] \
487 modify exact [dx];
488
489#undef ASMBitToggle
490#if defined(__SW_0) || defined(__SW_1) || defined(__SW_2)
491# pragma aux ASMBitToggle = \
492 " mov ch, cl" /* Only the three lowest bits are relevant due to 64KB segments */ \
493 " mov cl, 5" \
494 " shl ch, cl" \
495 " add bh, ch" /* Adjust the pointer. */ \
496 " mov cl, al" \
497 " shr ax, 1" /* convert to byte offset */ \
498 " shr ax, 1" \
499 " shr ax, 1" \
500 " add bx, ax" /* adjust pointer again */\
501 " and cl, 7" \
502 " mov al, 1" \
503 " shl al, cl" /* al=bitmask */ \
504 " xor es:[bx], al" \
505 parm [es bx] [ax cx] \
506 modify exact [ax bx cx];
507#else
508# pragma aux ASMBitToggle = \
509 "shl edx, 16" \
510 "mov dx, ax" \
511 "btc es:[bx], edx" \
512 parm [es bx] [ax dx] \
513 modify exact [dx];
514#endif
515
516#undef ASMAtomicBitToggle
517#pragma aux ASMAtomicBitToggle = \
518 ".386" \
519 "shl edx, 16" \
520 "mov dx, ax" \
521 "lock btc es:[bx], edx" \
522 parm [es bx] [ax dx] \
523 modify exact [dx];
524
525#undef ASMBitTestAndSet
526#if defined(__SW_0) || defined(__SW_1) || defined(__SW_2)
527# pragma aux ASMBitTestAndSet = \
528 " mov ch, cl" /* Only the three lowest bits are relevant due to 64KB segments */ \
529 " mov cl, 5" \
530 " shl ch, cl" \
531 " add bh, ch" /* Adjust the pointer. */ \
532 " mov cl, al" \
533 " shr ax, 1" /* convert to byte offset */ \
534 " shr ax, 1" \
535 " shr ax, 1" \
536 " add bx, ax" /* adjust pointer again */\
537 " and cl, 7" /* cl=byte shift count */ \
538 " mov ah, 1" \
539 " shl ah, cl" /* ah=bitmask */ \
540 " mov al, es:[bx]" \
541 " or ah, al" \
542 " mov es:[bx], ah" \
543 " shr al, cl" \
544 " and al, 1" \
545 parm [es bx] [ax cx] \
546 value [al] \
547 modify exact [ax bx cx];
548#else
549# pragma aux ASMBitTestAndSet = \
550 "shl edx, 16" \
551 "mov dx, ax" \
552 "bts es:[bx], edx" \
553 "setc al" \
554 parm [es bx] [ax dx] \
555 value [al] \
556 modify exact [ax dx];
557#endif
558
559#undef ASMAtomicBitTestAndSet
560#pragma aux ASMAtomicBitTestAndSet = \
561 ".386" \
562 "shl edx, 16" \
563 "mov dx, ax" \
564 "lock bts es:[bx], edx" \
565 "setc al" \
566 parm [es bx] [ax dx] \
567 value [al] \
568 modify exact [ax dx];
569
570#undef ASMBitTestAndClear
571#if defined(__SW_0) || defined(__SW_1) || defined(__SW_2)
572# pragma aux ASMBitTestAndClear = \
573 " mov ch, cl" /* Only the three lowest bits are relevant due to 64KB segments */ \
574 " mov cl, 5" \
575 " shl ch, cl" \
576 " add bh, ch" /* Adjust the pointer. */ \
577 " mov cl, al" \
578 " shr ax, 1" /* convert to byte offset */ \
579 " shr ax, 1" \
580 " shr ax, 1" \
581 " add bx, ax" /* adjust pointer again */\
582 " and cl, 7" /* cl=byte shift count */ \
583 " mov ah, 1" \
584 " shl ah, cl" \
585 " not ah" /* ah=bitmask */ \
586 " mov al, es:[bx]" \
587 " and ah, al" \
588 " mov es:[bx], ah" \
589 " shr al, cl" \
590 " and al, 1" \
591 parm [es bx] [ax cx] \
592 value [al] \
593 modify exact [ax bx cx];
594#else
595# pragma aux ASMBitTestAndClear = \
596 "shl edx, 16" \
597 "mov dx, ax" \
598 "btr es:[bx], edx" \
599 "setc al" \
600 parm [es bx] [ax dx] \
601 value [al] \
602 modify exact [ax dx];
603#endif
604
605#undef ASMAtomicBitTestAndClear
606#pragma aux ASMAtomicBitTestAndClear = \
607 ".386" \
608 "shl edx, 16" \
609 "mov dx, ax" \
610 "lock btr es:[bx], edx" \
611 "setc al" \
612 parm [es bx] [ax dx] \
613 value [al] \
614 modify exact [ax dx];
615
616#undef ASMBitTestAndToggle
617#if defined(__SW_0) || defined(__SW_1) || defined(__SW_2)
618# pragma aux ASMBitTestAndToggle = \
619 " mov ch, cl" /* Only the three lowest bits are relevant due to 64KB segments */ \
620 " mov cl, 5" \
621 " shl ch, cl" \
622 " add bh, ch" /* Adjust the pointer. */ \
623 " mov cl, al" \
624 " shr ax, 1" /* convert to byte offset */ \
625 " shr ax, 1" \
626 " shr ax, 1" \
627 " add bx, ax" /* adjust pointer again */\
628 " and cl, 7" /* cl=byte shift count */ \
629 " mov ah, 1" \
630 " shl ah, cl" /* ah=bitmask */ \
631 " mov al, es:[bx]" \
632 " xor ah, al" \
633 " mov es:[bx], ah" \
634 " shr al, cl" \
635 " and al, 1" \
636 parm [es bx] [ax cx] \
637 value [al] \
638 modify exact [ax bx cx];
639#else
640# pragma aux ASMBitTestAndToggle = \
641 "shl edx, 16" \
642 "mov dx, ax" \
643 "btc es:[bx], edx" \
644 "setc al" \
645 parm [es bx] [ax dx] \
646 value [al] \
647 modify exact [ax dx];
648#endif
649
650#undef ASMAtomicBitTestAndToggle
651#pragma aux ASMAtomicBitTestAndToggle = \
652 ".386" \
653 "shl edx, 16" \
654 "mov dx, ax" \
655 "lock btc es:[bx], edx" \
656 "setc al" \
657 parm [es bx] [ax dx] \
658 value [al] \
659 modify exact [ax dx];
660
661#undef ASMBitTest
662#if defined(__SW_0) || defined(__SW_1) || defined(__SW_2)
663# pragma aux ASMBitTest = \
664 " mov ch, cl" /* Only the three lowest bits are relevant due to 64KB segments */ \
665 " mov cl, 5" \
666 " shl ch, cl" \
667 " add bh, ch" /* Adjust the pointer. */ \
668 " mov cl, al" \
669 " shr ax, 1" /* convert to byte offset */ \
670 " shr ax, 1" \
671 " shr ax, 1" \
672 " add bx, ax" /* adjust pointer again */\
673 " and cl, 7" \
674 " mov al, es:[bx]" \
675 " shr al, cl" \
676 " and al, 1" \
677 parm [es bx] [ax cx] \
678 value [al] \
679 modify exact [ax bx cx];
680#else
681# pragma aux ASMBitTest = \
682 "shl edx, 16" \
683 "mov dx, ax" \
684 "bt es:[bx], edx" \
685 "setc al" \
686 parm [es bx] [ax dx] nomemory \
687 value [al] \
688 modify exact [ax dx] nomemory;
689#endif
690
691/* ASMBitFirstClear: External file. */
692/* ASMBitNextClear: External file. */
693/* ASMBitFirstSet: External file. */
694/* ASMBitNextSet: External file. */
695
696#if defined(__SW_0) || defined(__SW_1) || defined(__SW_2)
697/* ASMBitFirstSetU32: External file. */
698#else
699# undef ASMBitFirstSetU32
700# pragma aux ASMBitFirstSetU32 = \
701 "shl edx, 16" \
702 "mov dx, ax" \
703 "bsf eax, edx" \
704 "jz not_found" \
705 "inc ax" \
706 "jmp done" \
707 "not_found:" \
708 "xor ax, ax" \
709 "done:" \
710 parm [ax dx] nomemory \
711 value [ax] \
712 modify exact [ax dx] nomemory;
713#endif
714
715#if defined(__SW_0) || defined(__SW_1) || defined(__SW_2)
716/* ASMBitFirstSetU64: External file. */
717#else
718# undef ASMBitFirstSetU64
719# pragma aux ASMBitFirstSetU64 = \
720 ".386" \
721 "shl ecx, 16" \
722 "mov cx, dx" \
723 "bsf ecx, ecx" \
724 "jz not_found_low" \
725 "mov ax, cx" \
726 "inc ax" \
727 "jmp done" \
728 \
729 "not_found_low:" \
730 "shr eax, 16" \
731 "mov ax, bx" \
732 "bsf eax, eax" \
733 "jz not_found_high" \
734 "add ax, 33" \
735 "jmp done" \
736 \
737 "not_found_high:" \
738 "xor ax, ax" \
739 "done:" \
740 parm [dx cx bx ax] nomemory \
741 value [ax] \
742 modify exact [ax cx] nomemory;
743#endif
744
745#if defined(__SW_0) || defined(__SW_1) || defined(__SW_2)
746/* ASMBitFirstSetU16: External file. */
747#else
748# undef ASMBitFirstSetU16
749# pragma aux ASMBitFirstSetU16 = \
750 "bsf ax, ax" \
751 "jz not_found" \
752 "inc ax" \
753 "jmp done" \
754 "not_found:" \
755 "xor ax, ax" \
756 "done:" \
757 parm [ax] nomemory \
758 value [ax] \
759 modify exact [ax] nomemory;
760#endif
761
762#if defined(__SW_0) || defined(__SW_1) || defined(__SW_2)
763/* ASMBitLastSetU32: External file. */
764#else
765# undef ASMBitLastSetU32
766# pragma aux ASMBitLastSetU32 = \
767 "shl edx, 16" \
768 "mov dx, ax" \
769 "bsr eax, edx" \
770 "jz not_found" \
771 "inc ax" \
772 "jmp done" \
773 "not_found:" \
774 "xor ax, ax" \
775 "done:" \
776 parm [ax dx] nomemory \
777 value [ax] \
778 modify exact [ax dx] nomemory;
779#endif
780
781#if defined(__SW_0) || defined(__SW_1) || defined(__SW_2)
782/* ASMBitLastSetU64: External file. */
783#else
784# undef ASMBitLastSetU64
785# pragma aux ASMBitLastSetU64 = \
786 ".386" \
787 "shl ecx, 16" \
788 "mov cx, dx" \
789 "bsf ecx, ecx" \
790 "jz not_found_low" \
791 "mov ax, cx" \
792 "inc ax" \
793 "jmp done" \
794 \
795 "not_found_low:" \
796 "shr eax, 16" \
797 "mov ax, bx" \
798 "bsf eax, eax" \
799 "jz not_found_high" \
800 "add ax, 33" \
801 "jmp done" \
802 \
803 "not_found_high:" \
804 "xor ax, ax" \
805 "done:" \
806 parm [dx cx bx ax] nomemory \
807 value [ax] \
808 modify exact [ax cx] nomemory;
809#endif
810
811#if defined(__SW_0) || defined(__SW_1) || defined(__SW_2)
812/* ASMBitLastSetU16: External file. */
813#else
814# undef ASMBitLastSetU16
815# pragma aux ASMBitLastSetU16 = \
816 "bsr ax, ax" \
817 "jz not_found" \
818 "inc ax" \
819 "jmp done" \
820 "not_found:" \
821 "xor ax, ax" \
822 "done:" \
823 parm [ax] nomemory \
824 value [ax] \
825 modify exact [ax] nomemory;
826#endif
827
828#undef ASMByteSwapU16
829#pragma aux ASMByteSwapU16 = \
830 "xchg al, ah" \
831 parm [ax] nomemory \
832 value [ax] \
833 modify exact [ax] nomemory;
834
835#undef ASMByteSwapU32
836#pragma aux ASMByteSwapU32 = \
837 "xchg dh, al" \
838 "xchg dl, ah" \
839 parm [ax dx] nomemory \
840 value [ax dx] \
841 modify exact [ax dx] nomemory;
842
843#undef ASMRotateLeftU32
844#pragma aux ASMRotateLeftU32 = \
845 ".386" \
846 "shl edx, 16" \
847 "mov dx, ax" \
848 "rol edx, cl" \
849 "mov eax, edx" \
850 "shr edx, 16" \
851 parm [ax dx] [cx] nomemory \
852 value [ax dx] \
853 modify exact [ax dx] nomemory;
854
855#undef ASMRotateRightU32
856#pragma aux ASMRotateRightU32 = \
857 ".386" \
858 "shl edx, 16" \
859 "mov dx, ax" \
860 "ror edx, cl" \
861 "mov eax, edx" \
862 "shr edx, 16" \
863 parm [ax dx] [cx] nomemory \
864 value [ax dx] \
865 modify exact [ax dx] nomemory;
866
867#endif
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette