VirtualBox

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

Last change on this file was 103005, checked in by vboxsync, 4 months ago

iprt/asm.h,*: Split out the ASMMem* and related stuff into a separate header, asm-mem.h, so that we can get the RT_ASM_PAGE_SIZE stuff out of the way.

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

© 2023 Oracle
ContactPrivacy policyTerms of Use