VirtualBox

source: vbox/trunk/include/iprt/asm-watcom-x86-32.h@ 58813

Last change on this file since 58813 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: 13.8 KB
Line 
1/** @file
2 * IPRT - Assembly Functions, x86 32-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_32_h
30#define ___iprt_asm_watcom_x86_32_h
31
32#ifndef __FLAT__
33# error "Only works with flat pointers! (-mf)"
34#endif
35
36/*
37 * Note! The #undef that preceds the #pragma aux statements is for undoing
38 * the mangling, because the symbol in #pragma aux [symbol] statements
39 * doesn't get subjected to preprocessing. This is also why we include
40 * the watcom header at the top rather than at the bottom of the
41 * asm-amd64-x86.h file.
42 */
43
44#undef ASMCompilerBarrier
45#if 0 /* overkill version. */
46# pragma aux ASMCompilerBarrier = \
47 "nop" \
48 parm [] \
49 modify exact [eax ebx ecx edx es ds fs gs];
50#else
51# pragma aux ASMCompilerBarrier = \
52 "" \
53 parm [] \
54 modify exact [];
55#endif
56
57#undef ASMNopPause
58#pragma aux ASMNopPause = \
59 ".686p" \
60 ".xmm2" \
61 "pause" \
62 parm [] nomemory \
63 modify exact [] nomemory;
64
65#undef ASMAtomicXchgU8
66#pragma aux ASMAtomicXchgU8 = \
67 "xchg [ecx], al" \
68 parm [ecx] [al] \
69 value [al] \
70 modify exact [al];
71
72#undef ASMAtomicXchgU16
73#pragma aux ASMAtomicXchgU16 = \
74 "xchg [ecx], ax" \
75 parm [ecx] [ax] \
76 value [ax] \
77 modify exact [ax];
78
79#undef ASMAtomicXchgU32
80#pragma aux ASMAtomicXchgU32 = \
81 "xchg [ecx], eax" \
82 parm [ecx] [eax] \
83 value [eax] \
84 modify exact [eax];
85
86#undef ASMAtomicXchgU64
87#pragma aux ASMAtomicXchgU64 = \
88 ".586" \
89 "try_again:" \
90 "lock cmpxchg8b [esi]" \
91 "jnz try_again" \
92 parm [esi] [ebx ecx] \
93 value [eax edx] \
94 modify exact [edx ecx ebx eax];
95
96#undef ASMAtomicCmpXchgU8
97#pragma aux ASMAtomicCmpXchgU8 = \
98 ".486" \
99 "lock cmpxchg [edx], cl" \
100 "setz al" \
101 parm [edx] [cl] [al] \
102 value [al] \
103 modify exact [al];
104
105#undef ASMAtomicCmpXchgU16
106#pragma aux ASMAtomicCmpXchgU16 = \
107 ".486" \
108 "lock cmpxchg [edx], cx" \
109 "setz al" \
110 parm [edx] [cx] [ax] \
111 value [al] \
112 modify exact [ax];
113
114#undef ASMAtomicCmpXchgU32
115#pragma aux ASMAtomicCmpXchgU32 = \
116 ".486" \
117 "lock cmpxchg [edx], ecx" \
118 "setz al" \
119 parm [edx] [ecx] [eax] \
120 value [al] \
121 modify exact [eax];
122
123#undef ASMAtomicCmpXchgU64
124#pragma aux ASMAtomicCmpXchgU64 = \
125 ".586" \
126 "lock cmpxchg8b [edi]" \
127 "setz al" \
128 parm [edi] [ebx ecx] [eax edx] \
129 value [al] \
130 modify exact [eax edx];
131
132#undef ASMAtomicCmpXchgExU32
133#pragma aux ASMAtomicCmpXchgExU32 = \
134 ".586" \
135 "lock cmpxchg [edx], ecx" \
136 "mov [edi], eax" \
137 "setz al" \
138 parm [edx] [ecx] [eax] [edi] \
139 value [al] \
140 modify exact [eax];
141
142#undef ASMAtomicCmpXchgExU64
143#pragma aux ASMAtomicCmpXchgExU64 = \
144 ".586" \
145 "lock cmpxchg8b [edi]" \
146 "mov [esi], eax" \
147 "mov [esi + 4], edx" \
148 "setz al" \
149 parm [edi] [ebx ecx] [eax edx] [esi] \
150 value [al] \
151 modify exact [eax edx];
152
153#undef ASMSerializeInstruction
154#pragma aux ASMSerializeInstruction = \
155 ".586" \
156 "xor eax, eax" \
157 "cpuid" \
158 parm [] \
159 modify exact [eax ebx ecx edx];
160
161#undef ASMAtomicReadU64
162#pragma aux ASMAtomicReadU64 = \
163 ".586" \
164 "xor eax, eax" \
165 "mov edx, eax" \
166 "mov ebx, eax" \
167 "mov ecx, eax" \
168 "lock cmpxchg8b [edi]" \
169 parm [edi] \
170 value [eax edx] \
171 modify exact [eax ebx ecx edx];
172
173#undef ASMAtomicUoReadU64
174#pragma aux ASMAtomicUoReadU64 = \
175 ".586" \
176 "xor eax, eax" \
177 "mov edx, eax" \
178 "mov ebx, eax" \
179 "mov ecx, eax" \
180 "lock cmpxchg8b [edi]" \
181 parm [edi] \
182 value [eax edx] \
183 modify exact [eax ebx ecx edx];
184
185#undef ASMAtomicAddU16
186#pragma aux ASMAtomicAddU16 = \
187 ".486" \
188 "lock xadd [ecx], ax" \
189 parm [ecx] [ax] \
190 value [ax] \
191 modify exact [ax];
192
193#undef ASMAtomicAddU32
194#pragma aux ASMAtomicAddU32 = \
195 ".486" \
196 "lock xadd [ecx], eax" \
197 parm [ecx] [eax] \
198 value [eax] \
199 modify exact [eax];
200
201#undef ASMAtomicIncU16
202#pragma aux ASMAtomicIncU16 = \
203 ".486" \
204 "mov ax, 1" \
205 "lock xadd [ecx], ax" \
206 "inc ax" \
207 parm [ecx] \
208 value [ax] \
209 modify exact [ax];
210
211#undef ASMAtomicIncU32
212#pragma aux ASMAtomicIncU32 = \
213 ".486" \
214 "mov eax, 1" \
215 "lock xadd [ecx], eax" \
216 "inc eax" \
217 parm [ecx] \
218 value [eax] \
219 modify exact [eax];
220
221/* ASMAtomicIncU64: Should be done by C inline or in external file. */
222
223#undef ASMAtomicDecU16
224#pragma aux ASMAtomicDecU16 = \
225 ".486" \
226 "mov ax, 0ffffh" \
227 "lock xadd [ecx], ax" \
228 "dec ax" \
229 parm [ecx] \
230 value [ax] \
231 modify exact [ax];
232
233#undef ASMAtomicDecU32
234#pragma aux ASMAtomicDecU32 = \
235 ".486" \
236 "mov eax, 0ffffffffh" \
237 "lock xadd [ecx], eax" \
238 "dec eax" \
239 parm [ecx] \
240 value [eax] \
241 modify exact [eax];
242
243/* ASMAtomicDecU64: Should be done by C inline or in external file. */
244
245#undef ASMAtomicOrU32
246#pragma aux ASMAtomicOrU32 = \
247 "lock or [ecx], eax" \
248 parm [ecx] [eax] \
249 modify exact [];
250
251/* ASMAtomicOrU64: Should be done by C inline or in external file. */
252
253#undef ASMAtomicAndU32
254#pragma aux ASMAtomicAndU32 = \
255 "lock and [ecx], eax" \
256 parm [ecx] [eax] \
257 modify exact [];
258
259/* ASMAtomicAndU64: Should be done by C inline or in external file. */
260
261#undef ASMAtomicUoOrU32
262#pragma aux ASMAtomicUoOrU32 = \
263 "or [ecx], eax" \
264 parm [ecx] [eax] \
265 modify exact [];
266
267/* ASMAtomicUoOrU64: Should be done by C inline or in external file. */
268
269#undef ASMAtomicUoAndU32
270#pragma aux ASMAtomicUoAndU32 = \
271 "and [ecx], eax" \
272 parm [ecx] [eax] \
273 modify exact [];
274
275/* ASMAtomicUoAndU64: Should be done by C inline or in external file. */
276
277#undef ASMAtomicUoIncU32
278#pragma aux ASMAtomicUoIncU32 = \
279 ".486" \
280 "xadd [ecx], eax" \
281 "inc eax" \
282 parm [ecx] \
283 value [eax] \
284 modify exact [eax];
285
286#undef ASMAtomicUoDecU32
287#pragma aux ASMAtomicUoDecU32 = \
288 ".486" \
289 "mov eax, 0ffffffffh" \
290 "xadd [ecx], eax" \
291 "dec eax" \
292 parm [ecx] \
293 value [eax] \
294 modify exact [eax];
295
296#undef ASMMemZeroPage
297#pragma aux ASMMemZeroPage = \
298 "mov ecx, 1024" \
299 "xor eax, eax" \
300 "rep stosd" \
301 parm [edi] \
302 modify exact [eax ecx edi];
303
304#undef ASMMemZero32
305#pragma aux ASMMemZero32 = \
306 "shr ecx, 2" \
307 "xor eax, eax" \
308 "rep stosd" \
309 parm [edi] [ecx] \
310 modify exact [eax ecx edi];
311
312#undef ASMMemFill32
313#pragma aux ASMMemFill32 = \
314 "shr ecx, 2" \
315 "rep stosd" \
316 parm [edi] [ecx] [eax]\
317 modify exact [ecx edi];
318
319#undef ASMProbeReadByte
320#pragma aux ASMProbeReadByte = \
321 "mov al, [ecx]" \
322 parm [ecx] \
323 value [al] \
324 modify exact [al];
325
326#undef ASMBitSet
327#pragma aux ASMBitSet = \
328 "bts [ecx], eax" \
329 parm [ecx] [eax] \
330 modify exact [];
331
332#undef ASMAtomicBitSet
333#pragma aux ASMAtomicBitSet = \
334 "lock bts [ecx], eax" \
335 parm [ecx] [eax] \
336 modify exact [];
337
338#undef ASMBitClear
339#pragma aux ASMBitClear = \
340 "btr [ecx], eax" \
341 parm [ecx] [eax] \
342 modify exact [];
343
344#undef ASMAtomicBitClear
345#pragma aux ASMAtomicBitClear = \
346 "lock btr [ecx], eax" \
347 parm [ecx] [eax] \
348 modify exact [];
349
350#undef ASMBitToggle
351#pragma aux ASMBitToggle = \
352 "btc [ecx], eax" \
353 parm [ecx] [eax] \
354 modify exact [];
355
356#undef ASMAtomicBitToggle
357#pragma aux ASMAtomicBitToggle = \
358 "lock btc [ecx], eax" \
359 parm [ecx] [eax] \
360 modify exact [];
361
362
363#undef ASMBitTestAndSet
364#pragma aux ASMBitTestAndSet = \
365 "bts [ecx], eax" \
366 "setc al" \
367 parm [ecx] [eax] \
368 value [al] \
369 modify exact [eax];
370
371#undef ASMAtomicBitTestAndSet
372#pragma aux ASMAtomicBitTestAndSet = \
373 "lock bts [ecx], eax" \
374 "setc al" \
375 parm [ecx] [eax] \
376 value [al] \
377 modify exact [eax];
378
379#undef ASMBitTestAndClear
380#pragma aux ASMBitTestAndClear = \
381 "btr [ecx], eax" \
382 "setc al" \
383 parm [ecx] [eax] \
384 value [al] \
385 modify exact [eax];
386
387#undef ASMAtomicBitTestAndClear
388#pragma aux ASMAtomicBitTestAndClear = \
389 "lock btr [ecx], eax" \
390 "setc al" \
391 parm [ecx] [eax] \
392 value [al] \
393 modify exact [eax];
394
395#undef ASMBitTestAndToggle
396#pragma aux ASMBitTestAndToggle = \
397 "btc [ecx], eax" \
398 "setc al" \
399 parm [ecx] [eax] \
400 value [al] \
401 modify exact [eax];
402
403#undef ASMAtomicBitTestAndToggle
404#pragma aux ASMAtomicBitTestAndToggle = \
405 "lock btc [ecx], eax" \
406 "setc al" \
407 parm [ecx] [eax] \
408 value [al] \
409 modify exact [eax];
410
411#undef ASMBitTest
412#pragma aux ASMBitTest = \
413 "bt [ecx], eax" \
414 "setc al" \
415 parm [ecx] [eax] nomemory \
416 value [al] \
417 modify exact [eax] nomemory;
418
419#if 0
420/** @todo this is way to much inline assembly, better off in an external function. */
421#undef ASMBitFirstClear
422#pragma aux ASMBitFirstClear = \
423 "mov edx, edi" /* save start of bitmap for later */ \
424 "add ecx, 31" \
425 "shr ecx, 5" /* cDWord = RT_ALIGN_32(cBits, 32) / 32; */ \
426 "mov eax, 0ffffffffh" \
427 "repe scasd" \
428 "je done" \
429 "lea edi, [edi - 4]" /* rewind edi */ \
430 "xor eax, [edi]" /* load inverted bits */ \
431 "sub edi, edx" /* calc byte offset */ \
432 "shl edi, 3" /* convert byte to bit offset */ \
433 "mov edx, eax" \
434 "bsf eax, edx" \
435 "add eax, edi" \
436 "done:" \
437 parm [edi] [ecx] \
438 value [eax] \
439 modify exact [eax ecx edx edi];
440
441/* ASMBitNextClear: Too much work, do when needed. */
442
443/** @todo this is way to much inline assembly, better off in an external function. */
444#undef ASMBitFirstSet
445#pragma aux ASMBitFirstSet = \
446 "mov edx, edi" /* save start of bitmap for later */ \
447 "add ecx, 31" \
448 "shr ecx, 5" /* cDWord = RT_ALIGN_32(cBits, 32) / 32; */ \
449 "mov eax, 0ffffffffh" \
450 "repe scasd" \
451 "je done" \
452 "lea edi, [edi - 4]" /* rewind edi */ \
453 "mov eax, [edi]" /* reload previous dword */ \
454 "sub edi, edx" /* calc byte offset */ \
455 "shl edi, 3" /* convert byte to bit offset */ \
456 "mov edx, eax" \
457 "bsf eax, edx" \
458 "add eax, edi" \
459 "done:" \
460 parm [edi] [ecx] \
461 value [eax] \
462 modify exact [eax ecx edx edi];
463
464/* ASMBitNextSet: Too much work, do when needed. */
465#else
466/* ASMBitFirstClear: External file. */
467/* ASMBitNextClear: External file. */
468/* ASMBitFirstSet: External file. */
469/* ASMBitNextSet: External file. */
470#endif
471
472#undef ASMBitFirstSetU32
473#pragma aux ASMBitFirstSetU32 = \
474 "bsf eax, eax" \
475 "jz not_found" \
476 "inc eax" \
477 "jmp done" \
478 "not_found:" \
479 "xor eax, eax" \
480 "done:" \
481 parm [eax] nomemory \
482 value [eax] \
483 modify exact [eax] nomemory;
484
485#undef ASMBitFirstSetU64
486#pragma aux ASMBitFirstSetU64 = \
487 "bsf eax, eax" \
488 "jz not_found_low" \
489 "inc eax" \
490 "jmp done" \
491 \
492 "not_found_low:" \
493 "bsf eax, edx" \
494 "jz not_found_high" \
495 "add eax, 33" \
496 "jmp done" \
497 \
498 "not_found_high:" \
499 "xor eax, eax" \
500 "done:" \
501 parm [eax edx] nomemory \
502 value [eax] \
503 modify exact [eax] nomemory;
504
505#undef ASMBitFirstSetU16
506#pragma aux ASMBitFirstSetU16 = \
507 "movzx eax, ax" \
508 "bsf eax, eax" \
509 "jz not_found" \
510 "inc eax" \
511 "jmp done" \
512 "not_found:" \
513 "xor eax, eax" \
514 "done:" \
515 parm [ax] nomemory \
516 value [eax] \
517 modify exact [eax] nomemory;
518
519#undef ASMBitLastSetU32
520#pragma aux ASMBitLastSetU32 = \
521 "bsr eax, eax" \
522 "jz not_found" \
523 "inc eax" \
524 "jmp done" \
525 "not_found:" \
526 "xor eax, eax" \
527 "done:" \
528 parm [eax] nomemory \
529 value [eax] \
530 modify exact [eax] nomemory;
531
532#undef ASMBitLastSetU64
533#pragma aux ASMBitLastSetU64 = \
534 "bsf eax, eax" \
535 "jz not_found_low" \
536 "inc eax" \
537 "jmp done" \
538 \
539 "not_found_low:" \
540 "bsf eax, edx" \
541 "jz not_found_high" \
542 "add eax, 33" \
543 "jmp done" \
544 \
545 "not_found_high:" \
546 "xor eax, eax" \
547 "done:" \
548 parm [eax edx] nomemory \
549 value [eax] \
550 modify exact [eax] nomemory;
551
552#undef ASMBitLastSetU16
553#pragma aux ASMBitLastSetU16 = \
554 "movzx eax, ax" \
555 "bsr eax, eax" \
556 "jz not_found" \
557 "inc eax" \
558 "jmp done" \
559 "not_found:" \
560 "xor eax, eax" \
561 "done:" \
562 parm [ax] nomemory \
563 value [eax] \
564 modify exact [eax] nomemory;
565
566#undef ASMByteSwapU16
567#pragma aux ASMByteSwapU16 = \
568 "ror ax, 8" \
569 parm [ax] nomemory \
570 value [ax] \
571 modify exact [ax] nomemory;
572
573#undef ASMByteSwapU32
574#pragma aux ASMByteSwapU32 = \
575 "bswap eax" \
576 parm [eax] nomemory \
577 value [eax] \
578 modify exact [eax] nomemory;
579
580#undef ASMRotateLeftU32
581#pragma aux ASMRotateLeftU32 = \
582 "rol eax, cl" \
583 parm [eax] [ecx] nomemory \
584 value [eax] \
585 modify exact [eax] nomemory;
586
587#undef ASMRotateRightU32
588#pragma aux ASMRotateRightU32 = \
589 "ror eax, cl" \
590 parm [eax] [ecx] nomemory \
591 value [eax] \
592 modify exact [eax] nomemory;
593
594#endif
595
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