VirtualBox

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

Last change on this file since 80957 was 76585, checked in by vboxsync, 6 years ago

*: scm --fix-header-guard-endif

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