VirtualBox

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

Last change on this file since 103626 was 103005, checked in by vboxsync, 10 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
Line 
1/** @file
2 * IPRT - Assembly Functions, x86 16-bit Watcom C/C++ pragma aux.
3 */
4
5/*
6 * Copyright (C) 2006-2023 Oracle and/or its affiliates.
7 *
8 * This file is part of VirtualBox base platform packages, as
9 * available from https://www.virtualbox.org.
10 *
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 *
24 * The contents of this file may alternatively be used under the terms
25 * of the Common Development and Distribution License Version 1.0
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
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.
32 *
33 * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
34 */
35
36#ifndef IPRT_INCLUDED_asm_watcom_x86_16_h
37#define IPRT_INCLUDED_asm_watcom_x86_16_h
38/* no pragma once */
39
40#ifndef IPRT_INCLUDED_asm_h
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.
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
52 * the watcom header at both the top and the bottom of asm.h file.
53 */
54
55#undef ASMCompilerBarrier
56#ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
57# if 0 /* overkill version. */
58# pragma aux ASMCompilerBarrier = \
59 "nop" \
60 parm [] \
61 modify exact [ax bx cx dx es ds];
62# else
63# pragma aux ASMCompilerBarrier = \
64 "" \
65 parm [] \
66 modify exact [];
67# endif
68#endif
69
70#undef ASMNopPause
71#ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
72#pragma aux ASMNopPause = \
73 ".686p" \
74 ".xmm2" \
75 "pause" \
76 parm [] nomemory \
77 modify exact [] nomemory;
78#endif
79
80#undef ASMAtomicXchgU8
81#ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
82#pragma aux ASMAtomicXchgU8 = \
83 "xchg es:[bx], al" \
84 parm [es bx] [al] \
85 value [al] \
86 modify exact [al];
87#endif
88
89#undef ASMAtomicXchgU16
90#ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
91#pragma aux ASMAtomicXchgU16 = \
92 "xchg es:[bx], ax" \
93 parm [es bx] [ax] \
94 value [ax] \
95 modify exact [ax];
96#endif
97
98#undef ASMAtomicXchgU32
99#ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
100#pragma aux ASMAtomicXchgU32 = \
101 ".386" \
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];
110#endif
111
112#undef ASMAtomicXchgU64
113#ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
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];
133#endif
134
135#undef ASMAtomicCmpXchgU8
136#ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
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];
144#endif
145
146#undef ASMAtomicCmpXchgU16
147#ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
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];
155#endif
156
157#undef ASMAtomicCmpXchgU32
158#ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
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];
171#endif
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
177#undef ASMSerializeInstructionCpuId
178#ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
179#pragma aux ASMSerializeInstructionCpuId = \
180 ".586" \
181 "xor eax, eax" \
182 "cpuid" \
183 parm [] \
184 modify exact [ax bx cx dx];
185#endif
186
187#undef ASMSerializeInstructionIRet
188#ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
189#pragma aux ASMSerializeInstructionIRet = \
190 "pushf" \
191 "push cs" \
192 "call foo" /* 'push offset done' doesn't work */ \
193 "jmp done" \
194 "foo:" \
195 "iret" \
196 "done:" \
197 parm [] \
198 modify exact [];
199#endif
200
201#undef ASMSerializeInstructionRdTscp
202#ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
203#pragma aux ASMSerializeInstructionRdTscp = \
204 0x0f 0x01 0xf9 \
205 parm [] \
206 modify exact [ax dx cx];
207#endif
208
209#undef ASMAtomicReadU64
210#ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
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" \
223 parm [es si] \
224 value [dx cx bx ax] \
225 modify exact [dx cx bx ax];
226#endif
227
228#undef ASMAtomicUoReadU64
229#ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
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" \
242 parm [es si] \
243 value [dx cx bx ax] \
244 modify exact [dx cx bx ax];
245#endif
246
247#undef ASMAtomicAddU16
248#ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
249#pragma aux ASMAtomicAddU16 = \
250 ".486" \
251 "lock xadd es:[bx], ax" \
252 parm [es bx] [ax] \
253 value [ax] \
254 modify exact [ax];
255#endif
256
257#undef ASMAtomicAddU32
258#ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
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];
269#endif
270
271#undef ASMAtomicIncU16
272#ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
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];
281#endif
282
283#undef ASMAtomicIncU32
284#ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
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];
295#endif
296
297/* ASMAtomicIncU64: Should be done by C inline or in external file. */
298
299#undef ASMAtomicDecU16
300#ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
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];
309#endif
310
311#undef ASMAtomicDecU32
312#ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
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];
323#endif
324
325/* ASMAtomicDecU64: Should be done by C inline or in external file. */
326
327#undef ASMAtomicOrU32
328#ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
329#pragma aux ASMAtomicOrU32 = \
330 ".386" \
331 "shl edx, 16" \
332 "mov dx, ax" \
333 "lock or es:[bx], edx" \
334 parm [es bx] [ax dx] \
335 modify exact [dx];
336#endif
337
338/* ASMAtomicOrU64: Should be done by C inline or in external file. */
339
340#undef ASMAtomicAndU32
341#ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
342#pragma aux ASMAtomicAndU32 = \
343 ".386" \
344 "shl edx, 16" \
345 "mov dx, ax" \
346 "lock and es:[bx], edx" \
347 parm [es bx] [ax dx] \
348 modify exact [dx];
349#endif
350
351/* ASMAtomicAndU64: Should be done by C inline or in external file. */
352
353#undef ASMAtomicUoOrU32
354#ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
355#pragma aux ASMAtomicUoOrU32 = \
356 ".386" \
357 "shl edx, 16" \
358 "mov dx, ax" \
359 "or es:[bx], edx" \
360 parm [es bx] [ax dx] \
361 modify exact [dx];
362#endif
363
364/* ASMAtomicUoOrU64: Should be done by C inline or in external file. */
365
366#undef ASMAtomicUoAndU32
367#ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
368#pragma aux ASMAtomicUoAndU32 = \
369 ".386" \
370 "shl edx, 16" \
371 "mov dx, ax" \
372 "and es:[bx], edx" \
373 parm [es bx] [ax dx] \
374 modify exact [dx];
375#endif
376
377/* ASMAtomicUoAndU64: Should be done by C inline or in external file. */
378
379#undef ASMAtomicUoIncU32
380#ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
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];
391#endif
392
393#undef ASMAtomicUoDecU32
394#ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
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];
405#endif
406
407#undef ASMBitSet
408#ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
409# if defined(__SW_0) || defined(__SW_1) || defined(__SW_2)
410# pragma aux ASMBitSet = \
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];
426# else
427# pragma aux ASMBitSet = \
428 "shl edx, 16" \
429 "mov dx, ax" \
430 "bts es:[bx], edx" \
431 parm [es bx] [ax dx] \
432 modify exact [dx];
433# endif
434#endif
435
436#undef ASMAtomicBitSet
437#ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
438#pragma aux ASMAtomicBitSet = \
439 ".386" \
440 "shl edx, 16" \
441 "mov dx, ax" \
442 "lock bts es:[bx], edx" \
443 parm [es bx] [ax dx] \
444 modify exact [dx];
445#endif
446
447#undef ASMBitClear
448#ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
449# if defined(__SW_0) || defined(__SW_1) || defined(__SW_2)
450# pragma aux ASMBitClear = \
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];
467# else
468# pragma aux ASMBitClear = \
469 "shl edx, 16" \
470 "mov dx, ax" \
471 "btr es:[bx], edx" \
472 parm [es bx] [ax dx] \
473 modify exact [dx];
474# endif
475#endif
476
477#undef ASMAtomicBitClear
478#ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
479#pragma aux ASMAtomicBitClear = \
480 ".386" \
481 "shl edx, 16" \
482 "mov dx, ax" \
483 "lock btr es:[bx], edx" \
484 parm [es bx] [ax dx] \
485 modify exact [dx];
486#endif
487
488#undef ASMBitToggle
489#ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
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#endif
516
517#undef ASMAtomicBitToggle
518#ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
519#pragma aux ASMAtomicBitToggle = \
520 ".386" \
521 "shl edx, 16" \
522 "mov dx, ax" \
523 "lock btc es:[bx], edx" \
524 parm [es bx] [ax dx] \
525 modify exact [dx];
526#endif
527
528#undef ASMBitTestAndSet
529#ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
530# if defined(__SW_0) || defined(__SW_1) || defined(__SW_2)
531# pragma aux ASMBitTestAndSet = \
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];
552# else
553# pragma aux ASMBitTestAndSet = \
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];
561# endif
562#endif
563
564#undef ASMAtomicBitTestAndSet
565#ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
566#pragma aux ASMAtomicBitTestAndSet = \
567 ".386" \
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];
575#endif
576
577#undef ASMBitTestAndClear
578#ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
579# if defined(__SW_0) || defined(__SW_1) || defined(__SW_2)
580# pragma aux ASMBitTestAndClear = \
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];
602# else
603# pragma aux ASMBitTestAndClear = \
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];
611# endif
612#endif
613
614#undef ASMAtomicBitTestAndClear
615#ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
616#pragma aux ASMAtomicBitTestAndClear = \
617 ".386" \
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];
625#endif
626
627#undef ASMBitTestAndToggle
628#ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
629# if defined(__SW_0) || defined(__SW_1) || defined(__SW_2)
630# pragma aux ASMBitTestAndToggle = \
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];
651# else
652# pragma aux ASMBitTestAndToggle = \
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];
660# endif
661#endif
662
663#undef ASMAtomicBitTestAndToggle
664#ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
665#pragma aux ASMAtomicBitTestAndToggle = \
666 ".386" \
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];
674#endif
675
676#undef ASMBitTest
677#ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
678# if defined(__SW_0) || defined(__SW_1) || defined(__SW_2)
679# pragma aux ASMBitTest = \
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];
696# else
697# pragma aux ASMBitTest = \
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;
705# endif
706#endif
707
708/* ASMBitFirstClear: External file. */
709/* ASMBitNextClear: External file. */
710/* ASMBitFirstSet: External file. */
711/* ASMBitNextSet: External file. */
712
713#if defined(__SW_0) || defined(__SW_1) || defined(__SW_2)
714/* ASMBitFirstSetU32: External file. */
715#else
716# undef ASMBitFirstSetU32
717# ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
718# pragma aux ASMBitFirstSetU32 = \
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;
731# endif
732#endif
733
734#if defined(__SW_0) || defined(__SW_1) || defined(__SW_2)
735/* ASMBitFirstSetU64: External file. */
736#else
737# undef ASMBitFirstSetU64
738# ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
739# pragma aux ASMBitFirstSetU64 = \
740 ".386" \
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;
763# endif
764#endif
765
766#if defined(__SW_0) || defined(__SW_1) || defined(__SW_2)
767/* ASMBitFirstSetU16: External file. */
768#else
769# undef ASMBitFirstSetU16
770# ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
771# pragma aux ASMBitFirstSetU16 = \
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;
782# endif
783#endif
784
785#if defined(__SW_0) || defined(__SW_1) || defined(__SW_2)
786/* ASMBitLastSetU32: External file. */
787#else
788# undef ASMBitLastSetU32
789# ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
790# pragma aux ASMBitLastSetU32 = \
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;
803# endif
804#endif
805
806#if defined(__SW_0) || defined(__SW_1) || defined(__SW_2)
807/* ASMBitLastSetU64: External file. */
808#else
809# undef ASMBitLastSetU64
810# ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
811# pragma aux ASMBitLastSetU64 = \
812 ".386" \
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;
835# endif
836#endif
837
838#if defined(__SW_0) || defined(__SW_1) || defined(__SW_2)
839/* ASMBitLastSetU16: External file. */
840#else
841# undef ASMBitLastSetU16
842# ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
843# pragma aux ASMBitLastSetU16 = \
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;
854# endif
855#endif
856
857#undef ASMByteSwapU16
858#ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
859#pragma aux ASMByteSwapU16 = \
860 "xchg al, ah" \
861 parm [ax] nomemory \
862 value [ax] \
863 modify exact [ax] nomemory;
864#endif
865
866#undef ASMByteSwapU32
867#ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
868#pragma aux ASMByteSwapU32 = \
869 "xchg dh, al" \
870 "xchg dl, ah" \
871 parm [ax dx] nomemory \
872 value [ax dx] \
873 modify exact [ax dx] nomemory;
874#endif
875
876#undef ASMRotateLeftU32
877#ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
878#pragma aux ASMRotateLeftU32 = \
879 ".386" \
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;
888#endif
889
890#undef ASMRotateRightU32
891#ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
892#pragma aux ASMRotateRightU32 = \
893 ".386" \
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;
902#endif
903
904#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