VirtualBox

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

Last change on this file since 98103 was 98103, checked in by vboxsync, 17 months ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 24.6 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 ASMMemZeroPage
408#ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
409# if defined(__SW_0) || defined(__SW_1) || defined(__SW_2)
410# pragma aux ASMMemZeroPage = \
411 "mov cx, 2048" \
412 "xor ax, ax" \
413 "rep stosw" \
414 parm [es di] \
415 modify exact [ax cx di];
416# else
417# pragma aux ASMMemZeroPage = \
418 "mov ecx, 1024" \
419 "xor eax, eax" \
420 "rep stosd" \
421 parm [es di] \
422 modify exact [ax cx di];
423# endif
424#endif
425
426#undef ASMMemZero32
427#ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
428# if defined(__SW_0) || defined(__SW_1) || defined(__SW_2)
429# pragma aux ASMMemZero32 = \
430 "xor ax, ax" \
431 "shr cx, 1" \
432 "shr cx, 1" \
433 "rep stosw" \
434 parm [es di] [cx] \
435 modify exact [ax dx cx di];
436# else
437# pragma aux ASMMemZero32 = \
438 "and ecx, 0ffffh" /* probably not necessary, lazy bird should check... */ \
439 "shr ecx, 2" \
440 "xor eax, eax" \
441 "rep stosd" \
442 parm [es di] [cx] \
443 modify exact [ax cx di];
444# endif
445#endif
446
447#undef ASMMemFill32
448#ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
449# if defined(__SW_0) || defined(__SW_1) || defined(__SW_2)
450# pragma aux ASMMemFill32 = \
451 " shr cx, 1" \
452 " shr cx, 1" \
453 " jz done" \
454 "again:" \
455 " stosw" \
456 " xchg ax, dx" \
457 " stosw" \
458 " xchg ax, dx" \
459 " dec cx" \
460 " jnz again" \
461 "done:" \
462 parm [es di] [cx] [ax dx]\
463 modify exact [cx di];
464# else
465# pragma aux ASMMemFill32 = \
466 "and ecx, 0ffffh" /* probably not necessary, lazy bird should check... */ \
467 "shr ecx, 2" \
468 "shl eax, 16" \
469 "mov ax, dx" \
470 "rol eax, 16" \
471 "rep stosd" \
472 parm [es di] [cx] [ax dx]\
473 modify exact [ax cx di];
474# endif
475#endif
476
477#undef ASMProbeReadByte
478#ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
479#pragma aux ASMProbeReadByte = \
480 "mov al, es:[bx]" \
481 parm [es bx] \
482 value [al] \
483 modify exact [al];
484#endif
485
486#undef ASMBitSet
487#ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
488# if defined(__SW_0) || defined(__SW_1) || defined(__SW_2)
489# pragma aux ASMBitSet = \
490 " mov ch, cl" /* Only the three lowest bits are relevant due to 64KB segments */ \
491 " mov cl, 5" \
492 " shl ch, cl" \
493 " add bh, ch" /* Adjust the pointer. */ \
494 " mov cl, al" \
495 " shr ax, 1" /* convert to byte offset */ \
496 " shr ax, 1" \
497 " shr ax, 1" \
498 " add bx, ax" /* adjust pointer again */\
499 " and cl, 7" \
500 " mov al, 1" \
501 " shl al, cl" /* al=bitmask */ \
502 " or es:[bx], al" \
503 parm [es bx] [ax cx] \
504 modify exact [ax bx cx];
505# else
506# pragma aux ASMBitSet = \
507 "shl edx, 16" \
508 "mov dx, ax" \
509 "bts es:[bx], edx" \
510 parm [es bx] [ax dx] \
511 modify exact [dx];
512# endif
513#endif
514
515#undef ASMAtomicBitSet
516#ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
517#pragma aux ASMAtomicBitSet = \
518 ".386" \
519 "shl edx, 16" \
520 "mov dx, ax" \
521 "lock bts es:[bx], edx" \
522 parm [es bx] [ax dx] \
523 modify exact [dx];
524#endif
525
526#undef ASMBitClear
527#ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
528# if defined(__SW_0) || defined(__SW_1) || defined(__SW_2)
529# pragma aux ASMBitClear = \
530 " mov ch, cl" /* Only the three lowest bits are relevant due to 64KB segments */ \
531 " mov cl, 5" \
532 " shl ch, cl" \
533 " add bh, ch" /* Adjust the pointer. */ \
534 " mov cl, al" \
535 " shr ax, 1" /* convert to byte offset */ \
536 " shr ax, 1" \
537 " shr ax, 1" \
538 " add bx, ax" /* adjust pointer again */\
539 " and cl, 7" \
540 " mov al, 1" \
541 " shl al, cl" \
542 " not al" /* al=bitmask */ \
543 " and es:[bx], al" \
544 parm [es bx] [ax cx] \
545 modify exact [ax bx cx];
546# else
547# pragma aux ASMBitClear = \
548 "shl edx, 16" \
549 "mov dx, ax" \
550 "btr es:[bx], edx" \
551 parm [es bx] [ax dx] \
552 modify exact [dx];
553# endif
554#endif
555
556#undef ASMAtomicBitClear
557#ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
558#pragma aux ASMAtomicBitClear = \
559 ".386" \
560 "shl edx, 16" \
561 "mov dx, ax" \
562 "lock btr es:[bx], edx" \
563 parm [es bx] [ax dx] \
564 modify exact [dx];
565#endif
566
567#undef ASMBitToggle
568#ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
569# if defined(__SW_0) || defined(__SW_1) || defined(__SW_2)
570# pragma aux ASMBitToggle = \
571 " mov ch, cl" /* Only the three lowest bits are relevant due to 64KB segments */ \
572 " mov cl, 5" \
573 " shl ch, cl" \
574 " add bh, ch" /* Adjust the pointer. */ \
575 " mov cl, al" \
576 " shr ax, 1" /* convert to byte offset */ \
577 " shr ax, 1" \
578 " shr ax, 1" \
579 " add bx, ax" /* adjust pointer again */\
580 " and cl, 7" \
581 " mov al, 1" \
582 " shl al, cl" /* al=bitmask */ \
583 " xor es:[bx], al" \
584 parm [es bx] [ax cx] \
585 modify exact [ax bx cx];
586# else
587# pragma aux ASMBitToggle = \
588 "shl edx, 16" \
589 "mov dx, ax" \
590 "btc es:[bx], edx" \
591 parm [es bx] [ax dx] \
592 modify exact [dx];
593# endif
594#endif
595
596#undef ASMAtomicBitToggle
597#ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
598#pragma aux ASMAtomicBitToggle = \
599 ".386" \
600 "shl edx, 16" \
601 "mov dx, ax" \
602 "lock btc es:[bx], edx" \
603 parm [es bx] [ax dx] \
604 modify exact [dx];
605#endif
606
607#undef ASMBitTestAndSet
608#ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
609# if defined(__SW_0) || defined(__SW_1) || defined(__SW_2)
610# pragma aux ASMBitTestAndSet = \
611 " mov ch, cl" /* Only the three lowest bits are relevant due to 64KB segments */ \
612 " mov cl, 5" \
613 " shl ch, cl" \
614 " add bh, ch" /* Adjust the pointer. */ \
615 " mov cl, al" \
616 " shr ax, 1" /* convert to byte offset */ \
617 " shr ax, 1" \
618 " shr ax, 1" \
619 " add bx, ax" /* adjust pointer again */\
620 " and cl, 7" /* cl=byte shift count */ \
621 " mov ah, 1" \
622 " shl ah, cl" /* ah=bitmask */ \
623 " mov al, es:[bx]" \
624 " or ah, al" \
625 " mov es:[bx], ah" \
626 " shr al, cl" \
627 " and al, 1" \
628 parm [es bx] [ax cx] \
629 value [al] \
630 modify exact [ax bx cx];
631# else
632# pragma aux ASMBitTestAndSet = \
633 "shl edx, 16" \
634 "mov dx, ax" \
635 "bts es:[bx], edx" \
636 "setc al" \
637 parm [es bx] [ax dx] \
638 value [al] \
639 modify exact [ax dx];
640# endif
641#endif
642
643#undef ASMAtomicBitTestAndSet
644#ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
645#pragma aux ASMAtomicBitTestAndSet = \
646 ".386" \
647 "shl edx, 16" \
648 "mov dx, ax" \
649 "lock bts es:[bx], edx" \
650 "setc al" \
651 parm [es bx] [ax dx] \
652 value [al] \
653 modify exact [ax dx];
654#endif
655
656#undef ASMBitTestAndClear
657#ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
658# if defined(__SW_0) || defined(__SW_1) || defined(__SW_2)
659# pragma aux ASMBitTestAndClear = \
660 " mov ch, cl" /* Only the three lowest bits are relevant due to 64KB segments */ \
661 " mov cl, 5" \
662 " shl ch, cl" \
663 " add bh, ch" /* Adjust the pointer. */ \
664 " mov cl, al" \
665 " shr ax, 1" /* convert to byte offset */ \
666 " shr ax, 1" \
667 " shr ax, 1" \
668 " add bx, ax" /* adjust pointer again */\
669 " and cl, 7" /* cl=byte shift count */ \
670 " mov ah, 1" \
671 " shl ah, cl" \
672 " not ah" /* ah=bitmask */ \
673 " mov al, es:[bx]" \
674 " and ah, al" \
675 " mov es:[bx], ah" \
676 " shr al, cl" \
677 " and al, 1" \
678 parm [es bx] [ax cx] \
679 value [al] \
680 modify exact [ax bx cx];
681# else
682# pragma aux ASMBitTestAndClear = \
683 "shl edx, 16" \
684 "mov dx, ax" \
685 "btr es:[bx], edx" \
686 "setc al" \
687 parm [es bx] [ax dx] \
688 value [al] \
689 modify exact [ax dx];
690# endif
691#endif
692
693#undef ASMAtomicBitTestAndClear
694#ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
695#pragma aux ASMAtomicBitTestAndClear = \
696 ".386" \
697 "shl edx, 16" \
698 "mov dx, ax" \
699 "lock btr es:[bx], edx" \
700 "setc al" \
701 parm [es bx] [ax dx] \
702 value [al] \
703 modify exact [ax dx];
704#endif
705
706#undef ASMBitTestAndToggle
707#ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
708# if defined(__SW_0) || defined(__SW_1) || defined(__SW_2)
709# pragma aux ASMBitTestAndToggle = \
710 " mov ch, cl" /* Only the three lowest bits are relevant due to 64KB segments */ \
711 " mov cl, 5" \
712 " shl ch, cl" \
713 " add bh, ch" /* Adjust the pointer. */ \
714 " mov cl, al" \
715 " shr ax, 1" /* convert to byte offset */ \
716 " shr ax, 1" \
717 " shr ax, 1" \
718 " add bx, ax" /* adjust pointer again */\
719 " and cl, 7" /* cl=byte shift count */ \
720 " mov ah, 1" \
721 " shl ah, cl" /* ah=bitmask */ \
722 " mov al, es:[bx]" \
723 " xor ah, al" \
724 " mov es:[bx], ah" \
725 " shr al, cl" \
726 " and al, 1" \
727 parm [es bx] [ax cx] \
728 value [al] \
729 modify exact [ax bx cx];
730# else
731# pragma aux ASMBitTestAndToggle = \
732 "shl edx, 16" \
733 "mov dx, ax" \
734 "btc es:[bx], edx" \
735 "setc al" \
736 parm [es bx] [ax dx] \
737 value [al] \
738 modify exact [ax dx];
739# endif
740#endif
741
742#undef ASMAtomicBitTestAndToggle
743#ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
744#pragma aux ASMAtomicBitTestAndToggle = \
745 ".386" \
746 "shl edx, 16" \
747 "mov dx, ax" \
748 "lock btc es:[bx], edx" \
749 "setc al" \
750 parm [es bx] [ax dx] \
751 value [al] \
752 modify exact [ax dx];
753#endif
754
755#undef ASMBitTest
756#ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
757# if defined(__SW_0) || defined(__SW_1) || defined(__SW_2)
758# pragma aux ASMBitTest = \
759 " mov ch, cl" /* Only the three lowest bits are relevant due to 64KB segments */ \
760 " mov cl, 5" \
761 " shl ch, cl" \
762 " add bh, ch" /* Adjust the pointer. */ \
763 " mov cl, al" \
764 " shr ax, 1" /* convert to byte offset */ \
765 " shr ax, 1" \
766 " shr ax, 1" \
767 " add bx, ax" /* adjust pointer again */\
768 " and cl, 7" \
769 " mov al, es:[bx]" \
770 " shr al, cl" \
771 " and al, 1" \
772 parm [es bx] [ax cx] \
773 value [al] \
774 modify exact [ax bx cx];
775# else
776# pragma aux ASMBitTest = \
777 "shl edx, 16" \
778 "mov dx, ax" \
779 "bt es:[bx], edx" \
780 "setc al" \
781 parm [es bx] [ax dx] nomemory \
782 value [al] \
783 modify exact [ax dx] nomemory;
784# endif
785#endif
786
787/* ASMBitFirstClear: External file. */
788/* ASMBitNextClear: External file. */
789/* ASMBitFirstSet: External file. */
790/* ASMBitNextSet: External file. */
791
792#if defined(__SW_0) || defined(__SW_1) || defined(__SW_2)
793/* ASMBitFirstSetU32: External file. */
794#else
795# undef ASMBitFirstSetU32
796# ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
797# pragma aux ASMBitFirstSetU32 = \
798 "shl edx, 16" \
799 "mov dx, ax" \
800 "bsf eax, edx" \
801 "jz not_found" \
802 "inc ax" \
803 "jmp done" \
804 "not_found:" \
805 "xor ax, ax" \
806 "done:" \
807 parm [ax dx] nomemory \
808 value [ax] \
809 modify exact [ax dx] nomemory;
810# endif
811#endif
812
813#if defined(__SW_0) || defined(__SW_1) || defined(__SW_2)
814/* ASMBitFirstSetU64: External file. */
815#else
816# undef ASMBitFirstSetU64
817# ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
818# pragma aux ASMBitFirstSetU64 = \
819 ".386" \
820 "shl ecx, 16" \
821 "mov cx, dx" \
822 "bsf ecx, ecx" \
823 "jz not_found_low" \
824 "mov ax, cx" \
825 "inc ax" \
826 "jmp done" \
827 \
828 "not_found_low:" \
829 "shr eax, 16" \
830 "mov ax, bx" \
831 "bsf eax, eax" \
832 "jz not_found_high" \
833 "add ax, 33" \
834 "jmp done" \
835 \
836 "not_found_high:" \
837 "xor ax, ax" \
838 "done:" \
839 parm [dx cx bx ax] nomemory \
840 value [ax] \
841 modify exact [ax cx] nomemory;
842# endif
843#endif
844
845#if defined(__SW_0) || defined(__SW_1) || defined(__SW_2)
846/* ASMBitFirstSetU16: External file. */
847#else
848# undef ASMBitFirstSetU16
849# ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
850# pragma aux ASMBitFirstSetU16 = \
851 "bsf ax, ax" \
852 "jz not_found" \
853 "inc ax" \
854 "jmp done" \
855 "not_found:" \
856 "xor ax, ax" \
857 "done:" \
858 parm [ax] nomemory \
859 value [ax] \
860 modify exact [ax] nomemory;
861# endif
862#endif
863
864#if defined(__SW_0) || defined(__SW_1) || defined(__SW_2)
865/* ASMBitLastSetU32: External file. */
866#else
867# undef ASMBitLastSetU32
868# ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
869# pragma aux ASMBitLastSetU32 = \
870 "shl edx, 16" \
871 "mov dx, ax" \
872 "bsr eax, edx" \
873 "jz not_found" \
874 "inc ax" \
875 "jmp done" \
876 "not_found:" \
877 "xor ax, ax" \
878 "done:" \
879 parm [ax dx] nomemory \
880 value [ax] \
881 modify exact [ax dx] nomemory;
882# endif
883#endif
884
885#if defined(__SW_0) || defined(__SW_1) || defined(__SW_2)
886/* ASMBitLastSetU64: External file. */
887#else
888# undef ASMBitLastSetU64
889# ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
890# pragma aux ASMBitLastSetU64 = \
891 ".386" \
892 "shl ecx, 16" \
893 "mov cx, dx" \
894 "bsf ecx, ecx" \
895 "jz not_found_low" \
896 "mov ax, cx" \
897 "inc ax" \
898 "jmp done" \
899 \
900 "not_found_low:" \
901 "shr eax, 16" \
902 "mov ax, bx" \
903 "bsf eax, eax" \
904 "jz not_found_high" \
905 "add ax, 33" \
906 "jmp done" \
907 \
908 "not_found_high:" \
909 "xor ax, ax" \
910 "done:" \
911 parm [dx cx bx ax] nomemory \
912 value [ax] \
913 modify exact [ax cx] nomemory;
914# endif
915#endif
916
917#if defined(__SW_0) || defined(__SW_1) || defined(__SW_2)
918/* ASMBitLastSetU16: External file. */
919#else
920# undef ASMBitLastSetU16
921# ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
922# pragma aux ASMBitLastSetU16 = \
923 "bsr ax, ax" \
924 "jz not_found" \
925 "inc ax" \
926 "jmp done" \
927 "not_found:" \
928 "xor ax, ax" \
929 "done:" \
930 parm [ax] nomemory \
931 value [ax] \
932 modify exact [ax] nomemory;
933# endif
934#endif
935
936#undef ASMByteSwapU16
937#ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
938#pragma aux ASMByteSwapU16 = \
939 "xchg al, ah" \
940 parm [ax] nomemory \
941 value [ax] \
942 modify exact [ax] nomemory;
943#endif
944
945#undef ASMByteSwapU32
946#ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
947#pragma aux ASMByteSwapU32 = \
948 "xchg dh, al" \
949 "xchg dl, ah" \
950 parm [ax dx] nomemory \
951 value [ax dx] \
952 modify exact [ax dx] nomemory;
953#endif
954
955#undef ASMRotateLeftU32
956#ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
957#pragma aux ASMRotateLeftU32 = \
958 ".386" \
959 "shl edx, 16" \
960 "mov dx, ax" \
961 "rol edx, cl" \
962 "mov eax, edx" \
963 "shr edx, 16" \
964 parm [ax dx] [cx] nomemory \
965 value [ax dx] \
966 modify exact [ax dx] nomemory;
967#endif
968
969#undef ASMRotateRightU32
970#ifdef IPRT_ASM_WATCOM_X86_16_WITH_PRAGMAS
971#pragma aux ASMRotateRightU32 = \
972 ".386" \
973 "shl edx, 16" \
974 "mov dx, ax" \
975 "ror edx, cl" \
976 "mov eax, edx" \
977 "shr edx, 16" \
978 parm [ax dx] [cx] nomemory \
979 value [ax dx] \
980 modify exact [ax dx] nomemory;
981#endif
982
983#endif /* !IPRT_INCLUDED_asm_watcom_x86_16_h */
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use