VirtualBox

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

Last change on this file since 58788 was 58788, checked in by vboxsync, 9 years ago

iprt/asm-watcom-x86-*.h: Some fixes.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 16.3 KB
Line 
1/** @file
2 * IPRT - Assembly Functions, x86 16-bit Watcom C/C++ pragma aux.
3 */
4
5/*
6 * Copyright (C) 2006-2015 Oracle Corporation
7 *
8 * This file is part of VirtualBox Open Source Edition (OSE), as
9 * available from http://www.virtualbox.org. This file is free software;
10 * you can redistribute it and/or modify it under the terms of the GNU
11 * General Public License (GPL) as published by the Free Software
12 * Foundation, in version 2 as it comes in the "COPYING" file of the
13 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
15 *
16 * The contents of this file may alternatively be used under the terms
17 * of the Common Development and Distribution License Version 1.0
18 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
19 * VirtualBox OSE distribution, in which case the provisions of the
20 * CDDL are applicable instead of those of the GPL.
21 *
22 * You may elect to license modified versions of this file under the
23 * terms and conditions of either the GPL or the CDDL or both.
24 */
25
26#ifndef ___iprt_asm_h
27# error "Don't include this header directly."
28#endif
29#ifndef ___iprt_asm_watcom_x86_16_h
30#define ___iprt_asm_watcom_x86_16_h
31
32#if !RT_FAR_DATA
33# error "Only works with far data pointers!"
34#endif
35
36/*
37 * Turns out we cannot use 'ds' for segment stuff here because the compiler
38 * seems to insists on loading the DGROUP segment into 'ds' before calling
39 * stuff when using -ecc. Using 'es' instead as this seems to work fine.
40 *
41 * Note! The #undef that preceds the #pragma aux statements is for undoing
42 * the mangling, because the symbol in #pragma aux [symbol] statements
43 * doesn't get subjected to preprocessing. This is also why we include
44 * the watcom header at the top rather than at the bottom of the
45 * asm-amd64-x86.h file.
46 */
47
48#undef ASMCompilerBarrier
49#if 0 /* overkill version. */
50# pragma aux ASMCompilerBarrier = \
51 "nop" \
52 parm [] \
53 modify exact [ax bx cx dx es ds];
54#else
55# pragma aux ASMCompilerBarrier = \
56 "" \
57 parm [] \
58 modify exact [];
59#endif
60
61#undef ASMNopPause
62#pragma aux ASMNopPause = \
63 ".686p" \
64 ".xmm2" \
65 "pause" \
66 parm [] nomemory \
67 modify exact [] nomemory;
68
69#undef ASMAtomicXchgU8
70#pragma aux ASMAtomicXchgU8 = \
71 "xchg es:[bx], al" \
72 parm [es bx] [al] \
73 value [al] \
74 modify exact [al];
75
76#undef ASMAtomicXchgU16
77#pragma aux ASMAtomicXchgU16 = \
78 "xchg es:[bx], ax" \
79 parm [es bx] [ax] \
80 value [ax] \
81 modify exact [ax];
82
83#undef ASMAtomicXchgU32
84#pragma aux ASMAtomicXchgU32 = \
85 "shl ecx, 16" \
86 "mov cx, ax" \
87 "xchg es:[bx], ecx" \
88 "mov eax, ecx" \
89 "shr ecx, 16" \
90 parm [es bx] [ax cx] \
91 value [ax cx] \
92 modify exact [ax cx];
93
94#undef ASMAtomicXchgU64
95#pragma aux ASMAtomicXchgU64 = \
96 ".586" \
97 "shl eax, 16" \
98 "mov ax, bx" /* eax = high dword */ \
99 "shl ecx, 16" \
100 "mov cx, dx" /* ecx = low dword */ \
101 "mov ebx, ecx" /* ebx = low */ \
102 "mov ecx, eax" /* ecx = high */ \
103 "try_again:" \
104 "lock cmpxchg8b es:[si]" \
105 "jnz try_again" \
106 "xchg eax, edx" \
107 "mov ebx, eax" \
108 "shr eax, 16" \
109 "mov ecx, edx" \
110 "shr ecx, 16" \
111 parm [es si] [dx cx bx ax] \
112 value [dx cx bx ax] \
113 modify exact [dx cx bx ax];
114
115#undef ASMAtomicCmpXchgU8
116#pragma aux ASMAtomicCmpXchgU8 = \
117 ".486" \
118 "lock cmpxchg es:[bx], cl" \
119 "setz al" \
120 parm [es bx] [cl] [al] \
121 value [al] \
122 modify exact [al];
123
124#undef ASMAtomicCmpXchgU16
125#pragma aux ASMAtomicCmpXchgU16 = \
126 ".486" \
127 "lock cmpxchg es:[bx], cx" \
128 "setz al" \
129 parm [es bx] [cx] [ax] \
130 value [al] \
131 modify exact [ax];
132
133#undef ASMAtomicCmpXchgU32
134#pragma aux ASMAtomicCmpXchgU32 = \
135 ".486" \
136 "shl ecx, 16" \
137 "mov cx, dx" \
138 "shl eax, 16" \
139 "mov ax, di" \
140 "rol eax, 16" \
141 "lock cmpxchg es:[bx], ecx" \
142 "setz al" \
143 parm [es bx] [cx dx] [ax di] \
144 value [al] \
145 modify exact [ax cx];
146
147/* ASMAtomicCmpXchgU64: External assembly implementation, too few registers for parameters. */
148/* ASMAtomicCmpXchgExU32: External assembly implementation, too few registers for parameters. */
149/* ASMAtomicCmpXchgExU64: External assembly implementation, too few registers for parameters. */
150
151#undef ASMSerializeInstruction
152#pragma aux ASMSerializeInstruction = \
153 ".586" \
154 "xor eax, eax" \
155 "cpuid" \
156 parm [] \
157 modify exact [ax bx cx dx];
158
159#undef ASMAtomicReadU64
160#pragma aux ASMAtomicReadU64 = \
161 ".586" \
162 "xor eax, eax" \
163 "xor edx, edx" \
164 "xor ebx, ebx" \
165 "xor ecx, ecx" \
166 "lock cmpxchg8b es:[si]" \
167 "xchg eax, edx" \
168 "mov ebx, eax" \
169 "shr eax, 16" \
170 "mov ecx, edx" \
171 "shr ecx, 16" \
172 parm [es si] \
173 value [dx cx bx ax] \
174 modify exact [dx cx bx ax];
175
176#undef ASMAtomicUoReadU64
177#pragma aux ASMAtomicUoReadU64 = \
178 ".586" \
179 "xor eax, eax" \
180 "xor edx, edx" \
181 "xor ebx, ebx" \
182 "xor ecx, ecx" \
183 "lock cmpxchg8b es:[si]" \
184 "xchg eax, edx" \
185 "mov ebx, eax" \
186 "shr eax, 16" \
187 "mov ecx, edx" \
188 "shr ecx, 16" \
189 parm [es si] \
190 value [dx cx bx ax] \
191 modify exact [dx cx bx ax];
192
193#undef ASMAtomicAddU16
194#pragma aux ASMAtomicAddU16 = \
195 ".486" \
196 "lock xadd es:[bx], ax" \
197 parm [es bx] [ax] \
198 value [ax] \
199 modify exact [ax];
200
201#undef ASMAtomicAddU32
202#pragma aux ASMAtomicAddU32 = \
203 ".486" \
204 "shl edx, 16" \
205 "mov dx, ax" \
206 "lock xadd es:[bx], edx" \
207 "mov ax, dx" \
208 "shr edx, 16" \
209 parm [es bx] [ax dx] \
210 value [ax dx] \
211 modify exact [ax dx];
212
213#undef ASMAtomicIncU16
214#pragma aux ASMAtomicIncU16 = \
215 ".486" \
216 "mov ax, 1" \
217 "lock xadd es:[bx], ax" \
218 "inc ax" \
219 parm [es bx] \
220 value [ax] \
221 modify exact [ax];
222
223#undef ASMAtomicIncU32
224#pragma aux ASMAtomicIncU32 = \
225 ".486" \
226 "mov edx, 1" \
227 "lock xadd es:[bx], edx" \
228 "inc edx" \
229 "mov ax, dx" \
230 "shr edx, 16" \
231 parm [es bx] \
232 value [ax dx] \
233 modify exact [ax dx];
234
235/* ASMAtomicIncU64: Should be done by C inline or in external file. */
236
237#undef ASMAtomicDecU16
238#pragma aux ASMAtomicDecU16 = \
239 ".486" \
240 "mov ax, 0ffffh" \
241 "lock xadd es:[bx], ax" \
242 "dec ax" \
243 parm [es bx] \
244 value [ax] \
245 modify exact [ax];
246
247#undef ASMAtomicDecU32
248#pragma aux ASMAtomicDecU32 = \
249 ".486" \
250 "mov edx, 0ffffffffh" \
251 "lock xadd es:[bx], edx" \
252 "dec edx" \
253 "mov ax, dx" \
254 "shr edx, 16" \
255 parm [es bx] \
256 value [ax dx] \
257 modify exact [ax dx];
258
259/* ASMAtomicDecU64: Should be done by C inline or in external file. */
260
261#undef ASMAtomicOrU32
262#pragma aux ASMAtomicOrU32 = \
263 "shl edx, 16" \
264 "mov dx, ax" \
265 "lock or es:[bx], edx" \
266 parm [es bx] [ax dx] \
267 modify exact [dx];
268
269/* ASMAtomicOrU64: Should be done by C inline or in external file. */
270
271#undef ASMAtomicAndU32
272#pragma aux ASMAtomicAndU32 = \
273 "shl edx, 16" \
274 "mov dx, ax" \
275 "lock and es:[bx], edx" \
276 parm [es bx] [ax dx] \
277 modify exact [dx];
278
279/* ASMAtomicAndU64: Should be done by C inline or in external file. */
280
281#undef ASMAtomicUoOrU32
282#pragma aux ASMAtomicUoOrU32 = \
283 "shl edx, 16" \
284 "mov dx, ax" \
285 "or es:[bx], edx" \
286 parm [es bx] [ax dx] \
287 modify exact [dx];
288
289/* ASMAtomicUoOrU64: Should be done by C inline or in external file. */
290
291#undef ASMAtomicUoAndU32
292#pragma aux ASMAtomicUoAndU32 = \
293 "shl edx, 16" \
294 "mov dx, ax" \
295 "and es:[bx], edx" \
296 parm [es bx] [ax dx] \
297 modify exact [dx];
298
299/* ASMAtomicUoAndU64: Should be done by C inline or in external file. */
300
301#undef ASMAtomicUoIncU32
302#pragma aux ASMAtomicUoIncU32 = \
303 ".486" \
304 "mov edx, 1" \
305 "xadd es:[bx], edx" \
306 "inc edx" \
307 "mov ax, dx" \
308 "shr edx, 16" \
309 parm [es bx] \
310 value [ax dx] \
311 modify exact [ax dx];
312
313#undef ASMAtomicUoDecU32
314#pragma aux ASMAtomicUoDecU32 = \
315 ".486" \
316 "mov edx, 0ffffffffh" \
317 "xadd es:[bx], edx" \
318 "dec edx" \
319 "mov ax, dx" \
320 "shr edx, 16" \
321 parm [es bx] \
322 value [ax dx] \
323 modify exact [ax dx];
324
325#undef ASMMemZeroPage
326#pragma aux ASMMemZeroPage = \
327 "mov ecx, 1024" \
328 "xor eax, eax" \
329 "rep stosd" \
330 parm [es di] \
331 modify exact [ax cx di];
332
333#undef ASMMemZero32
334#pragma aux ASMMemZero32 = \
335 "and ecx, 0ffffh" /* probably not necessary, lazy bird should check... */ \
336 "shr ecx, 2" \
337 "xor eax, eax" \
338 "rep stosd" \
339 parm [es di] [cx] \
340 modify exact [ax cx di];
341
342#undef ASMMemFill32
343#pragma aux ASMMemFill32 = \
344 "and ecx, 0ffffh" /* probably not necessary, lazy bird should check... */ \
345 "shr ecx, 2" \
346 "shr eax, 16" \
347 "mov ax, dx" \
348 "rol eax, 16" \
349 "rep stosd" \
350 parm [es di] [cx] [ax dx]\
351 modify exact [ax cx di];
352
353#undef ASMProbeReadByte
354#pragma aux ASMProbeReadByte = \
355 "mov al, es:[bx]" \
356 parm [es bx] \
357 value [al] \
358 modify exact [al];
359
360#undef ASMBitSet
361#pragma aux ASMBitSet = \
362 "shl edx, 16" \
363 "mov dx, ax" \
364 "bts es:[bx], edx" \
365 parm [es bx] [ax dx] \
366 modify exact [dx];
367
368#undef ASMAtomicBitSet
369#pragma aux ASMAtomicBitSet = \
370 "shl edx, 16" \
371 "mov dx, ax" \
372 "lock bts es:[bx], edx" \
373 parm [es bx] [ax dx] \
374 modify exact [dx];
375
376#undef ASMBitClear
377#pragma aux ASMBitClear = \
378 "shl edx, 16" \
379 "mov dx, ax" \
380 "btr es:[bx], edx" \
381 parm [es bx] [ax dx] \
382 modify exact [dx];
383
384#undef ASMAtomicBitClear
385#pragma aux ASMAtomicBitClear = \
386 "shl edx, 16" \
387 "mov dx, ax" \
388 "lock btr es:[bx], edx" \
389 parm [es bx] [ax dx] \
390 modify exact [dx];
391
392#undef ASMBitToggle
393#pragma aux ASMBitToggle = \
394 "shl edx, 16" \
395 "mov dx, ax" \
396 "btc es:[bx], edx" \
397 parm [es bx] [ax dx] \
398 modify exact [dx];
399
400#undef ASMAtomicBitToggle
401#pragma aux ASMAtomicBitToggle = \
402 "shl edx, 16" \
403 "mov dx, ax" \
404 "lock btc es:[bx], edx" \
405 parm [es bx] [ax dx] \
406 modify exact [dx];
407
408#undef ASMBitTestAndSet
409#pragma aux ASMBitTestAndSet = \
410 "shl edx, 16" \
411 "mov dx, ax" \
412 "bts es:[bx], edx" \
413 "setc al" \
414 parm [es bx] [ax dx] \
415 value [al] \
416 modify exact [ax dx];
417
418#undef ASMAtomicBitTestAndSet
419#pragma aux ASMAtomicBitTestAndSet = \
420 "shl edx, 16" \
421 "mov dx, ax" \
422 "lock bts es:[bx], edx" \
423 "setc al" \
424 parm [es bx] [ax dx] \
425 value [al] \
426 modify exact [ax dx];
427
428#undef ASMBitTestAndClear
429#pragma aux ASMBitTestAndClear = \
430 "shl edx, 16" \
431 "mov dx, ax" \
432 "btr es:[bx], edx" \
433 "setc al" \
434 parm [es bx] [ax dx] \
435 value [al] \
436 modify exact [ax dx];
437
438#undef ASMAtomicBitTestAndClear
439#pragma aux ASMAtomicBitTestAndClear = \
440 "shl edx, 16" \
441 "mov dx, ax" \
442 "lock btr es:[bx], edx" \
443 "setc al" \
444 parm [es bx] [ax dx] \
445 value [al] \
446 modify exact [ax dx];
447
448#undef ASMBitTestAndToggle
449#pragma aux ASMBitTestAndToggle = \
450 "shl edx, 16" \
451 "mov dx, ax" \
452 "btc es:[bx], edx" \
453 "setc al" \
454 parm [es bx] [ax dx] \
455 value [al] \
456 modify exact [ax dx];
457
458#undef ASMAtomicBitTestAndToggle
459#pragma aux ASMAtomicBitTestAndToggle = \
460 "shl edx, 16" \
461 "mov dx, ax" \
462 "lock btc es:[bx], edx" \
463 "setc al" \
464 parm [es bx] [ax dx] \
465 value [al] \
466 modify exact [ax dx];
467
468#undef ASMBitTest
469#pragma aux ASMBitTest = \
470 "shl edx, 16" \
471 "mov dx, ax" \
472 "bt es:[bx], edx" \
473 "setc al" \
474 parm [es bx] [ax dx] nomemory \
475 value [al] \
476 modify exact [ax dx] nomemory;
477
478#if 0
479/** @todo this is way to much inline assembly, better off in an external function. */
480#undef ASMBitFirstClear
481#pragma aux ASMBitFirstClear = \
482 "mov bx, di" /* save start of bitmap for later */ \
483 "shl ecx, 16" \
484 "mov cx, ax" /* ecx = cBits */ \
485 "add ecx, 31" \
486 "shr ecx, 5" /* cDWord = RT_ALIGN_32(cBits, 32) / 32; */ \
487 "mov eax, 0ffffffffh" \
488 "mov edx, eax" /* default return value */ \
489 "repe scasd" \
490 "je done" \
491 "sub di, 4" /* rewind di */ \
492 "xor eax, es:[di]" /* load inverted bits */ \
493 "sub di, bx" /* calc byte offset */ \
494 "movzx edi, di" \
495 "shl edi, 3" /* convert byte to bit offset */ \
496 "bsf edx, eax" \
497 "add edx, edi" \
498 "done:" \
499 "mov eax, edx" \
500 "shr edx, 16" \
501 parm [es di] [ax cx] \
502 value [ax dx] \
503 modify exact [ax bx cx dx di];
504
505/* ASMBitNextClear: Too much work, do when needed. */
506
507/** @todo this is way to much inline assembly, better off in an external function. */
508#undef ASMBitFirstSet
509#pragma aux ASMBitFirstSet = \
510 "mov bx, di" /* save start of bitmap for later */ \
511 "shl ecx, 16" \
512 "mov cx, ax" /* ecx = cBits */ \
513 "add ecx, 31" \
514 "shr ecx, 5" /* cDWord = RT_ALIGN_32(cBits, 32) / 32; */ \
515 "xor eax, eax" \
516 "mov edx, 0ffffffffh" /* default return value */ \
517 "repe scasd" \
518 "je done" \
519 "sub di, 4" /* rewind di */ \
520 "mov eax, es:[di]" /* reload previous dword */ \
521 "sub di, bx" /* calc byte offset */ \
522 "movzx edi, di" \
523 "shl edi, 3" /* convert byte to bit offset */ \
524 "bsf edx, eax" /* find first set bit in dword */ \
525 "add edx, edi" /* calc final bit number */ \
526 "done:" \
527 "mov eax, edx" \
528 "shr edx, 16" \
529 parm [es di] [ax cx] \
530 value [ax dx] \
531 modify exact [ax bx cx dx di];
532
533/* ASMBitNextSet: Too much work, do when needed. */
534#else
535/* ASMBitFirstClear: External file. */
536/* ASMBitNextClear: External file. */
537/* ASMBitFirstSet: External file. */
538/* ASMBitNextSet: External file. */
539#endif
540
541#undef ASMBitFirstSetU32
542#pragma aux ASMBitFirstSetU32 = \
543 "shl edx, 16" \
544 "mov dx, ax" \
545 "bsf eax, edx" \
546 "jz not_found" \
547 "inc ax" \
548 "jmp done" \
549 "not_found:" \
550 "xor ax, ax" \
551 "done:" \
552 parm [ax dx] nomemory \
553 value [ax] \
554 modify exact [ax dx] nomemory;
555
556#undef ASMBitFirstSetU64
557#pragma aux ASMBitFirstSetU64 = \
558 "shl ecx, 16" \
559 "mov cx, dx" \
560 "bsf ecx, ecx" \
561 "jz not_found_low" \
562 "mov ax, cx" \
563 "inc ax" \
564 "jmp done" \
565 \
566 "not_found_low:" \
567 "shr eax, 16" \
568 "mov ax, bx" \
569 "bsf eax, eax" \
570 "jz not_found_high" \
571 "add ax, 33" \
572 "jmp done" \
573 \
574 "not_found_high:" \
575 "xor ax, ax" \
576 "done:" \
577 parm [dx cx bx ax] nomemory \
578 value [ax] \
579 modify exact [ax cx] nomemory;
580
581#undef ASMBitFirstSetU16
582#pragma aux ASMBitFirstSetU16 = \
583 "bsf ax, ax" \
584 "jz not_found" \
585 "inc ax" \
586 "jmp done" \
587 "not_found:" \
588 "xor ax, ax" \
589 "done:" \
590 parm [ax] nomemory \
591 value [ax] \
592 modify exact [ax] nomemory;
593
594#undef ASMBitLastSetU32
595#pragma aux ASMBitLastSetU32 = \
596 "shl edx, 16" \
597 "mov dx, ax" \
598 "bsr eax, edx" \
599 "jz not_found" \
600 "inc ax" \
601 "jmp done" \
602 "not_found:" \
603 "xor ax, ax" \
604 "done:" \
605 parm [ax dx] nomemory \
606 value [ax] \
607 modify exact [ax dx] nomemory;
608
609#undef ASMBitLastSetU64
610#pragma aux ASMBitLastSetU64 = \
611 "shl ecx, 16" \
612 "mov cx, dx" \
613 "bsf ecx, ecx" \
614 "jz not_found_low" \
615 "mov ax, cx" \
616 "inc ax" \
617 "jmp done" \
618 \
619 "not_found_low:" \
620 "shr eax, 16" \
621 "mov ax, bx" \
622 "bsf eax, eax" \
623 "jz not_found_high" \
624 "add ax, 33" \
625 "jmp done" \
626 \
627 "not_found_high:" \
628 "xor ax, ax" \
629 "done:" \
630 parm [dx cx bx ax] nomemory \
631 value [ax] \
632 modify exact [ax cx] nomemory;
633
634#undef ASMBitLastSetU16
635#pragma aux ASMBitLastSetU16 = \
636 "bsr ax, ax" \
637 "jz not_found" \
638 "inc ax" \
639 "jmp done" \
640 "not_found:" \
641 "xor ax, ax" \
642 "done:" \
643 parm [ax] nomemory \
644 value [ax] \
645 modify exact [ax] nomemory;
646
647#undef ASMByteSwapU16
648#pragma aux ASMByteSwapU16 = \
649 "ror ax, 8" \
650 parm [ax] nomemory \
651 value [ax] \
652 modify exact [ax] nomemory;
653
654#undef ASMByteSwapU32
655#pragma aux ASMByteSwapU32 = \
656 "xchg ax, dx" \
657 parm [ax dx] nomemory \
658 value [ax dx] \
659 modify exact [ax dx] nomemory;
660
661#undef ASMRotateLeftU32
662#pragma aux ASMRotateLeftU32 = \
663 "shl edx, 16" \
664 "mov dx, ax" \
665 "rol edx, cl" \
666 "mov eax, edx" \
667 "shr edx, 16" \
668 parm [ax dx] [cx] nomemory \
669 value [ax dx] \
670 modify exact [ax dx] nomemory;
671
672#undef ASMRotateRightU32
673#pragma aux ASMRotateRightU32 = \
674 "shl edx, 16" \
675 "mov dx, ax" \
676 "ror edx, cl" \
677 "mov eax, edx" \
678 "shr edx, 16" \
679 parm [ax dx] [cx] nomemory \
680 value [ax dx] \
681 modify exact [ax dx] nomemory;
682
683#endif
Note: See TracBrowser for help on using the repository browser.

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