VirtualBox

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

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

iprt/asm.h: Experimented with alternative serializating instructions (ASMSerializeInstruction), cpuid(0) is very reasonable compared to iret (rdtscp would be preferable).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 14.2 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 ASMSerializeInstructionCpuId
154#pragma aux ASMSerializeInstructionCpuId = \
155 ".586" \
156 "xor eax, eax" \
157 "cpuid" \
158 parm [] \
159 modify exact [eax ebx ecx edx];
160
161#undef ASMSerializeInstructionIRet
162#pragma aux ASMSerializeInstructionIRet = \
163 "pushf" \
164 "push cs" \
165 "call foo" /* 'push offset done' doesn't work */ \
166 "jmp done" \
167 "foo:" \
168 "iret" \
169 "done:" \
170 parm [] \
171 modify exact [];
172
173#undef ASMSerializeInstructionRdTscp
174#pragma aux ASMSerializeInstructionRdTscp = \
175 0x0f 0x01 0xf9 \
176 parm [] \
177 modify exact [eax edx ecx];
178
179#undef ASMAtomicReadU64
180#pragma aux ASMAtomicReadU64 = \
181 ".586" \
182 "xor eax, eax" \
183 "mov edx, eax" \
184 "mov ebx, eax" \
185 "mov ecx, eax" \
186 "lock cmpxchg8b [edi]" \
187 parm [edi] \
188 value [eax edx] \
189 modify exact [eax ebx ecx edx];
190
191#undef ASMAtomicUoReadU64
192#pragma aux ASMAtomicUoReadU64 = \
193 ".586" \
194 "xor eax, eax" \
195 "mov edx, eax" \
196 "mov ebx, eax" \
197 "mov ecx, eax" \
198 "lock cmpxchg8b [edi]" \
199 parm [edi] \
200 value [eax edx] \
201 modify exact [eax ebx ecx edx];
202
203#undef ASMAtomicAddU16
204#pragma aux ASMAtomicAddU16 = \
205 ".486" \
206 "lock xadd [ecx], ax" \
207 parm [ecx] [ax] \
208 value [ax] \
209 modify exact [ax];
210
211#undef ASMAtomicAddU32
212#pragma aux ASMAtomicAddU32 = \
213 ".486" \
214 "lock xadd [ecx], eax" \
215 parm [ecx] [eax] \
216 value [eax] \
217 modify exact [eax];
218
219#undef ASMAtomicIncU16
220#pragma aux ASMAtomicIncU16 = \
221 ".486" \
222 "mov ax, 1" \
223 "lock xadd [ecx], ax" \
224 "inc ax" \
225 parm [ecx] \
226 value [ax] \
227 modify exact [ax];
228
229#undef ASMAtomicIncU32
230#pragma aux ASMAtomicIncU32 = \
231 ".486" \
232 "mov eax, 1" \
233 "lock xadd [ecx], eax" \
234 "inc eax" \
235 parm [ecx] \
236 value [eax] \
237 modify exact [eax];
238
239/* ASMAtomicIncU64: Should be done by C inline or in external file. */
240
241#undef ASMAtomicDecU16
242#pragma aux ASMAtomicDecU16 = \
243 ".486" \
244 "mov ax, 0ffffh" \
245 "lock xadd [ecx], ax" \
246 "dec ax" \
247 parm [ecx] \
248 value [ax] \
249 modify exact [ax];
250
251#undef ASMAtomicDecU32
252#pragma aux ASMAtomicDecU32 = \
253 ".486" \
254 "mov eax, 0ffffffffh" \
255 "lock xadd [ecx], eax" \
256 "dec eax" \
257 parm [ecx] \
258 value [eax] \
259 modify exact [eax];
260
261/* ASMAtomicDecU64: Should be done by C inline or in external file. */
262
263#undef ASMAtomicOrU32
264#pragma aux ASMAtomicOrU32 = \
265 "lock or [ecx], eax" \
266 parm [ecx] [eax] \
267 modify exact [];
268
269/* ASMAtomicOrU64: Should be done by C inline or in external file. */
270
271#undef ASMAtomicAndU32
272#pragma aux ASMAtomicAndU32 = \
273 "lock and [ecx], eax" \
274 parm [ecx] [eax] \
275 modify exact [];
276
277/* ASMAtomicAndU64: Should be done by C inline or in external file. */
278
279#undef ASMAtomicUoOrU32
280#pragma aux ASMAtomicUoOrU32 = \
281 "or [ecx], eax" \
282 parm [ecx] [eax] \
283 modify exact [];
284
285/* ASMAtomicUoOrU64: Should be done by C inline or in external file. */
286
287#undef ASMAtomicUoAndU32
288#pragma aux ASMAtomicUoAndU32 = \
289 "and [ecx], eax" \
290 parm [ecx] [eax] \
291 modify exact [];
292
293/* ASMAtomicUoAndU64: Should be done by C inline or in external file. */
294
295#undef ASMAtomicUoIncU32
296#pragma aux ASMAtomicUoIncU32 = \
297 ".486" \
298 "xadd [ecx], eax" \
299 "inc eax" \
300 parm [ecx] \
301 value [eax] \
302 modify exact [eax];
303
304#undef ASMAtomicUoDecU32
305#pragma aux ASMAtomicUoDecU32 = \
306 ".486" \
307 "mov eax, 0ffffffffh" \
308 "xadd [ecx], eax" \
309 "dec eax" \
310 parm [ecx] \
311 value [eax] \
312 modify exact [eax];
313
314#undef ASMMemZeroPage
315#pragma aux ASMMemZeroPage = \
316 "mov ecx, 1024" \
317 "xor eax, eax" \
318 "rep stosd" \
319 parm [edi] \
320 modify exact [eax ecx edi];
321
322#undef ASMMemZero32
323#pragma aux ASMMemZero32 = \
324 "shr ecx, 2" \
325 "xor eax, eax" \
326 "rep stosd" \
327 parm [edi] [ecx] \
328 modify exact [eax ecx edi];
329
330#undef ASMMemFill32
331#pragma aux ASMMemFill32 = \
332 "shr ecx, 2" \
333 "rep stosd" \
334 parm [edi] [ecx] [eax]\
335 modify exact [ecx edi];
336
337#undef ASMProbeReadByte
338#pragma aux ASMProbeReadByte = \
339 "mov al, [ecx]" \
340 parm [ecx] \
341 value [al] \
342 modify exact [al];
343
344#undef ASMBitSet
345#pragma aux ASMBitSet = \
346 "bts [ecx], eax" \
347 parm [ecx] [eax] \
348 modify exact [];
349
350#undef ASMAtomicBitSet
351#pragma aux ASMAtomicBitSet = \
352 "lock bts [ecx], eax" \
353 parm [ecx] [eax] \
354 modify exact [];
355
356#undef ASMBitClear
357#pragma aux ASMBitClear = \
358 "btr [ecx], eax" \
359 parm [ecx] [eax] \
360 modify exact [];
361
362#undef ASMAtomicBitClear
363#pragma aux ASMAtomicBitClear = \
364 "lock btr [ecx], eax" \
365 parm [ecx] [eax] \
366 modify exact [];
367
368#undef ASMBitToggle
369#pragma aux ASMBitToggle = \
370 "btc [ecx], eax" \
371 parm [ecx] [eax] \
372 modify exact [];
373
374#undef ASMAtomicBitToggle
375#pragma aux ASMAtomicBitToggle = \
376 "lock btc [ecx], eax" \
377 parm [ecx] [eax] \
378 modify exact [];
379
380
381#undef ASMBitTestAndSet
382#pragma aux ASMBitTestAndSet = \
383 "bts [ecx], eax" \
384 "setc al" \
385 parm [ecx] [eax] \
386 value [al] \
387 modify exact [eax];
388
389#undef ASMAtomicBitTestAndSet
390#pragma aux ASMAtomicBitTestAndSet = \
391 "lock bts [ecx], eax" \
392 "setc al" \
393 parm [ecx] [eax] \
394 value [al] \
395 modify exact [eax];
396
397#undef ASMBitTestAndClear
398#pragma aux ASMBitTestAndClear = \
399 "btr [ecx], eax" \
400 "setc al" \
401 parm [ecx] [eax] \
402 value [al] \
403 modify exact [eax];
404
405#undef ASMAtomicBitTestAndClear
406#pragma aux ASMAtomicBitTestAndClear = \
407 "lock btr [ecx], eax" \
408 "setc al" \
409 parm [ecx] [eax] \
410 value [al] \
411 modify exact [eax];
412
413#undef ASMBitTestAndToggle
414#pragma aux ASMBitTestAndToggle = \
415 "btc [ecx], eax" \
416 "setc al" \
417 parm [ecx] [eax] \
418 value [al] \
419 modify exact [eax];
420
421#undef ASMAtomicBitTestAndToggle
422#pragma aux ASMAtomicBitTestAndToggle = \
423 "lock btc [ecx], eax" \
424 "setc al" \
425 parm [ecx] [eax] \
426 value [al] \
427 modify exact [eax];
428
429#undef ASMBitTest
430#pragma aux ASMBitTest = \
431 "bt [ecx], eax" \
432 "setc al" \
433 parm [ecx] [eax] nomemory \
434 value [al] \
435 modify exact [eax] nomemory;
436
437#if 0
438/** @todo this is way to much inline assembly, better off in an external function. */
439#undef ASMBitFirstClear
440#pragma aux ASMBitFirstClear = \
441 "mov edx, edi" /* save start of bitmap for later */ \
442 "add ecx, 31" \
443 "shr ecx, 5" /* cDWord = RT_ALIGN_32(cBits, 32) / 32; */ \
444 "mov eax, 0ffffffffh" \
445 "repe scasd" \
446 "je done" \
447 "lea edi, [edi - 4]" /* rewind edi */ \
448 "xor eax, [edi]" /* load inverted bits */ \
449 "sub edi, edx" /* calc byte offset */ \
450 "shl edi, 3" /* convert byte to bit offset */ \
451 "mov edx, eax" \
452 "bsf eax, edx" \
453 "add eax, edi" \
454 "done:" \
455 parm [edi] [ecx] \
456 value [eax] \
457 modify exact [eax ecx edx edi];
458
459/* ASMBitNextClear: Too much work, do when needed. */
460
461/** @todo this is way to much inline assembly, better off in an external function. */
462#undef ASMBitFirstSet
463#pragma aux ASMBitFirstSet = \
464 "mov edx, edi" /* save start of bitmap for later */ \
465 "add ecx, 31" \
466 "shr ecx, 5" /* cDWord = RT_ALIGN_32(cBits, 32) / 32; */ \
467 "mov eax, 0ffffffffh" \
468 "repe scasd" \
469 "je done" \
470 "lea edi, [edi - 4]" /* rewind edi */ \
471 "mov eax, [edi]" /* reload previous dword */ \
472 "sub edi, edx" /* calc byte offset */ \
473 "shl edi, 3" /* convert byte to bit offset */ \
474 "mov edx, eax" \
475 "bsf eax, edx" \
476 "add eax, edi" \
477 "done:" \
478 parm [edi] [ecx] \
479 value [eax] \
480 modify exact [eax ecx edx edi];
481
482/* ASMBitNextSet: Too much work, do when needed. */
483#else
484/* ASMBitFirstClear: External file. */
485/* ASMBitNextClear: External file. */
486/* ASMBitFirstSet: External file. */
487/* ASMBitNextSet: External file. */
488#endif
489
490#undef ASMBitFirstSetU32
491#pragma aux ASMBitFirstSetU32 = \
492 "bsf eax, eax" \
493 "jz not_found" \
494 "inc eax" \
495 "jmp done" \
496 "not_found:" \
497 "xor eax, eax" \
498 "done:" \
499 parm [eax] nomemory \
500 value [eax] \
501 modify exact [eax] nomemory;
502
503#undef ASMBitFirstSetU64
504#pragma aux ASMBitFirstSetU64 = \
505 "bsf eax, eax" \
506 "jz not_found_low" \
507 "inc eax" \
508 "jmp done" \
509 \
510 "not_found_low:" \
511 "bsf eax, edx" \
512 "jz not_found_high" \
513 "add eax, 33" \
514 "jmp done" \
515 \
516 "not_found_high:" \
517 "xor eax, eax" \
518 "done:" \
519 parm [eax edx] nomemory \
520 value [eax] \
521 modify exact [eax] nomemory;
522
523#undef ASMBitFirstSetU16
524#pragma aux ASMBitFirstSetU16 = \
525 "movzx eax, ax" \
526 "bsf eax, eax" \
527 "jz not_found" \
528 "inc eax" \
529 "jmp done" \
530 "not_found:" \
531 "xor eax, eax" \
532 "done:" \
533 parm [ax] nomemory \
534 value [eax] \
535 modify exact [eax] nomemory;
536
537#undef ASMBitLastSetU32
538#pragma aux ASMBitLastSetU32 = \
539 "bsr eax, eax" \
540 "jz not_found" \
541 "inc eax" \
542 "jmp done" \
543 "not_found:" \
544 "xor eax, eax" \
545 "done:" \
546 parm [eax] nomemory \
547 value [eax] \
548 modify exact [eax] nomemory;
549
550#undef ASMBitLastSetU64
551#pragma aux ASMBitLastSetU64 = \
552 "bsf eax, eax" \
553 "jz not_found_low" \
554 "inc eax" \
555 "jmp done" \
556 \
557 "not_found_low:" \
558 "bsf eax, edx" \
559 "jz not_found_high" \
560 "add eax, 33" \
561 "jmp done" \
562 \
563 "not_found_high:" \
564 "xor eax, eax" \
565 "done:" \
566 parm [eax edx] nomemory \
567 value [eax] \
568 modify exact [eax] nomemory;
569
570#undef ASMBitLastSetU16
571#pragma aux ASMBitLastSetU16 = \
572 "movzx eax, ax" \
573 "bsr eax, eax" \
574 "jz not_found" \
575 "inc eax" \
576 "jmp done" \
577 "not_found:" \
578 "xor eax, eax" \
579 "done:" \
580 parm [ax] nomemory \
581 value [eax] \
582 modify exact [eax] nomemory;
583
584#undef ASMByteSwapU16
585#pragma aux ASMByteSwapU16 = \
586 "ror ax, 8" \
587 parm [ax] nomemory \
588 value [ax] \
589 modify exact [ax] nomemory;
590
591#undef ASMByteSwapU32
592#pragma aux ASMByteSwapU32 = \
593 "bswap eax" \
594 parm [eax] nomemory \
595 value [eax] \
596 modify exact [eax] nomemory;
597
598#undef ASMRotateLeftU32
599#pragma aux ASMRotateLeftU32 = \
600 "rol eax, cl" \
601 parm [eax] [ecx] nomemory \
602 value [eax] \
603 modify exact [eax] nomemory;
604
605#undef ASMRotateRightU32
606#pragma aux ASMRotateRightU32 = \
607 "ror eax, cl" \
608 parm [eax] [ecx] nomemory \
609 value [eax] \
610 modify exact [eax] nomemory;
611
612#endif
613
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