741 lines
17 KiB
C
741 lines
17 KiB
C
/** @file
|
|
* IPRT - Assembly Functions, x86 32-bit Watcom C/C++ pragma aux.
|
|
*/
|
|
|
|
/*
|
|
* Copyright (C) 2006-2023 Oracle and/or its affiliates.
|
|
*
|
|
* This file is part of VirtualBox base platform packages, as
|
|
* available from https://www.virtualbox.org.
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation, in version 3 of the
|
|
* License.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, see <https://www.gnu.org/licenses>.
|
|
*
|
|
* The contents of this file may alternatively be used under the terms
|
|
* of the Common Development and Distribution License Version 1.0
|
|
* (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
|
|
* in the VirtualBox distribution, in which case the provisions of the
|
|
* CDDL are applicable instead of those of the GPL.
|
|
*
|
|
* You may elect to license modified versions of this file under the
|
|
* terms and conditions of either the GPL or the CDDL or both.
|
|
*
|
|
* SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
|
|
*/
|
|
|
|
#ifndef IPRT_INCLUDED_asm_watcom_x86_32_h
|
|
#define IPRT_INCLUDED_asm_watcom_x86_32_h
|
|
/* no pragma once */
|
|
|
|
#ifndef IPRT_INCLUDED_asm_h
|
|
# error "Don't include this header directly."
|
|
#endif
|
|
|
|
#ifndef __FLAT__
|
|
# error "Only works with flat pointers! (-mf)"
|
|
#endif
|
|
|
|
/*
|
|
* Note! The #undef that preceds the #pragma aux statements is for undoing
|
|
* the mangling, because the symbol in #pragma aux [symbol] statements
|
|
* doesn't get subjected to preprocessing. This is also why we include
|
|
* the watcom header at both the top and the bottom of asm.h file.
|
|
*/
|
|
|
|
#undef ASMCompilerBarrier
|
|
#ifdef IPRT_ASM_WATCOM_X86_32_WITH_PRAGMAS
|
|
# if 0 /* overkill version. */
|
|
# pragma aux ASMCompilerBarrier = \
|
|
"nop" \
|
|
parm [] \
|
|
modify exact [eax ebx ecx edx es ds fs gs];
|
|
# else
|
|
# pragma aux ASMCompilerBarrier = \
|
|
"" \
|
|
parm [] \
|
|
modify exact [];
|
|
# endif
|
|
#endif
|
|
|
|
#undef ASMNopPause
|
|
#ifdef IPRT_ASM_WATCOM_X86_32_WITH_PRAGMAS
|
|
#pragma aux ASMNopPause = \
|
|
".686p" \
|
|
".xmm2" \
|
|
"pause" \
|
|
parm [] nomemory \
|
|
modify exact [] nomemory;
|
|
#endif
|
|
|
|
#undef ASMAtomicXchgU8
|
|
#ifdef IPRT_ASM_WATCOM_X86_32_WITH_PRAGMAS
|
|
#pragma aux ASMAtomicXchgU8 = \
|
|
"xchg [ecx], al" \
|
|
parm [ecx] [al] \
|
|
value [al] \
|
|
modify exact [al];
|
|
#endif
|
|
|
|
#undef ASMAtomicXchgU16
|
|
#ifdef IPRT_ASM_WATCOM_X86_32_WITH_PRAGMAS
|
|
#pragma aux ASMAtomicXchgU16 = \
|
|
"xchg [ecx], ax" \
|
|
parm [ecx] [ax] \
|
|
value [ax] \
|
|
modify exact [ax];
|
|
#endif
|
|
|
|
#undef ASMAtomicXchgU32
|
|
#ifdef IPRT_ASM_WATCOM_X86_32_WITH_PRAGMAS
|
|
#pragma aux ASMAtomicXchgU32 = \
|
|
"xchg [ecx], eax" \
|
|
parm [ecx] [eax] \
|
|
value [eax] \
|
|
modify exact [eax];
|
|
#endif
|
|
|
|
#undef ASMAtomicXchgU64
|
|
#ifdef IPRT_ASM_WATCOM_X86_32_WITH_PRAGMAS
|
|
#pragma aux ASMAtomicXchgU64 = \
|
|
".586" \
|
|
"try_again:" \
|
|
"lock cmpxchg8b [esi]" \
|
|
"jnz try_again" \
|
|
parm [esi] [ebx ecx] \
|
|
value [eax edx] \
|
|
modify exact [edx ecx ebx eax];
|
|
#endif
|
|
|
|
#undef ASMAtomicCmpXchgU8
|
|
#ifdef IPRT_ASM_WATCOM_X86_32_WITH_PRAGMAS
|
|
#pragma aux ASMAtomicCmpXchgU8 = \
|
|
".486" \
|
|
"lock cmpxchg [edx], cl" \
|
|
"setz al" \
|
|
parm [edx] [cl] [al] \
|
|
value [al] \
|
|
modify exact [al];
|
|
#endif
|
|
|
|
#undef ASMAtomicCmpXchgU16
|
|
#ifdef IPRT_ASM_WATCOM_X86_32_WITH_PRAGMAS
|
|
#pragma aux ASMAtomicCmpXchgU16 = \
|
|
".486" \
|
|
"lock cmpxchg [edx], cx" \
|
|
"setz al" \
|
|
parm [edx] [cx] [ax] \
|
|
value [al] \
|
|
modify exact [ax];
|
|
#endif
|
|
|
|
#undef ASMAtomicCmpXchgU32
|
|
#ifdef IPRT_ASM_WATCOM_X86_32_WITH_PRAGMAS
|
|
#pragma aux ASMAtomicCmpXchgU32 = \
|
|
".486" \
|
|
"lock cmpxchg [edx], ecx" \
|
|
"setz al" \
|
|
parm [edx] [ecx] [eax] \
|
|
value [al] \
|
|
modify exact [eax];
|
|
#endif
|
|
|
|
#undef ASMAtomicCmpXchgU64
|
|
#ifdef IPRT_ASM_WATCOM_X86_32_WITH_PRAGMAS
|
|
#pragma aux ASMAtomicCmpXchgU64 = \
|
|
".586" \
|
|
"lock cmpxchg8b [edi]" \
|
|
"setz al" \
|
|
parm [edi] [ebx ecx] [eax edx] \
|
|
value [al] \
|
|
modify exact [eax edx];
|
|
#endif
|
|
|
|
#undef ASMAtomicCmpXchgExU32
|
|
#ifdef IPRT_ASM_WATCOM_X86_32_WITH_PRAGMAS
|
|
#pragma aux ASMAtomicCmpXchgExU32 = \
|
|
".586" \
|
|
"lock cmpxchg [edx], ecx" \
|
|
"mov [edi], eax" \
|
|
"setz al" \
|
|
parm [edx] [ecx] [eax] [edi] \
|
|
value [al] \
|
|
modify exact [eax];
|
|
#endif
|
|
|
|
#undef ASMAtomicCmpXchgExU64
|
|
#ifdef IPRT_ASM_WATCOM_X86_32_WITH_PRAGMAS
|
|
#pragma aux ASMAtomicCmpXchgExU64 = \
|
|
".586" \
|
|
"lock cmpxchg8b [edi]" \
|
|
"mov [esi], eax" \
|
|
"mov [esi + 4], edx" \
|
|
"setz al" \
|
|
parm [edi] [ebx ecx] [eax edx] [esi] \
|
|
value [al] \
|
|
modify exact [eax edx];
|
|
#endif
|
|
|
|
#undef ASMSerializeInstructionCpuId
|
|
#ifdef IPRT_ASM_WATCOM_X86_32_WITH_PRAGMAS
|
|
#pragma aux ASMSerializeInstructionCpuId = \
|
|
".586" \
|
|
"xor eax, eax" \
|
|
"cpuid" \
|
|
parm [] \
|
|
modify exact [eax ebx ecx edx];
|
|
#endif
|
|
|
|
#undef ASMSerializeInstructionIRet
|
|
#ifdef IPRT_ASM_WATCOM_X86_32_WITH_PRAGMAS
|
|
#pragma aux ASMSerializeInstructionIRet = \
|
|
"pushf" \
|
|
"push cs" \
|
|
"call foo" /* 'push offset done' doesn't work */ \
|
|
"jmp done" \
|
|
"foo:" \
|
|
"iret" \
|
|
"done:" \
|
|
parm [] \
|
|
modify exact [];
|
|
#endif
|
|
|
|
#undef ASMSerializeInstructionRdTscp
|
|
#ifdef IPRT_ASM_WATCOM_X86_32_WITH_PRAGMAS
|
|
#pragma aux ASMSerializeInstructionRdTscp = \
|
|
0x0f 0x01 0xf9 \
|
|
parm [] \
|
|
modify exact [eax edx ecx];
|
|
#endif
|
|
|
|
#undef ASMAtomicReadU64
|
|
#ifdef IPRT_ASM_WATCOM_X86_32_WITH_PRAGMAS
|
|
#pragma aux ASMAtomicReadU64 = \
|
|
".586" \
|
|
"xor eax, eax" \
|
|
"mov edx, eax" \
|
|
"mov ebx, eax" \
|
|
"mov ecx, eax" \
|
|
"lock cmpxchg8b [edi]" \
|
|
parm [edi] \
|
|
value [eax edx] \
|
|
modify exact [eax ebx ecx edx];
|
|
#endif
|
|
|
|
#undef ASMAtomicUoReadU64
|
|
#ifdef IPRT_ASM_WATCOM_X86_32_WITH_PRAGMAS
|
|
#pragma aux ASMAtomicUoReadU64 = \
|
|
".586" \
|
|
"xor eax, eax" \
|
|
"mov edx, eax" \
|
|
"mov ebx, eax" \
|
|
"mov ecx, eax" \
|
|
"lock cmpxchg8b [edi]" \
|
|
parm [edi] \
|
|
value [eax edx] \
|
|
modify exact [eax ebx ecx edx];
|
|
#endif
|
|
|
|
#undef ASMAtomicAddU16
|
|
#ifdef IPRT_ASM_WATCOM_X86_32_WITH_PRAGMAS
|
|
#pragma aux ASMAtomicAddU16 = \
|
|
".486" \
|
|
"lock xadd [ecx], ax" \
|
|
parm [ecx] [ax] \
|
|
value [ax] \
|
|
modify exact [ax];
|
|
#endif
|
|
|
|
#undef ASMAtomicAddU32
|
|
#ifdef IPRT_ASM_WATCOM_X86_32_WITH_PRAGMAS
|
|
#pragma aux ASMAtomicAddU32 = \
|
|
".486" \
|
|
"lock xadd [ecx], eax" \
|
|
parm [ecx] [eax] \
|
|
value [eax] \
|
|
modify exact [eax];
|
|
#endif
|
|
|
|
#undef ASMAtomicIncU16
|
|
#ifdef IPRT_ASM_WATCOM_X86_32_WITH_PRAGMAS
|
|
#pragma aux ASMAtomicIncU16 = \
|
|
".486" \
|
|
"mov ax, 1" \
|
|
"lock xadd [ecx], ax" \
|
|
"inc ax" \
|
|
parm [ecx] \
|
|
value [ax] \
|
|
modify exact [ax];
|
|
#endif
|
|
|
|
#undef ASMAtomicIncU32
|
|
#ifdef IPRT_ASM_WATCOM_X86_32_WITH_PRAGMAS
|
|
#pragma aux ASMAtomicIncU32 = \
|
|
".486" \
|
|
"mov eax, 1" \
|
|
"lock xadd [ecx], eax" \
|
|
"inc eax" \
|
|
parm [ecx] \
|
|
value [eax] \
|
|
modify exact [eax];
|
|
#endif
|
|
|
|
/* ASMAtomicIncU64: Should be done by C inline or in external file. */
|
|
|
|
#undef ASMAtomicDecU16
|
|
#ifdef IPRT_ASM_WATCOM_X86_32_WITH_PRAGMAS
|
|
#pragma aux ASMAtomicDecU16 = \
|
|
".486" \
|
|
"mov ax, 0ffffh" \
|
|
"lock xadd [ecx], ax" \
|
|
"dec ax" \
|
|
parm [ecx] \
|
|
value [ax] \
|
|
modify exact [ax];
|
|
#endif
|
|
|
|
#undef ASMAtomicDecU32
|
|
#ifdef IPRT_ASM_WATCOM_X86_32_WITH_PRAGMAS
|
|
#pragma aux ASMAtomicDecU32 = \
|
|
".486" \
|
|
"mov eax, 0ffffffffh" \
|
|
"lock xadd [ecx], eax" \
|
|
"dec eax" \
|
|
parm [ecx] \
|
|
value [eax] \
|
|
modify exact [eax];
|
|
#endif
|
|
|
|
/* ASMAtomicDecU64: Should be done by C inline or in external file. */
|
|
|
|
#undef ASMAtomicOrU32
|
|
#ifdef IPRT_ASM_WATCOM_X86_32_WITH_PRAGMAS
|
|
#pragma aux ASMAtomicOrU32 = \
|
|
"lock or [ecx], eax" \
|
|
parm [ecx] [eax] \
|
|
modify exact [];
|
|
#endif
|
|
|
|
/* ASMAtomicOrU64: Should be done by C inline or in external file. */
|
|
|
|
#undef ASMAtomicAndU32
|
|
#ifdef IPRT_ASM_WATCOM_X86_32_WITH_PRAGMAS
|
|
#pragma aux ASMAtomicAndU32 = \
|
|
"lock and [ecx], eax" \
|
|
parm [ecx] [eax] \
|
|
modify exact [];
|
|
#endif
|
|
|
|
/* ASMAtomicAndU64: Should be done by C inline or in external file. */
|
|
|
|
#undef ASMAtomicUoOrU32
|
|
#ifdef IPRT_ASM_WATCOM_X86_32_WITH_PRAGMAS
|
|
#pragma aux ASMAtomicUoOrU32 = \
|
|
"or [ecx], eax" \
|
|
parm [ecx] [eax] \
|
|
modify exact [];
|
|
#endif
|
|
|
|
/* ASMAtomicUoOrU64: Should be done by C inline or in external file. */
|
|
|
|
#undef ASMAtomicUoAndU32
|
|
#ifdef IPRT_ASM_WATCOM_X86_32_WITH_PRAGMAS
|
|
#pragma aux ASMAtomicUoAndU32 = \
|
|
"and [ecx], eax" \
|
|
parm [ecx] [eax] \
|
|
modify exact [];
|
|
#endif
|
|
|
|
/* ASMAtomicUoAndU64: Should be done by C inline or in external file. */
|
|
|
|
#undef ASMAtomicUoIncU32
|
|
#ifdef IPRT_ASM_WATCOM_X86_32_WITH_PRAGMAS
|
|
#pragma aux ASMAtomicUoIncU32 = \
|
|
".486" \
|
|
"xadd [ecx], eax" \
|
|
"inc eax" \
|
|
parm [ecx] \
|
|
value [eax] \
|
|
modify exact [eax];
|
|
#endif
|
|
|
|
#undef ASMAtomicUoDecU32
|
|
#ifdef IPRT_ASM_WATCOM_X86_32_WITH_PRAGMAS
|
|
#pragma aux ASMAtomicUoDecU32 = \
|
|
".486" \
|
|
"mov eax, 0ffffffffh" \
|
|
"xadd [ecx], eax" \
|
|
"dec eax" \
|
|
parm [ecx] \
|
|
value [eax] \
|
|
modify exact [eax];
|
|
#endif
|
|
|
|
#undef ASMMemZeroPage
|
|
#ifdef IPRT_ASM_WATCOM_X86_32_WITH_PRAGMAS
|
|
#pragma aux ASMMemZeroPage = \
|
|
"mov ecx, 1024" \
|
|
"xor eax, eax" \
|
|
"rep stosd" \
|
|
parm [edi] \
|
|
modify exact [eax ecx edi];
|
|
#endif
|
|
|
|
#undef ASMMemZero32
|
|
#ifdef IPRT_ASM_WATCOM_X86_32_WITH_PRAGMAS
|
|
#pragma aux ASMMemZero32 = \
|
|
"shr ecx, 2" \
|
|
"xor eax, eax" \
|
|
"rep stosd" \
|
|
parm [edi] [ecx] \
|
|
modify exact [eax ecx edi];
|
|
#endif
|
|
|
|
#undef ASMMemFill32
|
|
#ifdef IPRT_ASM_WATCOM_X86_32_WITH_PRAGMAS
|
|
#pragma aux ASMMemFill32 = \
|
|
"shr ecx, 2" \
|
|
"rep stosd" \
|
|
parm [edi] [ecx] [eax]\
|
|
modify exact [ecx edi];
|
|
#endif
|
|
|
|
#undef ASMProbeReadByte
|
|
#ifdef IPRT_ASM_WATCOM_X86_32_WITH_PRAGMAS
|
|
#pragma aux ASMProbeReadByte = \
|
|
"mov al, [ecx]" \
|
|
parm [ecx] \
|
|
value [al] \
|
|
modify exact [al];
|
|
#endif
|
|
|
|
#undef ASMBitSet
|
|
#ifdef IPRT_ASM_WATCOM_X86_32_WITH_PRAGMAS
|
|
#pragma aux ASMBitSet = \
|
|
"bts [ecx], eax" \
|
|
parm [ecx] [eax] \
|
|
modify exact [];
|
|
#endif
|
|
|
|
#undef ASMAtomicBitSet
|
|
#ifdef IPRT_ASM_WATCOM_X86_32_WITH_PRAGMAS
|
|
#pragma aux ASMAtomicBitSet = \
|
|
"lock bts [ecx], eax" \
|
|
parm [ecx] [eax] \
|
|
modify exact [];
|
|
#endif
|
|
|
|
#undef ASMBitClear
|
|
#ifdef IPRT_ASM_WATCOM_X86_32_WITH_PRAGMAS
|
|
#pragma aux ASMBitClear = \
|
|
"btr [ecx], eax" \
|
|
parm [ecx] [eax] \
|
|
modify exact [];
|
|
#endif
|
|
|
|
#undef ASMAtomicBitClear
|
|
#ifdef IPRT_ASM_WATCOM_X86_32_WITH_PRAGMAS
|
|
#pragma aux ASMAtomicBitClear = \
|
|
"lock btr [ecx], eax" \
|
|
parm [ecx] [eax] \
|
|
modify exact [];
|
|
#endif
|
|
|
|
#undef ASMBitToggle
|
|
#ifdef IPRT_ASM_WATCOM_X86_32_WITH_PRAGMAS
|
|
#pragma aux ASMBitToggle = \
|
|
"btc [ecx], eax" \
|
|
parm [ecx] [eax] \
|
|
modify exact [];
|
|
#endif
|
|
|
|
#undef ASMAtomicBitToggle
|
|
#ifdef IPRT_ASM_WATCOM_X86_32_WITH_PRAGMAS
|
|
#pragma aux ASMAtomicBitToggle = \
|
|
"lock btc [ecx], eax" \
|
|
parm [ecx] [eax] \
|
|
modify exact [];
|
|
#endif
|
|
|
|
|
|
#undef ASMBitTestAndSet
|
|
#ifdef IPRT_ASM_WATCOM_X86_32_WITH_PRAGMAS
|
|
#pragma aux ASMBitTestAndSet = \
|
|
"bts [ecx], eax" \
|
|
"setc al" \
|
|
parm [ecx] [eax] \
|
|
value [al] \
|
|
modify exact [eax];
|
|
#endif
|
|
|
|
#undef ASMAtomicBitTestAndSet
|
|
#ifdef IPRT_ASM_WATCOM_X86_32_WITH_PRAGMAS
|
|
#pragma aux ASMAtomicBitTestAndSet = \
|
|
"lock bts [ecx], eax" \
|
|
"setc al" \
|
|
parm [ecx] [eax] \
|
|
value [al] \
|
|
modify exact [eax];
|
|
#endif
|
|
|
|
#undef ASMBitTestAndClear
|
|
#ifdef IPRT_ASM_WATCOM_X86_32_WITH_PRAGMAS
|
|
#pragma aux ASMBitTestAndClear = \
|
|
"btr [ecx], eax" \
|
|
"setc al" \
|
|
parm [ecx] [eax] \
|
|
value [al] \
|
|
modify exact [eax];
|
|
#endif
|
|
|
|
#undef ASMAtomicBitTestAndClear
|
|
#ifdef IPRT_ASM_WATCOM_X86_32_WITH_PRAGMAS
|
|
#pragma aux ASMAtomicBitTestAndClear = \
|
|
"lock btr [ecx], eax" \
|
|
"setc al" \
|
|
parm [ecx] [eax] \
|
|
value [al] \
|
|
modify exact [eax];
|
|
#endif
|
|
|
|
#undef ASMBitTestAndToggle
|
|
#ifdef IPRT_ASM_WATCOM_X86_32_WITH_PRAGMAS
|
|
#pragma aux ASMBitTestAndToggle = \
|
|
"btc [ecx], eax" \
|
|
"setc al" \
|
|
parm [ecx] [eax] \
|
|
value [al] \
|
|
modify exact [eax];
|
|
#endif
|
|
|
|
#undef ASMAtomicBitTestAndToggle
|
|
#ifdef IPRT_ASM_WATCOM_X86_32_WITH_PRAGMAS
|
|
#pragma aux ASMAtomicBitTestAndToggle = \
|
|
"lock btc [ecx], eax" \
|
|
"setc al" \
|
|
parm [ecx] [eax] \
|
|
value [al] \
|
|
modify exact [eax];
|
|
#endif
|
|
|
|
#undef ASMBitTest
|
|
#ifdef IPRT_ASM_WATCOM_X86_32_WITH_PRAGMAS
|
|
#pragma aux ASMBitTest = \
|
|
"bt [ecx], eax" \
|
|
"setc al" \
|
|
parm [ecx] [eax] nomemory \
|
|
value [al] \
|
|
modify exact [eax] nomemory;
|
|
#endif
|
|
|
|
#if 0
|
|
/** @todo this is way to much inline assembly, better off in an external function. */
|
|
#undef ASMBitFirstClear
|
|
#ifdef IPRT_ASM_WATCOM_X86_32_WITH_PRAGMAS
|
|
#pragma aux ASMBitFirstClear = \
|
|
"mov edx, edi" /* save start of bitmap for later */ \
|
|
"add ecx, 31" \
|
|
"shr ecx, 5" /* cDWord = RT_ALIGN_32(cBits, 32) / 32; */ \
|
|
"mov eax, 0ffffffffh" \
|
|
"repe scasd" \
|
|
"je done" \
|
|
"lea edi, [edi - 4]" /* rewind edi */ \
|
|
"xor eax, [edi]" /* load inverted bits */ \
|
|
"sub edi, edx" /* calc byte offset */ \
|
|
"shl edi, 3" /* convert byte to bit offset */ \
|
|
"mov edx, eax" \
|
|
"bsf eax, edx" \
|
|
"add eax, edi" \
|
|
"done:" \
|
|
parm [edi] [ecx] \
|
|
value [eax] \
|
|
modify exact [eax ecx edx edi];
|
|
#endif
|
|
|
|
/* ASMBitNextClear: Too much work, do when needed. */
|
|
|
|
/** @todo this is way to much inline assembly, better off in an external function. */
|
|
#undef ASMBitFirstSet
|
|
#ifdef IPRT_ASM_WATCOM_X86_32_WITH_PRAGMAS
|
|
#pragma aux ASMBitFirstSet = \
|
|
"mov edx, edi" /* save start of bitmap for later */ \
|
|
"add ecx, 31" \
|
|
"shr ecx, 5" /* cDWord = RT_ALIGN_32(cBits, 32) / 32; */ \
|
|
"mov eax, 0ffffffffh" \
|
|
"repe scasd" \
|
|
"je done" \
|
|
"lea edi, [edi - 4]" /* rewind edi */ \
|
|
"mov eax, [edi]" /* reload previous dword */ \
|
|
"sub edi, edx" /* calc byte offset */ \
|
|
"shl edi, 3" /* convert byte to bit offset */ \
|
|
"mov edx, eax" \
|
|
"bsf eax, edx" \
|
|
"add eax, edi" \
|
|
"done:" \
|
|
parm [edi] [ecx] \
|
|
value [eax] \
|
|
modify exact [eax ecx edx edi];
|
|
#endif
|
|
|
|
/* ASMBitNextSet: Too much work, do when needed. */
|
|
#else
|
|
/* ASMBitFirstClear: External file. */
|
|
/* ASMBitNextClear: External file. */
|
|
/* ASMBitFirstSet: External file. */
|
|
/* ASMBitNextSet: External file. */
|
|
#endif
|
|
|
|
#undef ASMBitFirstSetU32
|
|
#ifdef IPRT_ASM_WATCOM_X86_32_WITH_PRAGMAS
|
|
#pragma aux ASMBitFirstSetU32 = \
|
|
"bsf eax, eax" \
|
|
"jz not_found" \
|
|
"inc eax" \
|
|
"jmp done" \
|
|
"not_found:" \
|
|
"xor eax, eax" \
|
|
"done:" \
|
|
parm [eax] nomemory \
|
|
value [eax] \
|
|
modify exact [eax] nomemory;
|
|
#endif
|
|
|
|
#undef ASMBitFirstSetU64
|
|
#ifdef IPRT_ASM_WATCOM_X86_32_WITH_PRAGMAS
|
|
#pragma aux ASMBitFirstSetU64 = \
|
|
"bsf eax, eax" \
|
|
"jz not_found_low" \
|
|
"inc eax" \
|
|
"jmp done" \
|
|
\
|
|
"not_found_low:" \
|
|
"bsf eax, edx" \
|
|
"jz not_found_high" \
|
|
"add eax, 33" \
|
|
"jmp done" \
|
|
\
|
|
"not_found_high:" \
|
|
"xor eax, eax" \
|
|
"done:" \
|
|
parm [eax edx] nomemory \
|
|
value [eax] \
|
|
modify exact [eax] nomemory;
|
|
#endif
|
|
|
|
#undef ASMBitFirstSetU16
|
|
#ifdef IPRT_ASM_WATCOM_X86_32_WITH_PRAGMAS
|
|
#pragma aux ASMBitFirstSetU16 = \
|
|
"movzx eax, ax" \
|
|
"bsf eax, eax" \
|
|
"jz not_found" \
|
|
"inc eax" \
|
|
"jmp done" \
|
|
"not_found:" \
|
|
"xor eax, eax" \
|
|
"done:" \
|
|
parm [ax] nomemory \
|
|
value [eax] \
|
|
modify exact [eax] nomemory;
|
|
#endif
|
|
|
|
#undef ASMBitLastSetU32
|
|
#ifdef IPRT_ASM_WATCOM_X86_32_WITH_PRAGMAS
|
|
#pragma aux ASMBitLastSetU32 = \
|
|
"bsr eax, eax" \
|
|
"jz not_found" \
|
|
"inc eax" \
|
|
"jmp done" \
|
|
"not_found:" \
|
|
"xor eax, eax" \
|
|
"done:" \
|
|
parm [eax] nomemory \
|
|
value [eax] \
|
|
modify exact [eax] nomemory;
|
|
#endif
|
|
|
|
#undef ASMBitLastSetU64
|
|
#ifdef IPRT_ASM_WATCOM_X86_32_WITH_PRAGMAS
|
|
#pragma aux ASMBitLastSetU64 = \
|
|
"xchg eax, edx" \
|
|
"bsr eax, eax" \
|
|
"jz not_found_high" \
|
|
"add eax, 33" \
|
|
"jmp done" \
|
|
\
|
|
"not_found_high:" \
|
|
"bsr eax, edx" \
|
|
"jz not_found" \
|
|
"inc eax" \
|
|
"jmp done" \
|
|
\
|
|
"not_found:" \
|
|
"xor eax, eax" \
|
|
"done:" \
|
|
parm [eax edx] nomemory \
|
|
value [eax] \
|
|
modify exact [eax edx] nomemory;
|
|
#endif
|
|
|
|
#undef ASMBitLastSetU16
|
|
#ifdef IPRT_ASM_WATCOM_X86_32_WITH_PRAGMAS
|
|
#pragma aux ASMBitLastSetU16 = \
|
|
"movzx eax, ax" \
|
|
"bsr eax, eax" \
|
|
"jz not_found" \
|
|
"inc eax" \
|
|
"jmp done" \
|
|
"not_found:" \
|
|
"xor eax, eax" \
|
|
"done:" \
|
|
parm [ax] nomemory \
|
|
value [eax] \
|
|
modify exact [eax] nomemory;
|
|
#endif
|
|
|
|
#undef ASMByteSwapU16
|
|
#ifdef IPRT_ASM_WATCOM_X86_32_WITH_PRAGMAS
|
|
#pragma aux ASMByteSwapU16 = \
|
|
"ror ax, 8" \
|
|
parm [ax] nomemory \
|
|
value [ax] \
|
|
modify exact [ax] nomemory;
|
|
#endif
|
|
|
|
#undef ASMByteSwapU32
|
|
#ifdef IPRT_ASM_WATCOM_X86_32_WITH_PRAGMAS
|
|
#pragma aux ASMByteSwapU32 = \
|
|
"bswap eax" \
|
|
parm [eax] nomemory \
|
|
value [eax] \
|
|
modify exact [eax] nomemory;
|
|
#endif
|
|
|
|
#undef ASMRotateLeftU32
|
|
#ifdef IPRT_ASM_WATCOM_X86_32_WITH_PRAGMAS
|
|
#pragma aux ASMRotateLeftU32 = \
|
|
"rol eax, cl" \
|
|
parm [eax] [ecx] nomemory \
|
|
value [eax] \
|
|
modify exact [eax] nomemory;
|
|
#endif
|
|
|
|
#undef ASMRotateRightU32
|
|
#ifdef IPRT_ASM_WATCOM_X86_32_WITH_PRAGMAS
|
|
#pragma aux ASMRotateRightU32 = \
|
|
"ror eax, cl" \
|
|
parm [eax] [ecx] nomemory \
|
|
value [eax] \
|
|
modify exact [eax] nomemory;
|
|
#endif
|
|
|
|
#endif /* !IPRT_INCLUDED_asm_watcom_x86_32_h */
|
|
|