diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 14:19:18 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 14:19:18 +0000 |
commit | 4035b1bfb1e5843a539a8b624d21952b756974d1 (patch) | |
tree | f1e9cd5bf548cbc57ff2fddfb2b4aa9ae95587e2 /src/VBox/Runtime/common/asm | |
parent | Initial commit. (diff) | |
download | virtualbox-upstream.tar.xz virtualbox-upstream.zip |
Adding upstream version 6.1.22-dfsg.upstream/6.1.22-dfsgupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
55 files changed, 4873 insertions, 0 deletions
diff --git a/src/VBox/Runtime/common/asm/ASMAddFlags.asm b/src/VBox/Runtime/common/asm/ASMAddFlags.asm new file mode 100644 index 00000000..4eafd2ad --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMAddFlags.asm @@ -0,0 +1,70 @@ +; $Id: ASMAddFlags.asm $ +;; @file +; IPRT - ASMSetFlags(). +; + +; +; Copyright (C) 2006-2020 Oracle Corporation +; +; This file is part of VirtualBox Open Source Edition (OSE), as +; available from http://www.virtualbox.org. This file is free software; +; you can redistribute it and/or modify it under the terms of the GNU +; General Public License (GPL) as published by the Free Software +; Foundation, in version 2 as it comes in the "COPYING" file of the +; VirtualBox OSE distribution. VirtualBox OSE is distributed in the +; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL) only, as it comes in the "COPYING.CDDL" file of the +; VirtualBox OSE 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. +; + + +;******************************************************************************* +;* Header Files * +;******************************************************************************* +%include "iprt/asmdefs.mac" + +BEGINCODE + +;; +; @param rcx/rdi eflags to add +BEGINPROC_EXPORTED ASMAddFlags +%if ARCH_BITS == 64 + pushfq + mov rax, [rsp] + %ifdef ASM_CALL64_GCC + or rdi, rax + mov [rsp], rdi + %else + or rcx, rax + mov [rsp], rcx + %endif + popfq +%elif ARCH_BITS == 32 + mov ecx, [esp + 4] + pushfd + mov eax, [esp] + or ecx, eax + mov [esp], ecx + popfd +%elif ARCH_BITS == 16 + push bp + mov bp, sp + pushf + pop ax + push word [bp + 2 + 2] + or [bp - 2], ax + popf + leave +%else + %error ARCH_BITS +%endif + ret +ENDPROC ASMAddFlags + diff --git a/src/VBox/Runtime/common/asm/ASMAtomicCmpXchgExU64.asm b/src/VBox/Runtime/common/asm/ASMAtomicCmpXchgExU64.asm new file mode 100644 index 00000000..04ec43ed --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMAtomicCmpXchgExU64.asm @@ -0,0 +1,84 @@ +; $Id: ASMAtomicCmpXchgExU64.asm $ +;; @file +; IPRT - ASMAtomicCmpXchgExU64(). +; + +; +; Copyright (C) 2006-2020 Oracle Corporation +; +; This file is part of VirtualBox Open Source Edition (OSE), as +; available from http://www.virtualbox.org. This file is free software; +; you can redistribute it and/or modify it under the terms of the GNU +; General Public License (GPL) as published by the Free Software +; Foundation, in version 2 as it comes in the "COPYING" file of the +; VirtualBox OSE distribution. VirtualBox OSE is distributed in the +; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL) only, as it comes in the "COPYING.CDDL" file of the +; VirtualBox OSE 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. +; + +;******************************************************************************* +;* Header Files * +;******************************************************************************* +%include "iprt/asmdefs.mac" + +BEGINCODE + +;; +; Atomically Exchange an unsigned 64-bit value, ordered. +; +; @param pu64 x86:ebp+8 gcc:rdi msc:rcx +; @param u64New x86:ebp+c gcc:rsi msc:rdx +; @param u64Old x86:ebp+14 gcc:rdx msc:r8 +; @param pu64Old x86:ebp+1c gcc:rcx msc:r9 +; +; @returns bool result: true if successfully exchanged, false if not. +; x86:al +; +BEGINPROC_EXPORTED ASMAtomicCmpXchgExU64 +%ifdef RT_ARCH_AMD64 + %ifdef ASM_CALL64_MSC + mov rax, r8 + lock cmpxchg [rcx], rdx + mov [r9], rax + %else + mov rax, rdx + lock cmpxchg [rdi], rsi + mov [rcx], rax + %endif + setz al + movzx eax, al + ret +%endif +%ifdef RT_ARCH_X86 + push ebp + mov ebp, esp + push ebx + push edi + + mov ebx, dword [ebp+0ch] + mov ecx, dword [ebp+0ch + 4] + mov edi, [ebp+08h] + mov eax, dword [ebp+14h] + mov edx, dword [ebp+14h + 4] + lock cmpxchg8b [edi] + mov edi, [ebp + 1ch] + mov [edi], eax + mov [edi + 4], edx + setz al + movzx eax, al + + pop edi + pop ebx + leave + ret +%endif +ENDPROC ASMAtomicCmpXchgExU64 + diff --git a/src/VBox/Runtime/common/asm/ASMAtomicCmpXchgU16.asm b/src/VBox/Runtime/common/asm/ASMAtomicCmpXchgU16.asm new file mode 100644 index 00000000..bcf9624e --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMAtomicCmpXchgU16.asm @@ -0,0 +1,63 @@ +; $Id: ASMAtomicCmpXchgU16.asm $ +;; @file +; IPRT - ASMAtomicCmpXchgU16(). +; + +; +; Copyright (C) 2006-2020 Oracle Corporation +; +; This file is part of VirtualBox Open Source Edition (OSE), as +; available from http://www.virtualbox.org. This file is free software; +; you can redistribute it and/or modify it under the terms of the GNU +; General Public License (GPL) as published by the Free Software +; Foundation, in version 2 as it comes in the "COPYING" file of the +; VirtualBox OSE distribution. VirtualBox OSE is distributed in the +; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL) only, as it comes in the "COPYING.CDDL" file of the +; VirtualBox OSE 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. +; + +;******************************************************************************* +;* Header Files * +;******************************************************************************* +%include "iprt/asmdefs.mac" + +BEGINCODE + +;; +; Atomically compares and exchanges an unsigned 8-bit int. +; +; @param pu16 x86:esp+4 msc:rcx gcc:rdi +; @param u16New x86:esp+8 msc:dx gcc:si +; @param u16Old x86:esp+c msc:r8l gcc:dl +; +; @returns bool result: true if successfully exchanged, false if not. +; x86:al +; +BEGINPROC_EXPORTED ASMAtomicCmpXchgU16 +%ifdef RT_ARCH_AMD64 + %ifdef ASM_CALL64_MSC + mov ax, r8w + lock cmpxchg [rcx], dx + %else + mov ax, dx + lock cmpxchg [rdi], si + %endif +%else + mov ecx, [esp + 04h] + mov dx, [esp + 08h] + mov ax, [esp + 0ch] + lock cmpxchg [ecx], dx +%endif + setz al + movzx eax, al + ret +ENDPROC ASMAtomicCmpXchgU16 + diff --git a/src/VBox/Runtime/common/asm/ASMAtomicCmpXchgU64.asm b/src/VBox/Runtime/common/asm/ASMAtomicCmpXchgU64.asm new file mode 100644 index 00000000..23c11e61 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMAtomicCmpXchgU64.asm @@ -0,0 +1,78 @@ +; $Id: ASMAtomicCmpXchgU64.asm $ +;; @file +; IPRT - ASMAtomicCmpXchgU64(). +; + +; +; Copyright (C) 2006-2020 Oracle Corporation +; +; This file is part of VirtualBox Open Source Edition (OSE), as +; available from http://www.virtualbox.org. This file is free software; +; you can redistribute it and/or modify it under the terms of the GNU +; General Public License (GPL) as published by the Free Software +; Foundation, in version 2 as it comes in the "COPYING" file of the +; VirtualBox OSE distribution. VirtualBox OSE is distributed in the +; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL) only, as it comes in the "COPYING.CDDL" file of the +; VirtualBox OSE 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. +; + +;******************************************************************************* +;* Header Files * +;******************************************************************************* +%include "iprt/asmdefs.mac" + +BEGINCODE + +;; +; Atomically compares and exchanges an unsigned 64-bit int. +; +; @param pu64 x86:ebp+8 gcc:rdi msc:rcx +; @param u64New x86:ebp+c gcc:rsi msc:rdx +; @param u64Old x86:ebp+14 gcc:rdx msc:r8 +; +; @returns bool result: true if successfully exchanged, false if not. +; x86:al +; +BEGINPROC_EXPORTED ASMAtomicCmpXchgU64 +%ifdef RT_ARCH_AMD64 + %ifdef ASM_CALL64_MSC + mov rax, r8 + lock cmpxchg [rcx], rdx + %else + mov rax, rdx + lock cmpxchg [rdi], rsi + %endif + setz al + movzx eax, al + ret +%endif +%ifdef RT_ARCH_X86 + push ebp + mov ebp, esp + push ebx + push edi + + mov ebx, dword [ebp+0ch] + mov ecx, dword [ebp+0ch + 4] + mov edi, [ebp+08h] + mov eax, dword [ebp+14h] + mov edx, dword [ebp+14h + 4] + lock cmpxchg8b [edi] + setz al + movzx eax, al + + pop edi + pop ebx + leave + ret +%endif +ENDPROC ASMAtomicCmpXchgU64 + diff --git a/src/VBox/Runtime/common/asm/ASMAtomicCmpXchgU8.asm b/src/VBox/Runtime/common/asm/ASMAtomicCmpXchgU8.asm new file mode 100644 index 00000000..c79f143c --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMAtomicCmpXchgU8.asm @@ -0,0 +1,63 @@ +; $Id: ASMAtomicCmpXchgU8.asm $ +;; @file +; IPRT - ASMAtomicCmpXchgU8(). +; + +; +; Copyright (C) 2006-2020 Oracle Corporation +; +; This file is part of VirtualBox Open Source Edition (OSE), as +; available from http://www.virtualbox.org. This file is free software; +; you can redistribute it and/or modify it under the terms of the GNU +; General Public License (GPL) as published by the Free Software +; Foundation, in version 2 as it comes in the "COPYING" file of the +; VirtualBox OSE distribution. VirtualBox OSE is distributed in the +; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL) only, as it comes in the "COPYING.CDDL" file of the +; VirtualBox OSE 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. +; + +;******************************************************************************* +;* Header Files * +;******************************************************************************* +%include "iprt/asmdefs.mac" + +BEGINCODE + +;; +; Atomically compares and exchanges an unsigned 8-bit int. +; +; @param pu8 x86:esp+4 msc:rcx gcc:rdi +; @param u8New x86:esp+8 msc:dl gcc:sil +; @param u8Old x86:esp+c msc:r8l gcc:dl +; +; @returns bool result: true if successfully exchanged, false if not. +; x86:al +; +BEGINPROC_EXPORTED ASMAtomicCmpXchgU8 +%ifdef RT_ARCH_AMD64 + %ifdef ASM_CALL64_MSC + mov al, r8b + lock cmpxchg [rcx], dl + %else + mov al, dl + lock cmpxchg [rdi], sil + %endif +%else + mov ecx, [esp + 04h] + mov dl, [esp + 08h] + mov al, [esp + 0ch] + lock cmpxchg [ecx], dl +%endif + setz al + movzx eax, al + ret +ENDPROC ASMAtomicCmpXchgU8 + diff --git a/src/VBox/Runtime/common/asm/ASMAtomicReadU64.asm b/src/VBox/Runtime/common/asm/ASMAtomicReadU64.asm new file mode 100644 index 00000000..b0acc0be --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMAtomicReadU64.asm @@ -0,0 +1,71 @@ +; $Id: ASMAtomicReadU64.asm $ +;; @file +; IPRT - ASMAtomicReadU64(). +; + +; +; Copyright (C) 2006-2020 Oracle Corporation +; +; This file is part of VirtualBox Open Source Edition (OSE), as +; available from http://www.virtualbox.org. This file is free software; +; you can redistribute it and/or modify it under the terms of the GNU +; General Public License (GPL) as published by the Free Software +; Foundation, in version 2 as it comes in the "COPYING" file of the +; VirtualBox OSE distribution. VirtualBox OSE is distributed in the +; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL) only, as it comes in the "COPYING.CDDL" file of the +; VirtualBox OSE 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. +; + +;******************************************************************************* +;* Header Files * +;******************************************************************************* +%include "iprt/asmdefs.mac" + +BEGINCODE + +;; +; Atomically reads 64-bit value. +; +; @param pu64 x86:ebp+8 +; +; @returns The current value. (x86:eax+edx) +; +; +BEGINPROC_EXPORTED ASMAtomicReadU64 +%ifdef RT_ARCH_AMD64 + mfence ; ASSUME its present. + %ifdef ASM_CALL64_MSC + mov rax, [rcx] + %else + mov rax, [rdi] + %endif + ret +%endif +%ifdef RT_ARCH_X86 + push ebp + mov ebp, esp + push ebx + push edi + + xor eax, eax + xor edx, edx + mov edi, [ebp+08h] + xor ecx, ecx + xor ebx, ebx + lock cmpxchg8b [edi] + + pop edi + pop ebx + leave + ret +%endif +ENDPROC ASMAtomicReadU64 + diff --git a/src/VBox/Runtime/common/asm/ASMAtomicUoAndU32.asm b/src/VBox/Runtime/common/asm/ASMAtomicUoAndU32.asm new file mode 100644 index 00000000..12cfff39 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMAtomicUoAndU32.asm @@ -0,0 +1,56 @@ +; $Id: ASMAtomicUoAndU32.asm $ +;; @file +; IPRT - ASMAtomicUoAndU32(). +; + +; +; Copyright (C) 2013-2020 Oracle Corporation +; +; This file is part of VirtualBox Open Source Edition (OSE), as +; available from http://www.virtualbox.org. This file is free software; +; you can redistribute it and/or modify it under the terms of the GNU +; General Public License (GPL) as published by the Free Software +; Foundation, in version 2 as it comes in the "COPYING" file of the +; VirtualBox OSE distribution. VirtualBox OSE is distributed in the +; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL) only, as it comes in the "COPYING.CDDL" file of the +; VirtualBox OSE 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. +; + +;******************************************************************************* +;* Header Files * +;******************************************************************************* +%include "iprt/asmdefs.mac" + +BEGINCODE + +;; +; Atomically OR an unsigned 32-bit value, unordered. +; +; @param pu32 x86:esp+4 gcc:rdi msc:rcx +; @param u32Or x86:esp+8 gcc:rsi msc:rdx +; +; @returns void +; +BEGINPROC_EXPORTED ASMAtomicUoAndU32 +%ifdef RT_ARCH_AMD64 + %ifdef ASM_CALL64_MSC + and [rcx], edx + %else + and [rdi], esi + %endif +%elifdef RT_ARCH_X86 + mov ecx, [esp + 04h] + mov edx, [esp + 08h] + and [ecx], edx +%endif + ret +ENDPROC ASMAtomicUoAndU32 + diff --git a/src/VBox/Runtime/common/asm/ASMAtomicUoAndU64.asm b/src/VBox/Runtime/common/asm/ASMAtomicUoAndU64.asm new file mode 100644 index 00000000..1f6f2f8f --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMAtomicUoAndU64.asm @@ -0,0 +1,76 @@ +; $Id: ASMAtomicUoAndU64.asm $ +;; @file +; IPRT - ASMAtomicUoAndU64(). +; + +; +; Copyright (C) 2013-2020 Oracle Corporation +; +; This file is part of VirtualBox Open Source Edition (OSE), as +; available from http://www.virtualbox.org. This file is free software; +; you can redistribute it and/or modify it under the terms of the GNU +; General Public License (GPL) as published by the Free Software +; Foundation, in version 2 as it comes in the "COPYING" file of the +; VirtualBox OSE distribution. VirtualBox OSE is distributed in the +; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL) only, as it comes in the "COPYING.CDDL" file of the +; VirtualBox OSE 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. +; + +;******************************************************************************* +;* Header Files * +;******************************************************************************* +%include "iprt/asmdefs.mac" + +BEGINCODE + +;; +; Atomically AND an unsigned 64-bit value, unordered. +; +; @param pu64 x86:ebp+8 gcc:rdi msc:rcx +; @param u64Or x86:ebp+c gcc:rsi msc:rdx +; +; @returns void +; +BEGINPROC_EXPORTED ASMAtomicUoAndU64 +%ifdef RT_ARCH_AMD64 + %ifdef ASM_CALL64_MSC + and [rcx], rdx + %else + and [rdi], rsi + %endif +%elifdef RT_ARCH_X86 + push ebp + mov ebp, esp + push ebx + push edi + + mov edi, [ebp + 08h] + mov ebx, [ebp + 0ch] + mov ecx, [ebp + 0ch + 4] + mov eax, ebx + mov edx, ecx +.try_again: + cmpxchg8b [edi] + jz .done + mov ebx, eax + and ebx, [ebp + 0ch] + mov ecx, edx + and ecx, [ebp + 0ch + 4] + jmp .try_again + +.done: + pop edi + pop ebx + leave +%endif + ret +ENDPROC ASMAtomicUoAndU64 + diff --git a/src/VBox/Runtime/common/asm/ASMAtomicUoDecU32.asm b/src/VBox/Runtime/common/asm/ASMAtomicUoDecU32.asm new file mode 100644 index 00000000..273dadff --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMAtomicUoDecU32.asm @@ -0,0 +1,56 @@ +; $Id: ASMAtomicUoDecU32.asm $ +;; @file +; IPRT - ASMAtomicUoDecU32(). +; + +; +; Copyright (C) 2014-2020 Oracle Corporation +; +; This file is part of VirtualBox Open Source Edition (OSE), as +; available from http://www.virtualbox.org. This file is free software; +; you can redistribute it and/or modify it under the terms of the GNU +; General Public License (GPL) as published by the Free Software +; Foundation, in version 2 as it comes in the "COPYING" file of the +; VirtualBox OSE distribution. VirtualBox OSE is distributed in the +; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL) only, as it comes in the "COPYING.CDDL" file of the +; VirtualBox OSE 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. +; + +;******************************************************************************* +;* Header Files * +;******************************************************************************* +%include "iprt/asmdefs.mac" + +BEGINCODE + +;; +; Atomically decrement an unsigned 32-bit value, unordered. +; +; @param pu32 x86:esp+4 gcc:rdi msc:rcx + +; @returns the new decremented value. +; +BEGINPROC_EXPORTED ASMAtomicUoDecU32 + mov eax, -1 +%ifdef RT_ARCH_AMD64 + %ifdef ASM_CALL64_MSC + xadd [rcx], eax + %else + xadd [rdi], eax + %endif +%elifdef RT_ARCH_X86 + mov ecx, [esp + 04h] + xadd [ecx], eax +%endif + dec eax + ret +ENDPROC ASMAtomicUoDecU32 + diff --git a/src/VBox/Runtime/common/asm/ASMAtomicUoIncU32.asm b/src/VBox/Runtime/common/asm/ASMAtomicUoIncU32.asm new file mode 100644 index 00000000..8ac8d3dd --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMAtomicUoIncU32.asm @@ -0,0 +1,56 @@ +; $Id: ASMAtomicUoIncU32.asm $ +;; @file +; IPRT - ASMAtomicUoIncU32(). +; + +; +; Copyright (C) 2014-2020 Oracle Corporation +; +; This file is part of VirtualBox Open Source Edition (OSE), as +; available from http://www.virtualbox.org. This file is free software; +; you can redistribute it and/or modify it under the terms of the GNU +; General Public License (GPL) as published by the Free Software +; Foundation, in version 2 as it comes in the "COPYING" file of the +; VirtualBox OSE distribution. VirtualBox OSE is distributed in the +; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL) only, as it comes in the "COPYING.CDDL" file of the +; VirtualBox OSE 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. +; + +;******************************************************************************* +;* Header Files * +;******************************************************************************* +%include "iprt/asmdefs.mac" + +BEGINCODE + +;; +; Atomically increment an unsigned 32-bit value, unordered. +; +; @param pu32 x86:esp+4 gcc:rdi msc:rcx +; +; @returns the new incremented value. +; +BEGINPROC_EXPORTED ASMAtomicUoIncU32 + mov eax, 1 +%ifdef RT_ARCH_AMD64 + %ifdef ASM_CALL64_MSC + xadd [rcx], eax + %else + xadd [rdi], eax + %endif +%elifdef RT_ARCH_X86 + mov ecx, [esp + 04h] + xadd [ecx], eax +%endif + inc eax + ret +ENDPROC ASMAtomicUoIncU32 + diff --git a/src/VBox/Runtime/common/asm/ASMAtomicUoOrU32.asm b/src/VBox/Runtime/common/asm/ASMAtomicUoOrU32.asm new file mode 100644 index 00000000..d97a3d51 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMAtomicUoOrU32.asm @@ -0,0 +1,56 @@ +; $Id: ASMAtomicUoOrU32.asm $ +;; @file +; IPRT - ASMAtomicUoOrU32(). +; + +; +; Copyright (C) 2013-2020 Oracle Corporation +; +; This file is part of VirtualBox Open Source Edition (OSE), as +; available from http://www.virtualbox.org. This file is free software; +; you can redistribute it and/or modify it under the terms of the GNU +; General Public License (GPL) as published by the Free Software +; Foundation, in version 2 as it comes in the "COPYING" file of the +; VirtualBox OSE distribution. VirtualBox OSE is distributed in the +; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL) only, as it comes in the "COPYING.CDDL" file of the +; VirtualBox OSE 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. +; + +;******************************************************************************* +;* Header Files * +;******************************************************************************* +%include "iprt/asmdefs.mac" + +BEGINCODE + +;; +; Atomically OR an unsigned 32-bit value, unordered. +; +; @param pu32 x86:esp+4 gcc:rdi msc:rcx +; @param u32Or x86:esp+8 gcc:rsi msc:rdx +; +; @returns void +; +BEGINPROC_EXPORTED ASMAtomicUoOrU32 +%ifdef RT_ARCH_AMD64 + %ifdef ASM_CALL64_MSC + or [rcx], edx + %else + or [rdi], esi + %endif +%elifdef RT_ARCH_X86 + mov ecx, [esp + 04h] + mov edx, [esp + 08h] + or [ecx], edx +%endif + ret +ENDPROC ASMAtomicUoOrU32 + diff --git a/src/VBox/Runtime/common/asm/ASMAtomicUoOrU64.asm b/src/VBox/Runtime/common/asm/ASMAtomicUoOrU64.asm new file mode 100644 index 00000000..d169b7e2 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMAtomicUoOrU64.asm @@ -0,0 +1,76 @@ +; $Id: ASMAtomicUoOrU64.asm $ +;; @file +; IPRT - ASMAtomicUoOrU64(). +; + +; +; Copyright (C) 2013-2020 Oracle Corporation +; +; This file is part of VirtualBox Open Source Edition (OSE), as +; available from http://www.virtualbox.org. This file is free software; +; you can redistribute it and/or modify it under the terms of the GNU +; General Public License (GPL) as published by the Free Software +; Foundation, in version 2 as it comes in the "COPYING" file of the +; VirtualBox OSE distribution. VirtualBox OSE is distributed in the +; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL) only, as it comes in the "COPYING.CDDL" file of the +; VirtualBox OSE 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. +; + +;******************************************************************************* +;* Header Files * +;******************************************************************************* +%include "iprt/asmdefs.mac" + +BEGINCODE + +;; +; Atomically OR an unsigned 64-bit value, unordered. +; +; @param pu64 x86:ebp+8 gcc:rdi msc:rcx +; @param u64Or x86:ebp+c gcc:rsi msc:rdx +; +; @returns void +; +BEGINPROC_EXPORTED ASMAtomicUoOrU64 +%ifdef RT_ARCH_AMD64 + %ifdef ASM_CALL64_MSC + or [rcx], rdx + %else + or [rdi], rsi + %endif +%elifdef RT_ARCH_X86 + push ebp + mov ebp, esp + push ebx + push edi + + mov edi, [ebp + 08h] + mov ebx, [ebp + 0ch] + mov ecx, [ebp + 0ch + 4] + mov eax, ebx + mov edx, ecx +.try_again: + cmpxchg8b [edi] + jz .done + mov ebx, eax + or ebx, [ebp + 0ch] + mov ecx, edx + or ecx, [ebp + 0ch + 4] + jmp .try_again + +.done: + pop edi + pop ebx + leave +%endif + ret +ENDPROC ASMAtomicUoOrU64 + diff --git a/src/VBox/Runtime/common/asm/ASMAtomicUoReadU64.asm b/src/VBox/Runtime/common/asm/ASMAtomicUoReadU64.asm new file mode 100644 index 00000000..43a1050d --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMAtomicUoReadU64.asm @@ -0,0 +1,70 @@ +; $Id: ASMAtomicUoReadU64.asm $ +;; @file +; IPRT - ASMAtomicUoReadU64(). +; + +; +; Copyright (C) 2006-2020 Oracle Corporation +; +; This file is part of VirtualBox Open Source Edition (OSE), as +; available from http://www.virtualbox.org. This file is free software; +; you can redistribute it and/or modify it under the terms of the GNU +; General Public License (GPL) as published by the Free Software +; Foundation, in version 2 as it comes in the "COPYING" file of the +; VirtualBox OSE distribution. VirtualBox OSE is distributed in the +; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL) only, as it comes in the "COPYING.CDDL" file of the +; VirtualBox OSE 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. +; + +;******************************************************************************* +;* Header Files * +;******************************************************************************* +%include "iprt/asmdefs.mac" + +BEGINCODE + +;; +; Atomically reads 64-bit value. +; +; @param pu64 x86:ebp+8 +; +; @returns The current value. (x86:eax+edx) +; +; +BEGINPROC_EXPORTED ASMAtomicUoReadU64 +%ifdef RT_ARCH_AMD64 + %ifdef ASM_CALL64_MSC + mov rax, [rcx] + %else + mov rax, [rdi] + %endif + ret +%endif +%ifdef RT_ARCH_X86 + push ebp + mov ebp, esp + push ebx + push edi + + xor eax, eax + xor edx, edx + mov edi, [ebp+08h] + xor ecx, ecx + xor ebx, ebx + lock cmpxchg8b [edi] + + pop edi + pop ebx + leave + ret +%endif +ENDPROC ASMAtomicUoReadU64 + diff --git a/src/VBox/Runtime/common/asm/ASMAtomicXchgU16.asm b/src/VBox/Runtime/common/asm/ASMAtomicXchgU16.asm new file mode 100644 index 00000000..03347959 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMAtomicXchgU16.asm @@ -0,0 +1,60 @@ +; $Id: ASMAtomicXchgU16.asm $ +;; @file +; IPRT - ASMAtomicXchgU16(). +; + +; +; Copyright (C) 2006-2020 Oracle Corporation +; +; This file is part of VirtualBox Open Source Edition (OSE), as +; available from http://www.virtualbox.org. This file is free software; +; you can redistribute it and/or modify it under the terms of the GNU +; General Public License (GPL) as published by the Free Software +; Foundation, in version 2 as it comes in the "COPYING" file of the +; VirtualBox OSE distribution. VirtualBox OSE is distributed in the +; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL) only, as it comes in the "COPYING.CDDL" file of the +; VirtualBox OSE 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. +; + +;******************************************************************************* +;* Header Files * +;******************************************************************************* +%include "iprt/asmdefs.mac" + +BEGINCODE + +;; +; Atomically Exchange an unsigned 16-bit value, ordered. +; +; @param pu16 x86:ebp+8 gcc:rdi msc:rcx +; @param u16New x86:ebp+c gcc:si msc:dx +; +; @returns Current (i.e. old) *pu16 value (AX). +; +BEGINPROC_EXPORTED ASMAtomicXchgU16 +%ifdef RT_ARCH_AMD64 + %ifdef ASM_CALL64_MSC + mov ax, dx + xchg [rcx], ax + %else + mov ax, si + xchg [rdi], ax + %endif +%elifdef RT_ARCH_X86 + mov ecx, [esp+04h] + mov ax, [esp+08h] + xchg [ecx], ax +%else + %error "Unsupport arch." +%endif + ret +ENDPROC ASMAtomicXchgU16 + diff --git a/src/VBox/Runtime/common/asm/ASMAtomicXchgU64.asm b/src/VBox/Runtime/common/asm/ASMAtomicXchgU64.asm new file mode 100644 index 00000000..6687da75 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMAtomicXchgU64.asm @@ -0,0 +1,70 @@ +; $Id: ASMAtomicXchgU64.asm $ +;; @file +; IPRT - ASMAtomicXchgU64(). +; + +; +; Copyright (C) 2006-2020 Oracle Corporation +; +; This file is part of VirtualBox Open Source Edition (OSE), as +; available from http://www.virtualbox.org. This file is free software; +; you can redistribute it and/or modify it under the terms of the GNU +; General Public License (GPL) as published by the Free Software +; Foundation, in version 2 as it comes in the "COPYING" file of the +; VirtualBox OSE distribution. VirtualBox OSE is distributed in the +; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL) only, as it comes in the "COPYING.CDDL" file of the +; VirtualBox OSE 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. +; + +;******************************************************************************* +;* Header Files * +;******************************************************************************* +%include "iprt/asmdefs.mac" + +BEGINCODE + +;; +; Atomically Exchange an unsigned 64-bit value, ordered. +; +; @param pu64 x86:ebp+8 gcc:rdi msc:rcx +; @param u64New x86:ebp+c gcc:rsi msc:rdx +; +; @returns Current (i.e. old) *pu64 value (x86:eax:edx, 64-bit: rax) +; +BEGINPROC_EXPORTED ASMAtomicXchgU64 +%ifdef RT_ARCH_AMD64 + %ifdef ASM_CALL64_MSC + xchg [rcx], rdx + %else + xchg [rdi], rsi + %endif + ret +%endif +%ifdef RT_ARCH_X86 + push ebp + mov ebp, esp + push ebx + push edi + +.try_again: + mov ebx, dword [ebp+0ch] + mov ecx, dword [ebp+0ch + 4] + mov edi, [ebp+08h] + lock cmpxchg8b [edi] + jnz .try_again + + pop edi + pop ebx + leave + ret +%endif +ENDPROC ASMAtomicXchgU64 + diff --git a/src/VBox/Runtime/common/asm/ASMBitFirstClear.asm b/src/VBox/Runtime/common/asm/ASMBitFirstClear.asm new file mode 100644 index 00000000..3d1eac3e --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMBitFirstClear.asm @@ -0,0 +1,127 @@ +; $Id: ASMBitFirstClear.asm $ +;; @file +; IPRT - ASMBitFirstClear(). +; + +; +; Copyright (C) 2006-2020 Oracle Corporation +; +; This file is part of VirtualBox Open Source Edition (OSE), as +; available from http://www.virtualbox.org. This file is free software; +; you can redistribute it and/or modify it under the terms of the GNU +; General Public License (GPL) as published by the Free Software +; Foundation, in version 2 as it comes in the "COPYING" file of the +; VirtualBox OSE distribution. VirtualBox OSE is distributed in the +; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL) only, as it comes in the "COPYING.CDDL" file of the +; VirtualBox OSE 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. +; + + +;******************************************************************************* +;* Header Files * +;******************************************************************************* +%include "iprt/asmdefs.mac" + +BEGINCODE + +;; +; Finds the first clear bit in a bitmap. +; +; @returns (32/64:eax, 16:ax+dx) Index of the first zero bit. +; @returns (32/64:eax, 16:ax+dx) -1 if no clear bit was found. +; @param msc:rcx gcc:rdi pvBitmap Pointer to the bitmap. +; @param msc:edx gcc:rsi cBits The number of bits in the bitmap. Multiple of 32. +; +BEGINPROC_EXPORTED ASMBitFirstClear + ; + ; if (cBits) + ; Put cBits in ecx first. + ; +%if ARCH_BITS == 64 + %ifdef ASM_CALL64_GCC + mov ecx, esi + %else + xchg rcx, rdx ; rdx=pvDst, ecx=cBits + %endif +%elif ARCH_BITS == 32 + mov ecx, [esp + 4 + 4] +%elif ARCH_BITS == 16 + push bp + mov bp, sp + mov ecx, [bp + 4 + 4] +%endif + or ecx, ecx + jz short .failed + ;{ + push xDI + + ; asm {...} +%if ARCH_BITS == 64 + %ifdef ASM_CALL64_GCC + ; rdi = start of scasd - already done + %else + mov rdi, rdx ; rdi = start of scasd (Note! xchg rdx,rcx above) + %endif +%elif ARCH_BITS == 32 + mov edi, [esp + 8] +%elif ARCH_BITS == 16 + mov ax, [bp + 4 + 2] + mov di, [bp + 4] + mov es, ax ; es is volatile, no need to save. +%endif + add ecx, 31 ; 32 bit aligned + shr ecx, 5 ; number of dwords to scan. + mov xDX, xDI ; xDX = saved pvBitmap + mov eax, 0ffffffffh + repe scasd ; Scan for the first dword with any clear bit. + je .failed_restore + + ; find the bit in question + sub xDI, 4 ; one step back. +%if ARCH_BITS == 16 + movzx edi, di + xor eax, [es:xDI] ; eax = NOT [rdi] +%else + xor eax, [xDI] ; eax = NOT [rdi] +%endif + sub xDI, xDX + shl edi, 3 ; calc bit offset. + + bsf ecx, eax + jz .failed_restore ; race paranoia + add ecx, edi + mov eax, ecx + + ; return success + pop xDI +%if ARCH_BITS == 16 + mov edx, eax + shr edx, 16 + leave +%endif + ret + + ; failure + ;} + ;return -1; +.failed_restore: + pop xDI +.failed: +%if ARCH_BITS != 16 + mov eax, 0ffffffffh +%else + mov ax, 0ffffh + mov dx, ax + leave +%endif + ret +ENDPROC ASMBitFirstClear + diff --git a/src/VBox/Runtime/common/asm/ASMBitFirstSet.asm b/src/VBox/Runtime/common/asm/ASMBitFirstSet.asm new file mode 100644 index 00000000..303ae8a6 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMBitFirstSet.asm @@ -0,0 +1,127 @@ +; $Id: ASMBitFirstSet.asm $ +;; @file +; IPRT - ASMBitFirstSet(). +; + +; +; Copyright (C) 2006-2020 Oracle Corporation +; +; This file is part of VirtualBox Open Source Edition (OSE), as +; available from http://www.virtualbox.org. This file is free software; +; you can redistribute it and/or modify it under the terms of the GNU +; General Public License (GPL) as published by the Free Software +; Foundation, in version 2 as it comes in the "COPYING" file of the +; VirtualBox OSE distribution. VirtualBox OSE is distributed in the +; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL) only, as it comes in the "COPYING.CDDL" file of the +; VirtualBox OSE 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. +; + + +;******************************************************************************* +;* Header Files * +;******************************************************************************* +%include "iprt/asmdefs.mac" + +BEGINCODE + +;; +; Finds the first set bit in a bitmap. +; +; @returns (32/64:eax, 16:ax+dx) Index of the first zero bit. +; @returns (32/64:eax, 16:ax+dx) -1 if no set bit was found. +; @param msc:rcx gcc:rdi pvBitmap Pointer to the bitmap. +; @param msc:edx gcc:rsi cBits The number of bits in the bitmap. Multiple of 32. +; +BEGINPROC_EXPORTED ASMBitFirstSet + ; + ; if (cBits) + ; Put cBits in ecx first. + ; +%if ARCH_BITS == 64 + %ifdef ASM_CALL64_GCC + mov ecx, esi + %else + xchg rcx, rdx ; rdx=pvDst, ecx=cBits + %endif +%elif ARCH_BITS == 32 + mov ecx, [esp + 4 + 4] +%elif ARCH_BITS == 16 + push bp + mov bp, sp + mov ecx, [bp + 4 + 4] +%endif + or ecx, ecx + jz short .failed + ;{ + push xDI + + ; asm {...} +%if ARCH_BITS == 64 + %ifdef ASM_CALL64_GCC + ; rdi = start of scasd - already done + %else + mov rdi, rdx ; rdi = start of scasd (Note! xchg rdx,rcx above) + %endif +%elif ARCH_BITS == 32 + mov edi, [esp + 4] +%elif ARCH_BITS == 16 + mov ax, [bp + 4 + 2] + mov di, [bp + 4] + mov es, ax ; es is volatile, no need to save. +%endif + add ecx, 31 ; 32 bit aligned + shr ecx, 5 ; number of dwords to scan. + mov xDX, xDI ; xDX = saved pvBitmap + xor eax, eax + repe scasd ; Scan for the first dword with any bit set. + je .failed_restore + + ; find the bit in question + sub xDI, 4 ; one step back. +%if ARCH_BITS == 16 + movzx edi, di + mov eax, [es:xDI] +%else + mov eax, [xDI] +%endif + sub xDI, xDX + shl edi, 3 ; calc bit offset. + + bsf ecx, eax + jz .failed_restore ; race paranoia + add ecx, edi + mov eax, ecx + + ; return success + pop xDI +%if ARCH_BITS == 16 + mov edx, eax + shr edx, 16 + leave +%endif + ret + + ; failure + ;} + ;return -1; +.failed_restore: + pop xDI +.failed: +%if ARCH_BITS != 16 + mov eax, 0ffffffffh +%else + mov ax, 0ffffh + mov dx, ax + leave +%endif + ret +ENDPROC ASMBitFirstSet + diff --git a/src/VBox/Runtime/common/asm/ASMBitFirstSetU16.asm b/src/VBox/Runtime/common/asm/ASMBitFirstSetU16.asm new file mode 100644 index 00000000..5e44fb22 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMBitFirstSetU16.asm @@ -0,0 +1,93 @@ +; $Id: ASMBitFirstSetU16.asm $ +;; @file +; IPRT - ASMBitFirstSetU16(). +; + +; +; Copyright (C) 2006-2020 Oracle Corporation +; +; This file is part of VirtualBox Open Source Edition (OSE), as +; available from http://www.virtualbox.org. This file is free software; +; you can redistribute it and/or modify it under the terms of the GNU +; General Public License (GPL) as published by the Free Software +; Foundation, in version 2 as it comes in the "COPYING" file of the +; VirtualBox OSE distribution. VirtualBox OSE is distributed in the +; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL) only, as it comes in the "COPYING.CDDL" file of the +; VirtualBox OSE 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. +; + + +;******************************************************************************* +;* Header Files * +;******************************************************************************* +%include "iprt/asmdefs.mac" + +BEGINCODE + +;; +; Finds the first bit which is set in the given 16-bit integer. +; +; Bits are numbered from 1 (least significant) to 16. +; +; @returns (xAX) index [1..16] of the first set bit. +; @returns (xAX) 0 if all bits are cleared. +; @param msc:cx gcc:di x86:stack u16 Integer to search for set bits. +; +; @cproto DECLASM(unsigned) ASMBitFirstSetU16(uint16_t u16); +; +BEGINPROC_EXPORTED ASMBitFirstSetU16 +%if ARCH_BITS == 16 + CPU 8086 + push bp + mov bp, sp + + ; 16:0 + mov ax, 1 + mov cx, [bp + 2 + 2 + 0] + test cx, cx + jz .return_zero + + ; find the bit that was set. +.next_bit: + shr cx, 1 + jc .return + inc ax + jmp .next_bit + +.return_zero: + xor ax, ax +.return: + pop bp + ret + +%else + xor eax, eax + %if ARCH_BITS == 64 + %ifdef ASM_CALL64_GCC + bsf ax, si + %else + bsf ax, cx + %endif + %elif ARCH_BITS == 32 + bsf ax, word [esp + 4] + %else + %error "Missing or invalid ARCH_BITS." + %endif + jz .return_zero + inc eax +.return: + ret +.return_zero: + xor eax, eax + ret +%endif +ENDPROC ASMBitFirstSetU16 + diff --git a/src/VBox/Runtime/common/asm/ASMBitFirstSetU32.asm b/src/VBox/Runtime/common/asm/ASMBitFirstSetU32.asm new file mode 100644 index 00000000..c6c20a46 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMBitFirstSetU32.asm @@ -0,0 +1,97 @@ +; $Id: ASMBitFirstSetU32.asm $ +;; @file +; IPRT - ASMBitFirstSetU32(). +; + +; +; Copyright (C) 2006-2020 Oracle Corporation +; +; This file is part of VirtualBox Open Source Edition (OSE), as +; available from http://www.virtualbox.org. This file is free software; +; you can redistribute it and/or modify it under the terms of the GNU +; General Public License (GPL) as published by the Free Software +; Foundation, in version 2 as it comes in the "COPYING" file of the +; VirtualBox OSE distribution. VirtualBox OSE is distributed in the +; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL) only, as it comes in the "COPYING.CDDL" file of the +; VirtualBox OSE 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. +; + + +;******************************************************************************* +;* Header Files * +;******************************************************************************* +%include "iprt/asmdefs.mac" + +BEGINCODE + +;; +; Finds the first bit which is set in the given 32-bit integer. +; +; Bits are numbered from 1 (least significant) to 32. +; +; @returns (xAX) index [1..32] of the first set bit. +; @returns (xAX) 0 if all bits are cleared. +; @param msc:ecx gcc:edi x86:stack u32 Integer to search for set bits. +; +; @cproto DECLASM(unsigned) ASMBitFirstSetU32(uint32_t u32); +; +BEGINPROC_EXPORTED ASMBitFirstSetU32 +%if ARCH_BITS == 16 + CPU 8086 + push bp + mov bp, sp + + ; 15:0 + mov ax, 1 + mov cx, [bp + 2 + 2 + 0] + test cx, cx + jnz .next_bit + + ; 31:16 + mov al, 16 + or cx, [bp + 2 + 2 + 2] + jz .return_zero + + ; find the bit that was set. +.next_bit: + shr cx, 1 + jc .return + inc ax + jmp .next_bit + +.return_zero: + xor ax, ax +.return: + pop bp + ret + +%else + %if ARCH_BITS == 64 + %ifdef ASM_CALL64_GCC + bsf eax, esi + %else + bsf eax, ecx + %endif + %elif ARCH_BITS == 32 + bsf eax, dword [esp + 4] + %else + %error "Missing or invalid ARCH_BITS." + %endif + jz .return_zero + inc eax +.return: + ret +.return_zero: + xor eax, eax + ret +%endif +ENDPROC ASMBitFirstSetU32 + diff --git a/src/VBox/Runtime/common/asm/ASMBitFirstSetU64.asm b/src/VBox/Runtime/common/asm/ASMBitFirstSetU64.asm new file mode 100644 index 00000000..5f3a40d1 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMBitFirstSetU64.asm @@ -0,0 +1,116 @@ +; $Id: ASMBitFirstSetU64.asm $ +;; @file +; IPRT - ASMBitFirstSetU64(). +; + +; +; Copyright (C) 2006-2020 Oracle Corporation +; +; This file is part of VirtualBox Open Source Edition (OSE), as +; available from http://www.virtualbox.org. This file is free software; +; you can redistribute it and/or modify it under the terms of the GNU +; General Public License (GPL) as published by the Free Software +; Foundation, in version 2 as it comes in the "COPYING" file of the +; VirtualBox OSE distribution. VirtualBox OSE is distributed in the +; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL) only, as it comes in the "COPYING.CDDL" file of the +; VirtualBox OSE 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. +; + + +;******************************************************************************* +;* Header Files * +;******************************************************************************* +%include "iprt/asmdefs.mac" + +BEGINCODE + +;; +; Finds the first bit which is set in the given 64-bit integer. +; +; Bits are numbered from 1 (least significant) to 64. +; +; @returns (xAX) index [1..64] of the first set bit. +; @returns (xAX) 0 if all bits are cleared. +; @param msc:rcx gcc:rdi x86:stack u64 Integer to search for set bits. +; +; @cproto DECLASM(unsigned) ASMBitFirstSetU64(uint64_t u64); +; +BEGINPROC_EXPORTED ASMBitFirstSetU64 +%if ARCH_BITS == 16 + CPU 8086 + push bp + mov bp, sp + + ; 15:0 + mov ax, 1 + mov cx, [bp + 2 + 2 + 0] + test cx, cx + jnz .next_bit + + ; 31:16 + mov al, 16 + or cx, [bp + 2 + 2 + 2] + jnz .next_bit + + ; 47:32 + mov al, 32 + or cx, [bp + 2 + 2 + 4] + jnz .next_bit + + ; 63:48 + mov al, 48 + or cx, [bp + 2 + 2 + 6] + jz .return_zero + + ; find the bit that was set. +.next_bit: + shr cx, 1 + jc .return + inc ax + jmp .next_bit + +.return_zero: + xor ax, ax +.return: + pop bp + ret + +%else + %if ARCH_BITS == 64 + %ifdef ASM_CALL64_GCC + bsf rax, rsi + %else + bsf rax, rcx + %endif + jz .return_zero + inc eax + ret + + %elif ARCH_BITS == 32 + ; Check the first dword then the 2nd one. + bsf eax, dword [esp + 4 + 0] + jnz .check_2nd_dword + inc eax + ret +.check_2nd_dword: + bsf eax, dword [esp + 4 + 4] + jz .return_zero + add eax, 32 + ret + %else + %error "Missing or invalid ARCH_BITS." + %endif +.return_zero: + xor eax, eax + ret +%endif +ENDPROC ASMBitFirstSetU64 + diff --git a/src/VBox/Runtime/common/asm/ASMBitLastSetU16.asm b/src/VBox/Runtime/common/asm/ASMBitLastSetU16.asm new file mode 100644 index 00000000..a7313f9c --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMBitLastSetU16.asm @@ -0,0 +1,91 @@ +; $Id: ASMBitLastSetU16.asm $ +;; @file +; IPRT - ASMBitLastSetU16(). +; + +; +; Copyright (C) 2006-2020 Oracle Corporation +; +; This file is part of VirtualBox Open Source Edition (OSE), as +; available from http://www.virtualbox.org. This file is free software; +; you can redistribute it and/or modify it under the terms of the GNU +; General Public License (GPL) as published by the Free Software +; Foundation, in version 2 as it comes in the "COPYING" file of the +; VirtualBox OSE distribution. VirtualBox OSE is distributed in the +; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL) only, as it comes in the "COPYING.CDDL" file of the +; VirtualBox OSE 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. +; + + +;******************************************************************************* +;* Header Files * +;******************************************************************************* +%include "iprt/asmdefs.mac" + +BEGINCODE + +;; +; Finds the last bit which is set in the given 16-bit integer. +; +; Bits are numbered from 1 (least significant) to 16. +; +; @returns (xAX) index [1..16] of the last set bit. +; @returns (xAX) 0 if all bits are cleared. +; @param msc:cx gcc:di x86:stack u16 Integer to search for set bits. +; +; @cproto DECLASM(unsigned) ASMBitLastSetU16(uint32_t u16); +; +BEGINPROC_EXPORTED ASMBitLastSetU16 +%if ARCH_BITS == 16 + CPU 8086 + push bp + mov bp, sp + + mov cx, [bp + 2 + 2] + test cx, cx ; check if zero (eliminates checking dec ax result) + jz .return_zero + + mov ax, 16 +.next_bit: + shl cx, 1 + jc .return + dec ax + jmp .next_bit + +.return_zero: + xor ax, ax +.return: + pop bp + ret + +%else + xor eax, eax + %if ARCH_BITS == 64 + %ifdef ASM_CALL64_GCC + bsr ax, si + %else + bsr ax, cx + %endif + %elif ARCH_BITS == 32 + bsr ax, word [esp + 4] + %else + %error "Missing or invalid ARCH_BITS." + %endif + jz .return_zero + inc eax +.return: + ret +.return_zero: + xor eax, eax + ret +%endif +ENDPROC ASMBitLastSetU16 + diff --git a/src/VBox/Runtime/common/asm/ASMBitLastSetU32.asm b/src/VBox/Runtime/common/asm/ASMBitLastSetU32.asm new file mode 100644 index 00000000..622e2ffb --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMBitLastSetU32.asm @@ -0,0 +1,97 @@ +; $Id: ASMBitLastSetU32.asm $ +;; @file +; IPRT - ASMBitLastSetU32(). +; + +; +; Copyright (C) 2006-2020 Oracle Corporation +; +; This file is part of VirtualBox Open Source Edition (OSE), as +; available from http://www.virtualbox.org. This file is free software; +; you can redistribute it and/or modify it under the terms of the GNU +; General Public License (GPL) as published by the Free Software +; Foundation, in version 2 as it comes in the "COPYING" file of the +; VirtualBox OSE distribution. VirtualBox OSE is distributed in the +; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL) only, as it comes in the "COPYING.CDDL" file of the +; VirtualBox OSE 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. +; + + +;******************************************************************************* +;* Header Files * +;******************************************************************************* +%include "iprt/asmdefs.mac" + +BEGINCODE + +;; +; Finds the last bit which is set in the given 32-bit integer. +; +; Bits are numbered from 1 (least significant) to 32. +; +; @returns (xAX) index [1..32] of the last set bit. +; @returns (xAX) 0 if all bits are cleared. +; @param msc:ecx gcc:edi x86:stack u32 Integer to search for set bits. +; +; @cproto DECLASM(unsigned) ASMBitLastSetU32(uint32_t u32); +; +BEGINPROC_EXPORTED ASMBitLastSetU32 +%if ARCH_BITS == 16 + CPU 8086 + push bp + mov bp, sp + + ; high word. + mov ax, 32 + mov cx, [bp + 2 + 4] + test cx, cx + jnz .next_bit + + ; low word. + mov al, 16 + or cx, [bp + 2 + 2] + jz .return_zero + + ; find the bit that was set. +.next_bit: + shl cx, 1 + jc .return + dec ax + jmp .next_bit + +.return_zero: + xor ax, ax +.return: + pop bp + ret + +%else + %if ARCH_BITS == 64 + %ifdef ASM_CALL64_GCC + bsr eax, esi + %else + bsr eax, ecx + %endif + %elif ARCH_BITS == 32 + bsr eax, dword [esp + 4] + %else + %error "Missing or invalid ARCH_BITS." + %endif + jz .return_zero + inc eax +.return: + ret +.return_zero: + xor eax, eax + ret +%endif +ENDPROC ASMBitLastSetU32 + diff --git a/src/VBox/Runtime/common/asm/ASMBitLastSetU64.asm b/src/VBox/Runtime/common/asm/ASMBitLastSetU64.asm new file mode 100644 index 00000000..35443f9d --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMBitLastSetU64.asm @@ -0,0 +1,120 @@ +; $Id: ASMBitLastSetU64.asm $ +;; @file +; IPRT - ASMBitLastSetU64(). +; + +; +; Copyright (C) 2006-2020 Oracle Corporation +; +; This file is part of VirtualBox Open Source Edition (OSE), as +; available from http://www.virtualbox.org. This file is free software; +; you can redistribute it and/or modify it under the terms of the GNU +; General Public License (GPL) as published by the Free Software +; Foundation, in version 2 as it comes in the "COPYING" file of the +; VirtualBox OSE distribution. VirtualBox OSE is distributed in the +; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL) only, as it comes in the "COPYING.CDDL" file of the +; VirtualBox OSE 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. +; + + +;******************************************************************************* +;* Header Files * +;******************************************************************************* +%include "iprt/asmdefs.mac" + +BEGINCODE + +;; +; Finds the last bit which is set in the given 64-bit integer. +; +; Bits are numbered from 1 (least significant) to 64. +; +; @returns (xAX) index [1..64] of the last set bit. +; @returns (xAX) 0 if all bits are cleared. +; @param msc:rcx gcc:rdi x86:stack u64 Integer to search for set bits. +; +; @cproto DECLASM(unsigned) ASMBitLastSetU64(uint64_t u64); +; +BEGINPROC_EXPORTED ASMBitLastSetU64 +%if ARCH_BITS == 16 + CPU 8086 + push bp + mov bp, sp + + ; 63:48 + mov ax, 64 + mov cx, [bp + 2 + 2 + 6] + test cx, cx + jnz .next_bit + + ; 47:32 + mov al, 48 + or cx, [bp + 2 + 2 + 4] + jnz .next_bit + + ; 31:16 + mov al, 32 + or cx, [bp + 2 + 2 + 2] + jnz .next_bit + + ; 16:0 + mov al, 16 + or cx, [bp + 2 + 2 + 0] + jz .return_zero + + ; find the bit that was set. +.next_bit: + shl cx, 1 + jc .return + dec ax + jmp .next_bit + +.return_zero: + xor ax, ax +.return: + pop bp + ret + +%else + %if ARCH_BITS == 64 + %ifdef ASM_CALL64_GCC + bsr rax, rsi + %else + bsr rax, rcx + %endif + jz .return_zero + inc eax +.return: + ret + + %elif ARCH_BITS == 32 + ; Check the 2nd dword then the first one. + bsr eax, dword [esp + 4 + 4] + jz .check_1st_dword + add eax, 32 + ret + +.check_1st_dword: + bsr eax, dword [esp + 4 + 0] + jz .return_zero + inc eax + ret + + %else + %error "Missing or invalid ARCH_BITS." + %endif + +.return_zero: + xor eax, eax + ret +%endif +ENDPROC ASMBitLastSetU64 + diff --git a/src/VBox/Runtime/common/asm/ASMBitNextClear.asm b/src/VBox/Runtime/common/asm/ASMBitNextClear.asm new file mode 100644 index 00000000..da3b6016 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMBitNextClear.asm @@ -0,0 +1,173 @@ +; $Id: ASMBitNextClear.asm $ +;; @file +; IPRT - ASMBitNextClear(). +; + +; +; Copyright (C) 2006-2020 Oracle Corporation +; +; This file is part of VirtualBox Open Source Edition (OSE), as +; available from http://www.virtualbox.org. This file is free software; +; you can redistribute it and/or modify it under the terms of the GNU +; General Public License (GPL) as published by the Free Software +; Foundation, in version 2 as it comes in the "COPYING" file of the +; VirtualBox OSE distribution. VirtualBox OSE is distributed in the +; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL) only, as it comes in the "COPYING.CDDL" file of the +; VirtualBox OSE 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. +; + + +;******************************************************************************* +;* Header Files * +;******************************************************************************* +%include "iprt/asmdefs.mac" + +BEGINCODE + +;; +; Finds the next clear bit in a bitmap. +; +; @returns (32/64:eax, 16:ax+dx) Index of the first zero bit. +; @returns (32/64:eax, 16:ax+dx) -1 if no clear bit was found. +; @param msc:rcx gcc:rdi pvBitmap Pointer to the bitmap. +; @param msc:edx gcc:rsi cBits The number of bits in the bitmap. Multiple of 32. +; @param msc:r8d gcc:rcx iBitPrev The previous bit, start searching after it. +; +; @remarks Not quite sure how much sense it makes to do this in assembly, but +; it started out with the ASMBit* API, so that's why we still have it. +; +BEGINPROC_EXPORTED ASMBitNextClear +%if ARCH_BITS == 16 + push bp + mov bp, sp +%endif + push xDI + + ; + ; Align input registers: rdi=pvBitmap, ecx=iPrevBit + ; +%if ARCH_BITS == 64 + %ifdef ASM_CALL64_GCC + ; ecx = iBitPrev param, rdi=pvBitmap param. + %else + mov rdi, rcx ; rdi=pvBits + mov ecx, r8d ; ecx=iPrevBit + mov r8d, edx ; r8d=cBits (saved for .scan_dwords) + %endif + mov r9, rdi ; Save rdi for bit calculation. +%elif ARCH_BITS == 32 + mov edi, [esp + 8] ; edi=pvBits + mov ecx, [esp + 8 + 8] ; ecx=iPrevBit +%elif ARCH_BITS == 16 + les di, [bp + 4] ; es:di=pvBits + mov ecx, [bp + 4 + 8] ; ecx=iPrevBit +%endif + + ; + ; If iPrevBit and iPrevBit + 1 are in the same dword, inspect it for further bits. + ; + inc ecx + mov eax, ecx + shr eax, 5 + shl eax, 2 ; eax=byte offset into bitmap of current dword. + add xDI, xAX ; xDI=current dword address (of iPrevBit + 1). + and ecx, 31 + jz .scan_dwords + +%if ARCH_BITS == 16 + mov edx, [es:di] +%else + mov edx, [xDI] +%endif + not edx ; edx = inverted current dword + shr edx, cl ; Shift out bits that we have searched. + jz .next_dword ; If zero, nothing to find. Go rep scasd. + shl edx, cl ; Shift it back so bsf will return the right index. + + bsf edx, edx ; edx=index of first clear bit + + shl eax, 3 ; Turn eax back into a bit offset of the current dword. + add eax, edx ; eax=bit offset + +.return: + pop xDI +%if ARCH_BITS == 16 + mov edx, eax + shr edx, 16 + leave +%endif + ret + + ; + ; Do dword scan. + ; + + ; Skip empty dword. +.next_dword: + add xDI, 4 ; Skip the empty dword. + add eax, 4 + +.scan_dwords: + ; First load and align bit count. +%if ARCH_BITS == 64 + %ifdef ASM_CALL64_GCC + mov ecx, esi + %else + mov ecx, r8d + %endif +%elif ARCH_BITS == 32 + mov ecx, [esp + 8 + 4] +%elif ARCH_BITS == 16 + mov ecx, [bp + 4 + 4] +%endif + add ecx, 31 + shr ecx, 5 ; ecx=bitmap size in dwords. + + ; Adjust ecx to how many dwords there are left to scan. (eax = current byte offset) + shr eax, 2 ; eax=current dword offset. + sub ecx, eax + jbe .return_failure + + ; Do the scanning. + cld + mov eax, 0ffffffffh + repe scasd + je .return_failure + + ; Find the bit in question. + sub xDI, 4 ; One step back. +%if ARCH_BITS == 16 + movzx edi, di + xor eax, [es:xDI] +%else + xor eax, [xDI] +%endif + bsf eax, eax + jz .return_failure ; race paranoia + + ; Calc the bit offset. +%if ARCH_BITS == 16 + sub di, [bp + 4] + movzx edi, di +%elif ARCH_BITS == 32 + sub xDI, [esp + 8] +%elif ARCH_BITS == 64 + sub xDI, r9 +%endif + shl edi, 3 ; edi=bit offset of current dword. + add eax, edi + jmp .return + +.return_failure: + mov eax, 0ffffffffh + jmp .return +ENDPROC ASMBitNextClear + diff --git a/src/VBox/Runtime/common/asm/ASMBitNextSet.asm b/src/VBox/Runtime/common/asm/ASMBitNextSet.asm new file mode 100644 index 00000000..2b2a080e --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMBitNextSet.asm @@ -0,0 +1,173 @@ +; $Id: ASMBitNextSet.asm $ +;; @file +; IPRT - ASMBitNextSet(). +; + +; +; Copyright (C) 2006-2020 Oracle Corporation +; +; This file is part of VirtualBox Open Source Edition (OSE), as +; available from http://www.virtualbox.org. This file is free software; +; you can redistribute it and/or modify it under the terms of the GNU +; General Public License (GPL) as published by the Free Software +; Foundation, in version 2 as it comes in the "COPYING" file of the +; VirtualBox OSE distribution. VirtualBox OSE is distributed in the +; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL) only, as it comes in the "COPYING.CDDL" file of the +; VirtualBox OSE 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. +; + + +;******************************************************************************* +;* Header Files * +;******************************************************************************* +%include "iprt/asmdefs.mac" + +BEGINCODE + +;; +; Finds the next set bit in a bitmap. +; +; @returns (32/64:eax, 16:ax+dx) Index of the first zero bit. +; @returns (32/64:eax, 16:ax+dx) -1 if no set bit was found. +; @param msc:rcx gcc:rdi pvBitmap Pointer to the bitmap. +; @param msc:edx gcc:rsi cBits The number of bits in the bitmap. Multiple of 32. +; @param msc:r8d gcc:rcx iBitPrev The previous bit, start searching after it. +; +; @remarks Not quite sure how much sense it makes to do this in assembly, but +; it started out with the ASMBit* API, so that's why we still have it. +; +BEGINPROC_EXPORTED ASMBitNextSet +%if ARCH_BITS == 16 + push bp + mov bp, sp +%endif + push xDI + + ; + ; Align input registers: rdi=pvBitmap, ecx=iPrevBit + ; +%if ARCH_BITS == 64 + %ifdef ASM_CALL64_GCC + ; ecx = iBitPrev param, rdi=pvBitmap param. + %else + mov rdi, rcx ; rdi=pvBits + mov ecx, r8d ; ecx=iPrevBit + mov r8d, edx ; r8d=cBits (saved for .scan_dwords) + %endif + mov r9, rdi ; Save rdi for bit calculation. +%elif ARCH_BITS == 32 + mov edi, [esp + 8] ; edi=pvBits + mov ecx, [esp + 8 + 8] ; edx=iPrevBit +%elif ARCH_BITS == 16 + mov ax, [bp + 4 + 2] + mov es, ax + mov di, [bp + 4] ; es:di=pvBits + mov ecx, [bp + 4 + 8] ; edx=iPrevBit +%endif + + ; + ; If iPrevBit and iPrevBit + 1 are in the same dword, inspect it for further bits. + ; + inc ecx + mov eax, ecx + shr eax, 5 + shl eax, 2 ; eax=byte offset into bitmap of current dword. + add xDI, xAX ; xDI=current dword address (of iPrevBit + 1). + and ecx, 31 + jz .scan_dwords + +%if ARCH_BITS == 16 + mov edx, [es:di] ; edx = current dword +%else + mov edx, [xDI] ; edx = current dword +%endif + shr edx, cl ; Shift out bits that we have searched. + jz .next_dword ; If zero, nothing to find. Go rep scasd. + shl edx, cl ; Shift it back so bsf will return the right index. + + bsf edx, edx ; edx=index of first set bit + + shl eax, 3 ; Turn eax back into a bit offset of the current dword. + add eax, edx ; eax=bit offset + +.return: + pop xDI +%if ARCH_BITS == 16 + mov edx, eax + shr edx, 16 + leave +%endif + ret + + ; + ; Do dword scan. + ; + + ; Skip empty dword. +.next_dword: + add xDI, 4 ; Skip the empty dword. + add eax, 4 + +.scan_dwords: + ; First load and align bit count. +%if ARCH_BITS == 64 + %ifdef ASM_CALL64_GCC + mov ecx, esi + %else + mov ecx, r8d + %endif +%elif ARCH_BITS == 32 + mov ecx, [esp + 8 + 4] +%elif ARCH_BITS == 16 + mov ecx, [bp + 4 + 4] +%endif + add ecx, 31 + shr ecx, 5 ; ecx=bitmap size in dwords. + + ; Adjust ecx to how many dwords there are left to scan. (eax = current byte offset) + shr eax, 2 ; eax=current dword offset. + sub ecx, eax + jbe .return_failure + + ; Do the scanning. + xor eax, eax + repe scasd + je .return_failure + + ; Find the bit in question. + sub xDI, 4 ; One step back. +%if ARCH_BITS == 16 + movzx edi, di + mov eax, [es:xDI] +%else + mov eax, [xDI] +%endif + bsf eax, eax + jz .return_failure ; race paranoia + + ; Calc the bit offset. +%if ARCH_BITS == 16 + sub di, [bp + 4] + movzx edi, di +%elif ARCH_BITS == 32 + sub xDI, [esp + 4] +%elif ARCH_BITS == 64 + sub xDI, r9 +%endif + shl edi, 3 ; edi=bit offset of current dword. + add eax, edi + jmp .return + +.return_failure: + mov eax, 0ffffffffh + jmp .return +ENDPROC ASMBitNextSet + diff --git a/src/VBox/Runtime/common/asm/ASMCpuId.asm b/src/VBox/Runtime/common/asm/ASMCpuId.asm new file mode 100644 index 00000000..e0d5fa08 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMCpuId.asm @@ -0,0 +1,111 @@ +; $Id: ASMCpuId.asm $ +;; @file +; IPRT - ASMCpuIdExSlow(). +; + +; +; Copyright (C) 2012-2020 Oracle Corporation +; +; This file is part of VirtualBox Open Source Edition (OSE), as +; available from http://www.virtualbox.org. This file is free software; +; you can redistribute it and/or modify it under the terms of the GNU +; General Public License (GPL) as published by the Free Software +; Foundation, in version 2 as it comes in the "COPYING" file of the +; VirtualBox OSE distribution. VirtualBox OSE is distributed in the +; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL) only, as it comes in the "COPYING.CDDL" file of the +; VirtualBox OSE 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. +; + +;******************************************************************************* +;* Header Files * +;******************************************************************************* +%include "iprt/asmdefs.mac" + +BEGINCODE + +;; +; CPUID with EAX input, returning ALL output registers (no NULL checking). +; +; @param uOperator 8086:bp+4 x86:ebp+8 gcc:rdi msc:rcx +; @param pvEAX 8086:bp+8 x86:ebp+0c gcc:rsi msc:rdx +; @param pvEBX 8086:bp+0c x86:ebp+10 gcc:rdx msc:r8 +; @param pvECX 8086:bp+10 x86:ebp+14 gcc:rcx msc:r9 +; @param pvEDX 8086:bp+14 x86:ebp+18 gcc:r8 msc:rbp+30h +; +; DECLASM(void) ASMCpuId(uint32_t uOperator, void *pvEAX, void *pvEBX, void *pvECX, void *pvEDX); +; +BEGINPROC_EXPORTED ASMCpuId + push xBP + mov xBP, xSP + push xBX + +%ifdef ASM_CALL64_MSC + %if ARCH_BITS != 64 + %error ARCH_BITS mismatch? + %endif + mov eax, ecx + mov r10, rdx + cpuid + mov [r10], eax + mov [r8], ebx + mov [r9], ecx + mov r10, [rbp+30h] + mov [r10], edx + +%elifdef ASM_CALL64_GCC + mov eax, edi + mov r10, rdx + mov r11, rcx + cpuid + mov [rsi], eax + mov [r10], ebx + mov [r11], ecx + mov [r8], edx + +%elif ARCH_BITS == 32 + mov eax, [xBP + 08h] + cpuid + push edx + mov edx, [xBP + 0ch] + mov [edx], eax + mov edx, [xBP + 10h] + mov [edx], ebx + mov edx, [xBP + 14h] + mov [edx], ecx + mov edx, [xBP + 18h] + pop dword [edx] + +%elif ARCH_BITS == 16 + push es + push di + + mov eax, [xBP + 04h] + cpuid + les di, [xBP + 08h] + mov [di], eax + les di, [xBP + 0ch] + mov [di], ebx + les di, [xBP + 10h] + mov [di], ecx + les di, [xBP + 14h] + mov [di], edx + + pop di + pop es +%else + %error unsupported arch +%endif + + pop xBX + leave + ret +ENDPROC ASMCpuId + diff --git a/src/VBox/Runtime/common/asm/ASMCpuIdExSlow.asm b/src/VBox/Runtime/common/asm/ASMCpuIdExSlow.asm new file mode 100644 index 00000000..04b80684 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMCpuIdExSlow.asm @@ -0,0 +1,171 @@ +; $Id: ASMCpuIdExSlow.asm $ +;; @file +; IPRT - ASMCpuIdExSlow(). +; + +; +; Copyright (C) 2012-2020 Oracle Corporation +; +; This file is part of VirtualBox Open Source Edition (OSE), as +; available from http://www.virtualbox.org. This file is free software; +; you can redistribute it and/or modify it under the terms of the GNU +; General Public License (GPL) as published by the Free Software +; Foundation, in version 2 as it comes in the "COPYING" file of the +; VirtualBox OSE distribution. VirtualBox OSE is distributed in the +; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL) only, as it comes in the "COPYING.CDDL" file of the +; VirtualBox OSE 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. +; + +;******************************************************************************* +;* Header Files * +;******************************************************************************* +%include "iprt/asmdefs.mac" + +BEGINCODE + +;; +; CPUID with EAX and ECX inputs, returning ALL output registers. +; +; @param uOperator x86:ebp+8 gcc:rdi msc:rcx +; @param uInitEBX x86:ebp+c gcc:rsi msc:rdx +; @param uInitECX x86:ebp+10 gcc:rdx msc:r8 +; @param uInitEDX x86:ebp+14 gcc:rcx msc:r9 +; @param pvEAX x86:ebp+18 gcc:r8 msc:rbp+30h +; @param pvEBX x86:ebp+1c gcc:r9 msc:rbp+38h +; @param pvECX x86:ebp+20 gcc:rbp+10h msc:rbp+40h +; @param pvEDX x86:ebp+24 gcc:rbp+18h msc:rbp+48h +; +; @returns EAX +; +BEGINPROC_EXPORTED ASMCpuIdExSlow + push xBP + mov xBP, xSP + push xBX +%if ARCH_BITS == 32 + push edi +%elif ARCH_BITS == 16 + push di + push es +%endif + +%ifdef ASM_CALL64_MSC + %if ARCH_BITS != 64 + %error ARCH_BITS mismatch? + %endif + mov eax, ecx + mov ebx, edx + mov ecx, r8d + mov edx, r9d + mov r8, [rbp + 30h] + mov r9, [rbp + 38h] + mov r10, [rbp + 40h] + mov r11, [rbp + 48h] +%elifdef ASM_CALL64_GCC + mov eax, edi + mov ebx, esi + xchg ecx, edx + mov r10, [rbp + 10h] + mov r11, [rbp + 18h] +%elif ARCH_BITS == 32 + mov eax, [xBP + 08h] + mov ebx, [xBP + 0ch] + mov ecx, [xBP + 10h] + mov edx, [xBP + 14h] + mov edi, [xBP + 18h] +%elif ARCH_BITS == 16 + mov eax, [xBP + 08h - 4] + mov ebx, [xBP + 0ch - 4] + mov ecx, [xBP + 10h - 4] + mov edx, [xBP + 14h - 4] +%else + %error unsupported arch +%endif + + cpuid + +%ifdef RT_ARCH_AMD64 + test r8, r8 + jz .store_ebx + mov [r8], eax +%elif ARCH_BITS == 32 + test edi, edi + jz .store_ebx + mov [edi], eax +%else + cmp dword [bp + 18h - 4], 0 + je .store_ebx + les di, [bp + 18h - 4] + mov [es:di], eax +%endif +.store_ebx: + +%ifdef RT_ARCH_AMD64 + test r9, r9 + jz .store_ecx + mov [r9], ebx +%elif ARCH_BITS == 32 + mov edi, [ebp + 1ch] + test edi, edi + jz .store_ecx + mov [edi], ebx +%else + cmp dword [bp + 1ch - 4], 0 + je .store_ecx + les di, [bp + 1ch - 4] + mov [es:di], ebx +%endif +.store_ecx: + +%ifdef RT_ARCH_AMD64 + test r10, r10 + jz .store_edx + mov [r10], ecx +%elif ARCH_BITS == 32 + mov edi, [ebp + 20h] + test edi, edi + jz .store_edx + mov [edi], ecx +%else + cmp dword [bp + 20h - 4], 0 + je .store_edx + les di, [bp + 20h - 4] + mov [es:di], ecx +%endif +.store_edx: + +%ifdef RT_ARCH_AMD64 + test r11, r11 + jz .done + mov [r11], edx +%elif ARCH_BITS == 32 + mov edi, [ebp + 24h] + test edi, edi + jz .done + mov [edi], edx +%else + cmp dword [bp + 24h - 4], 0 + je .done + les di, [bp + 24h - 4] + mov [es:di], edx +%endif +.done: + +%if ARCH_BITS == 32 + pop edi +%elif ARCH_BITS == 16 + pop es + pop di +%endif + pop xBX + leave + ret +ENDPROC ASMCpuIdExSlow + diff --git a/src/VBox/Runtime/common/asm/ASMCpuId_Idx_ECX.asm b/src/VBox/Runtime/common/asm/ASMCpuId_Idx_ECX.asm new file mode 100644 index 00000000..8869535f --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMCpuId_Idx_ECX.asm @@ -0,0 +1,116 @@ +; $Id: ASMCpuId_Idx_ECX.asm $ +;; @file +; IPRT - ASMCpuId_Idx_ECX(). +; + +; +; Copyright (C) 2012-2020 Oracle Corporation +; +; This file is part of VirtualBox Open Source Edition (OSE), as +; available from http://www.virtualbox.org. This file is free software; +; you can redistribute it and/or modify it under the terms of the GNU +; General Public License (GPL) as published by the Free Software +; Foundation, in version 2 as it comes in the "COPYING" file of the +; VirtualBox OSE distribution. VirtualBox OSE is distributed in the +; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL) only, as it comes in the "COPYING.CDDL" file of the +; VirtualBox OSE 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. +; + +;******************************************************************************* +;* Header Files * +;******************************************************************************* +%include "iprt/asmdefs.mac" + +BEGINCODE + +;; +; CPUID with EAX and ECX inputs, returning ALL output registers. +; +; @param uOperator x86:ebp+8 gcc:rdi msc:rcx +; @param uIdxECX x86:ebp+c gcc:rsi msc:rdx +; @param pvEAX x86:ebp+10 gcc:rdx msc:r8 +; @param pvEBX x86:ebp+14 gcc:rcx msc:r9 +; @param pvECX x86:ebp+18 gcc:r8 msc:rsp+28h +; @param pvEDX x86:ebp+1c gcc:r9 msc:rsp+30h +; +; @returns void +; +BEGINPROC_EXPORTED ASMCpuId_Idx_ECX +%ifdef RT_ARCH_AMD64 + mov r10, rbx + + %ifdef ASM_CALL64_MSC + + mov eax, ecx + mov ecx, edx + xor ebx, ebx + xor edx, edx + + cpuid + + mov [r8], eax + mov [r9], ebx + mov rax, [rsp + 28h] + mov rbx, [rsp + 30h] + mov [rax], ecx + mov [rbx], edx + + %else + mov rsi, rdx + mov r11, rcx + mov eax, edi + mov ecx, esi + xor ebx, ebx + xor edx, edx + + cpuid + + mov [rsi], eax + mov [r11], ebx + mov [r8], ecx + mov [r9], edx + + %endif + + mov rbx, r10 + ret + +%elifdef RT_ARCH_X86 + push ebp + mov ebp, esp + push ebx + push edi + + xor edx, edx + xor ebx, ebx + mov eax, [ebp + 08h] + mov ecx, [ebp + 0ch] + + cpuid + + mov edi, [ebp + 10h] + mov [edi], eax + mov edi, [ebp + 14h] + mov [edi], ebx + mov edi, [ebp + 18h] + mov [edi], ecx + mov edi, [ebp + 1ch] + mov [edi], edx + + pop edi + pop ebx + leave + ret +%else + %error unsupported arch +%endif +ENDPROC ASMCpuId_Idx_ECX + diff --git a/src/VBox/Runtime/common/asm/ASMFxRstor.asm b/src/VBox/Runtime/common/asm/ASMFxRstor.asm new file mode 100644 index 00000000..a28652a9 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMFxRstor.asm @@ -0,0 +1,64 @@ +; $Id: ASMFxRstor.asm $ +;; @file +; IPRT - ASMFxRstor(). +; + +; +; Copyright (C) 2006-2020 Oracle Corporation +; +; This file is part of VirtualBox Open Source Edition (OSE), as +; available from http://www.virtualbox.org. This file is free software; +; you can redistribute it and/or modify it under the terms of the GNU +; General Public License (GPL) as published by the Free Software +; Foundation, in version 2 as it comes in the "COPYING" file of the +; VirtualBox OSE distribution. VirtualBox OSE is distributed in the +; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL) only, as it comes in the "COPYING.CDDL" file of the +; VirtualBox OSE 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. +; + +;******************************************************************************* +;* Header Files * +;******************************************************************************* +%define RT_ASM_WITH_SEH64 +%include "iprt/asmdefs.mac" + +BEGINCODE + +;; +; Loads extended CPU state. +; @param pFxState Pointer to the FXRSTOR state area. +; msc=rcx, gcc=rdi, x86=[esp+4] +; +BEGINPROC_EXPORTED ASMFxRstor +SEH64_END_PROLOGUE +%ifdef ASM_CALL64_MSC + o64 fxrstor [rcx] +%elifdef ASM_CALL64_GCC + o64 fxrstor [rdi] +%elif ARCH_BITS == 32 + mov ecx, [esp + 4] + fxrstor [ecx] +%elif ARCH_BITS == 16 + push bp + mov bp, sp + push es + push bx + les bx, [bp + 4] + fxrstor [es:bx] + pop bx + pop es + pop bp +%else + %error "Undefined arch?" +%endif + ret +ENDPROC ASMFxRstor + diff --git a/src/VBox/Runtime/common/asm/ASMFxSave.asm b/src/VBox/Runtime/common/asm/ASMFxSave.asm new file mode 100644 index 00000000..3c86a455 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMFxSave.asm @@ -0,0 +1,64 @@ +; $Id: ASMFxSave.asm $ +;; @file +; IPRT - ASMFxSave(). +; + +; +; Copyright (C) 2006-2020 Oracle Corporation +; +; This file is part of VirtualBox Open Source Edition (OSE), as +; available from http://www.virtualbox.org. This file is free software; +; you can redistribute it and/or modify it under the terms of the GNU +; General Public License (GPL) as published by the Free Software +; Foundation, in version 2 as it comes in the "COPYING" file of the +; VirtualBox OSE distribution. VirtualBox OSE is distributed in the +; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL) only, as it comes in the "COPYING.CDDL" file of the +; VirtualBox OSE 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. +; + +;******************************************************************************* +;* Header Files * +;******************************************************************************* +%define RT_ASM_WITH_SEH64 +%include "iprt/asmdefs.mac" + +BEGINCODE + +;; +; Saves extended CPU state. +; @param pFxState Pointer to the XSAVE state area. +; msc=rcx, gcc=rdi, x86=[esp+4] +; +BEGINPROC_EXPORTED ASMFxSave +SEH64_END_PROLOGUE +%ifdef ASM_CALL64_MSC + o64 fxsave [rcx] +%elifdef ASM_CALL64_GCC + o64 fxsave [rdi] +%elif ARCH_BITS == 32 + mov ecx, [esp + 4] + fxsave [ecx] +%elif ARCH_BITS == 16 + push bp + mov bp, sp + push es + push bx + les bx, [bp + 4] + fxsave [es:bx] + pop bx + pop es + pop bp +%else + %error "Undefined arch?" +%endif + ret +ENDPROC ASMFxSave + diff --git a/src/VBox/Runtime/common/asm/ASMGetFlags.asm b/src/VBox/Runtime/common/asm/ASMGetFlags.asm new file mode 100644 index 00000000..efa26e73 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMGetFlags.asm @@ -0,0 +1,43 @@ +; $Id: ASMGetFlags.asm $ +;; @file +; IPRT - ASMGetFlags(). +; + +; +; Copyright (C) 2006-2020 Oracle Corporation +; +; This file is part of VirtualBox Open Source Edition (OSE), as +; available from http://www.virtualbox.org. This file is free software; +; you can redistribute it and/or modify it under the terms of the GNU +; General Public License (GPL) as published by the Free Software +; Foundation, in version 2 as it comes in the "COPYING" file of the +; VirtualBox OSE distribution. VirtualBox OSE is distributed in the +; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL) only, as it comes in the "COPYING.CDDL" file of the +; VirtualBox OSE 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. +; + +;******************************************************************************* +;* Header Files * +;******************************************************************************* +%include "iprt/asmdefs.mac" + +BEGINCODE + +BEGINPROC_EXPORTED ASMGetFlags +%if ARCH_BITS == 32 + pushfd +%else + pushf +%endif + pop xAX + ret +ENDPROC ASMGetFlags + diff --git a/src/VBox/Runtime/common/asm/ASMGetGDTR.asm b/src/VBox/Runtime/common/asm/ASMGetGDTR.asm new file mode 100644 index 00000000..b8248e41 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMGetGDTR.asm @@ -0,0 +1,52 @@ +; $Id: ASMGetGDTR.asm $ +;; @file +; IPRT - ASMGetGDTR(). +; + +; +; Copyright (C) 2006-2020 Oracle Corporation +; +; This file is part of VirtualBox Open Source Edition (OSE), as +; available from http://www.virtualbox.org. This file is free software; +; you can redistribute it and/or modify it under the terms of the GNU +; General Public License (GPL) as published by the Free Software +; Foundation, in version 2 as it comes in the "COPYING" file of the +; VirtualBox OSE distribution. VirtualBox OSE is distributed in the +; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL) only, as it comes in the "COPYING.CDDL" file of the +; VirtualBox OSE 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. +; + +;******************************************************************************* +;* Header Files * +;******************************************************************************* +%include "iprt/asmdefs.mac" + +BEGINCODE + +;; +; Gets the content of the GDTR CPU register. +; @param pGdtr Where to store the GDTR contents. +; msc=rcx, gcc=rdi, x86=[esp+4] +; +BEGINPROC_EXPORTED ASMGetGDTR +%ifdef ASM_CALL64_MSC + mov rax, rcx +%elifdef ASM_CALL64_GCC + mov rax, rdi +%elifdef RT_ARCH_X86 + mov eax, [esp + 4] +%else + %error "Undefined arch?" +%endif + sgdt [xAX] + ret +ENDPROC ASMGetGDTR + diff --git a/src/VBox/Runtime/common/asm/ASMGetIDTR.asm b/src/VBox/Runtime/common/asm/ASMGetIDTR.asm new file mode 100644 index 00000000..6193a194 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMGetIDTR.asm @@ -0,0 +1,52 @@ +; $Id: ASMGetIDTR.asm $ +;; @file +; IPRT - ASMGetIDTR(). +; + +; +; Copyright (C) 2006-2020 Oracle Corporation +; +; This file is part of VirtualBox Open Source Edition (OSE), as +; available from http://www.virtualbox.org. This file is free software; +; you can redistribute it and/or modify it under the terms of the GNU +; General Public License (GPL) as published by the Free Software +; Foundation, in version 2 as it comes in the "COPYING" file of the +; VirtualBox OSE distribution. VirtualBox OSE is distributed in the +; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL) only, as it comes in the "COPYING.CDDL" file of the +; VirtualBox OSE 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. +; + +;******************************************************************************* +;* Header Files * +;******************************************************************************* +%include "iprt/asmdefs.mac" + +BEGINCODE + +;; +; Gets the content of the IDTR CPU register. +; @param pIdtr Where to store the IDTR contents. +; msc=rcx, gcc=rdi, x86=[esp+4] +; +BEGINPROC_EXPORTED ASMGetIDTR +%ifdef ASM_CALL64_MSC + mov rax, rcx +%elifdef ASM_CALL64_GCC + mov rax, rdi +%elifdef RT_ARCH_X86 + mov eax, [esp + 4] +%else + %error "Undefined arch?" +%endif + sidt [xAX] + ret +ENDPROC ASMGetIDTR + diff --git a/src/VBox/Runtime/common/asm/ASMGetIdtrLimit.asm b/src/VBox/Runtime/common/asm/ASMGetIdtrLimit.asm new file mode 100644 index 00000000..ec8a733f --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMGetIdtrLimit.asm @@ -0,0 +1,48 @@ +; $Id: ASMGetIdtrLimit.asm $ +;; @file +; IPRT - ASMGetIdtrLimit(). +; + +; +; Copyright (C) 2006-2020 Oracle Corporation +; +; This file is part of VirtualBox Open Source Edition (OSE), as +; available from http://www.virtualbox.org. This file is free software; +; you can redistribute it and/or modify it under the terms of the GNU +; General Public License (GPL) as published by the Free Software +; Foundation, in version 2 as it comes in the "COPYING" file of the +; VirtualBox OSE distribution. VirtualBox OSE is distributed in the +; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL) only, as it comes in the "COPYING.CDDL" file of the +; VirtualBox OSE 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. +; + +;******************************************************************************* +;* Header Files * +;******************************************************************************* +%define RT_ASM_WITH_SEH64 +%include "iprt/asmdefs.mac" + +BEGINCODE + +;; +; Gets the content of the IDTR CPU register. +; @returns IDTR.LIMIT in ax +; +BEGINPROC_EXPORTED ASMGetIdtrLimit + sub xSP, 18h + SEH64_ALLOCATE_STACK 18h +SEH64_END_PROLOGUE + sidt [xSP + 6] + mov ax, [xSP + 6] + add xSP, 18h + ret +ENDPROC ASMGetIdtrLimit + diff --git a/src/VBox/Runtime/common/asm/ASMGetLDTR.asm b/src/VBox/Runtime/common/asm/ASMGetLDTR.asm new file mode 100644 index 00000000..86ff3509 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMGetLDTR.asm @@ -0,0 +1,43 @@ +; $Id: ASMGetLDTR.asm $ +;; @file +; IPRT - ASMGetLDTR(). +; + +; +; Copyright (C) 2006-2020 Oracle Corporation +; +; This file is part of VirtualBox Open Source Edition (OSE), as +; available from http://www.virtualbox.org. This file is free software; +; you can redistribute it and/or modify it under the terms of the GNU +; General Public License (GPL) as published by the Free Software +; Foundation, in version 2 as it comes in the "COPYING" file of the +; VirtualBox OSE distribution. VirtualBox OSE is distributed in the +; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL) only, as it comes in the "COPYING.CDDL" file of the +; VirtualBox OSE 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. +; + +;******************************************************************************* +;* Header Files * +;******************************************************************************* +%include "iprt/asmdefs.mac" + +BEGINCODE + +;; +; Get the LDTR register. +; @returns LDTR. +; +BEGINPROC_EXPORTED ASMGetLDTR + sldt ax + movzx eax, ax + ret +ENDPROC ASMGetLDTR + diff --git a/src/VBox/Runtime/common/asm/ASMGetSegAttr.asm b/src/VBox/Runtime/common/asm/ASMGetSegAttr.asm new file mode 100644 index 00000000..762fc147 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMGetSegAttr.asm @@ -0,0 +1,61 @@ +; $Id: ASMGetSegAttr.asm $ +;; @file +; IPRT - ASMGetSegAttr(). +; + +; +; Copyright (C) 2013-2020 Oracle Corporation +; +; This file is part of VirtualBox Open Source Edition (OSE), as +; available from http://www.virtualbox.org. This file is free software; +; you can redistribute it and/or modify it under the terms of the GNU +; General Public License (GPL) as published by the Free Software +; Foundation, in version 2 as it comes in the "COPYING" file of the +; VirtualBox OSE distribution. VirtualBox OSE is distributed in the +; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL) only, as it comes in the "COPYING.CDDL" file of the +; VirtualBox OSE 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. +; + +;******************************************************************************* +;* Header Files * +;******************************************************************************* +%include "iprt/asmdefs.mac" + +BEGINCODE + +;; +; Get the segment attributes for a selector. +; +; @param uSel x86: [ebp + 08h] msc: ecx gcc: edi The selector value. +; @returns Segment attributes on success or ~0U on failure. +; +; @remarks Using ~0U for failure is chosen because valid access rights always +; have bits 0:7 as 0 (on both Intel & AMD). +; +BEGINPROC_EXPORTED ASMGetSegAttr +%ifdef ASM_CALL64_MSC + and ecx, 0ffffh + lar eax, ecx +%elifdef ASM_CALL64_GCC + and edi, 0ffffh + lar eax, edi +%elifdef RT_ARCH_X86 + movzx edx, word [esp + 4] + lar eax, edx +%else + %error "Which arch is this?" +%endif + jz .return + mov eax, 0ffffffffh +.return: + ret +ENDPROC ASMGetSegAttr + diff --git a/src/VBox/Runtime/common/asm/ASMGetTR.asm b/src/VBox/Runtime/common/asm/ASMGetTR.asm new file mode 100644 index 00000000..ecc839b5 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMGetTR.asm @@ -0,0 +1,43 @@ +; $Id: ASMGetTR.asm $ +;; @file +; IPRT - ASMGetTR(). +; + +; +; Copyright (C) 2006-2020 Oracle Corporation +; +; This file is part of VirtualBox Open Source Edition (OSE), as +; available from http://www.virtualbox.org. This file is free software; +; you can redistribute it and/or modify it under the terms of the GNU +; General Public License (GPL) as published by the Free Software +; Foundation, in version 2 as it comes in the "COPYING" file of the +; VirtualBox OSE distribution. VirtualBox OSE is distributed in the +; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL) only, as it comes in the "COPYING.CDDL" file of the +; VirtualBox OSE 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. +; + +;******************************************************************************* +;* Header Files * +;******************************************************************************* +%include "iprt/asmdefs.mac" + +BEGINCODE + +;; +; Get the TR register. +; @returns TR. +; +BEGINPROC_EXPORTED ASMGetTR + str ax + movzx eax, ax + ret +ENDPROC ASMGetTR + diff --git a/src/VBox/Runtime/common/asm/ASMGetXcr0.asm b/src/VBox/Runtime/common/asm/ASMGetXcr0.asm new file mode 100644 index 00000000..326bc826 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMGetXcr0.asm @@ -0,0 +1,56 @@ +; $Id: ASMGetXcr0.asm $ +;; @file +; IPRT - ASMGetXcr0(). +; + +; +; Copyright (C) 2006-2020 Oracle Corporation +; +; This file is part of VirtualBox Open Source Edition (OSE), as +; available from http://www.virtualbox.org. This file is free software; +; you can redistribute it and/or modify it under the terms of the GNU +; General Public License (GPL) as published by the Free Software +; Foundation, in version 2 as it comes in the "COPYING" file of the +; VirtualBox OSE distribution. VirtualBox OSE is distributed in the +; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL) only, as it comes in the "COPYING.CDDL" file of the +; VirtualBox OSE 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. +; + +;******************************************************************************* +;* Header Files * +;******************************************************************************* +%define RT_ASM_WITH_SEH64 +%include "iprt/asmdefs.mac" + +BEGINCODE + +;; +; Gets the content of the XCR0 CPU register. +; @returns XCR0 value in rax (amd64) / edx:eax (x86). +; +BEGINPROC_EXPORTED ASMGetXcr0 +SEH64_END_PROLOGUE + xor ecx, ecx ; XCR0 + xgetbv +%ifdef RT_ARCH_AMD64 + shl rdx, 32 + or rax, rdx +%endif +%if ARCH_BITS == 16 ; DX:CX:BX:AX - DX=15:0, CX=31:16, BX=47:32, AX=63:48 + mov ebx, edx + mov ecx, eax + shr ecx, 16 + xchg eax, edx + shr eax, 16 +%endif + ret +ENDPROC ASMGetXcr0 + diff --git a/src/VBox/Runtime/common/asm/ASMMemFirstMismatchingU8.asm b/src/VBox/Runtime/common/asm/ASMMemFirstMismatchingU8.asm new file mode 100644 index 00000000..2a8e560f --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMMemFirstMismatchingU8.asm @@ -0,0 +1,345 @@ +; $Id: ASMMemFirstMismatchingU8.asm $ +;; @file +; IPRT - ASMMemFirstMismatchingU8(). +; + +; +; Copyright (C) 2006-2020 Oracle Corporation +; +; This file is part of VirtualBox Open Source Edition (OSE), as +; available from http://www.virtualbox.org. This file is free software; +; you can redistribute it and/or modify it under the terms of the GNU +; General Public License (GPL) as published by the Free Software +; Foundation, in version 2 as it comes in the "COPYING" file of the +; VirtualBox OSE distribution. VirtualBox OSE is distributed in the +; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL) only, as it comes in the "COPYING.CDDL" file of the +; VirtualBox OSE 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. +; + + +;******************************************************************************* +;* Header Files * +;******************************************************************************* +%define RT_ASM_WITH_SEH64 +%include "iprt/asmdefs.mac" + + +BEGINCODE + +;; +; Variant of ASMMemFirstMismatchingU8 with a fixed @a u8 value. +; We repeat the prolog and join the generic function. +; +BEGINPROC_EXPORTED ASMMemFirstNonZero + ; + ; Prologue. + ; +%if ARCH_BITS != 64 + push xBP + mov xBP, xSP + push xDI + %if ARCH_BITS == 16 + push es + %endif +%elifdef ASM_CALL64_MSC + mov r9, rdi ; save rdi in r9 +%endif +SEH64_END_PROLOGUE + + ; + ; Normalize input; rdi=pv, rcx=cb, rax=0 + ; + %if ARCH_BITS == 64 + %ifdef ASM_CALL64_MSC + mov rdi, rcx + mov rcx, rdx + jrcxz RT_CONCAT(NAME(ASMMemFirstMismatchingU8),.return_all_same) + xor eax, eax + %else + mov rcx, rsi + jrcxz RT_CONCAT(NAME(ASMMemFirstMismatchingU8),.return_all_same) + xor eax, eax + %endif + + %elif ARCH_BITS == 32 + mov ecx, [ebp + 0ch] + jecxz RT_CONCAT(NAME(ASMMemFirstMismatchingU8),.return_all_same) + mov edi, [ebp + 08h] + xor eax, eax + + %elif ARCH_BITS == 16 + mov cx, [bp + 08h] ; cb + jcxz RT_CONCAT(NAME(ASMMemFirstMismatchingU8),.return16_all_same) + les di, [bp + 04h] ; pv (far) + xor ax, ax + + %else + %error "Invalid ARCH_BITS value" + %endif + + ; + ; Join ASMMemFirstMismatchingU8 + ; + jmp RT_CONCAT(NAME(ASMMemFirstMismatchingU8),.is_all_zero_joining) +ENDPROC ASMMemFirstNonZero + + +;; +; Inverted memchr. +; +; @returns Pointer to the byte which doesn't equal u8. +; @returns NULL if all equal to u8. +; +; @param msc:rcx gcc:rdi pv Pointer to the memory block. +; @param msc:rdx gcc:rsi cb Number of bytes in the block. This MUST be aligned on 32-bit! +; @param msc:r8b gcc:dl u8 The value it's supposed to be filled with. +; +; @cproto DECLINLINE(void *) ASMMemFirstMismatchingU8(void const *pv, size_t cb, uint8_t u8) +; +BEGINPROC_EXPORTED ASMMemFirstMismatchingU8 + ; + ; Prologue. + ; +%if ARCH_BITS != 64 + push xBP + mov xBP, xSP + push xDI + %if ARCH_BITS == 16 + push es + %endif +%elifdef ASM_CALL64_MSC + mov r9, rdi ; save rdi in r9 +%endif +SEH64_END_PROLOGUE + +%if ARCH_BITS != 16 + ; + ; The 32-bit and 64-bit variant of the code. + ; + + ; Normalize input; rdi=pv, rcx=cb, rax=eight-times-u8 + %if ARCH_BITS == 64 + %ifdef ASM_CALL64_MSC + mov rdi, rcx + mov rcx, rdx + jrcxz .return_all_same + movzx r8d, r8b + mov rax, qword 0101010101010101h + imul rax, r8 + %else + mov rcx, rsi + jrcxz .return_all_same + movzx edx, dl + mov rax, qword 0101010101010101h + imul rax, rdx + %endif + + %elif ARCH_BITS == 32 + mov ecx, [ebp + 0ch] + jecxz .return_all_same + mov edi, [ebp + 08h] + movzx eax, byte [ebp + 10h] + mov ah, al + movzx edx, ax + shl eax, 16 + or eax, edx + %else + %error "Invalid ARCH_BITS value" + %endif + +.is_all_zero_joining: + cld + + ; Unaligned pointer? Align it (elsewhere). + test edi, xCB - 1 + jnz .unaligned_pv +.aligned_pv: + + ; Do the dword/qword scan. + mov edx, xCB - 1 + and edx, ecx ; Remaining bytes for tail scan + %if ARCH_BITS == 64 + shr xCX, 3 + repe scasq + %else + shr xCX, 2 + repe scasd + %endif + jne .multibyte_mismatch + + ; Prep for tail scan. + mov ecx, edx + + ; + ; Byte by byte scan. + ; +.byte_by_byte: + repe scasb + jne .return_xDI + +.return_all_same: + xor eax, eax + %ifdef ASM_CALL64_MSC + mov rdi, r9 ; restore rdi + %elif ARCH_BITS == 32 + pop edi + leave + %endif + ret + + ; Return after byte scan mismatch. +.return_xDI: + lea xAX, [xDI - 1] + %ifdef ASM_CALL64_MSC + mov rdi, r9 ; restore rdi + %elif ARCH_BITS == 32 + pop edi + leave + %endif + ret + + ; + ; Multibyte mismatch. We rewind and do a byte scan of the remainder. + ; (can't just search the qword as the buffer must be considered volatile). + ; +.multibyte_mismatch: + lea xDI, [xDI - xCB] + lea xCX, [xCX * xCB + xCB] + or ecx, edx + jmp .byte_by_byte + + ; + ; Unaligned pointer. If it's worth it, align the pointer, but if the + ; memory block is too small do the byte scan variant. + ; +.unaligned_pv: + cmp xCX, 4*xCB ; 4 steps seems reasonable. + jbe .byte_by_byte + + ; Unrolled buffer realignment. + %if ARCH_BITS == 64 + dec xCX + scasb + jne .return_xDI + test edi, xCB - 1 + jz .aligned_pv + + dec xCX + scasb + jne .return_xDI + test edi, xCB - 1 + jz .aligned_pv + + dec xCX + scasb + jne .return_xDI + test edi, xCB - 1 + jz .aligned_pv + + dec xCX + scasb + jne .return_xDI + test edi, xCB - 1 + jz .aligned_pv + %endif + + dec xCX + scasb + jne .return_xDI + test edi, xCB - 1 + jz .aligned_pv + + dec xCX + scasb + jne .return_xDI + test edi, xCB - 1 + jz .aligned_pv + + dec xCX + scasb + jne .return_xDI + jmp .aligned_pv + + +%else ; ARCH_BITS == 16 + + ; + ; The 16-bit variant of the code is a little simpler since we're + ; working with two byte words in the 'fast' scan. We also keep + ; this separate from the 32-bit/64-bit code because that allows + ; avoid a few rex prefixes here and there by using extended + ; registers (e??) where we don't care about the whole register. + ; +CPU 8086 + + ; Load input parameters. + mov cx, [bp + 08h] ; cb + jcxz .return16_all_same + les di, [bp + 04h] ; pv (far) + mov al, [bp + 0ah] ; u8 + mov ah, al + +.is_all_zero_joining: + cld + + ; Align the pointer. + test di, 1 + jz .word_scan + + dec cx + scasb + jne .return16_di + jcxz .return16_all_same + + ; Scan word-by-word. +.word_scan: + mov dx, cx + shr cx, 1 + repe scasw + jne .word_mismatch + + ; do we have a tail byte? + test dl, 1 + jz .return16_all_same + scasb + jne .return16_di + +.return16_all_same: + xor ax, ax + xor dx, dx +.return16: + pop es + pop di + pop bp + ret + +.word_mismatch: + ; back up a word. + inc cx + sub di, 2 + + ; Do byte-by-byte scanning of the rest of the buffer. + shl cx, 1 + mov dl, 1 + and dl, [bp + 08h] ; cb + or cl, dl + repe scasb + je .return16_all_same + +.return16_di: + mov ax, di + dec ax + mov dx, es + jmp .return16 + +%endif ; ARCH_BITS == 16 +ENDPROC ASMMemFirstMismatchingU8 + diff --git a/src/VBox/Runtime/common/asm/ASMMultU32ByU32DivByU32.asm b/src/VBox/Runtime/common/asm/ASMMultU32ByU32DivByU32.asm new file mode 100644 index 00000000..c87b88c8 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMMultU32ByU32DivByU32.asm @@ -0,0 +1,64 @@ +; $Id: ASMMultU32ByU32DivByU32.asm $ +;; @file +; IPRT - Assembly Functions, ASMMultU32ByU32DivByU32. +; + +; +; Copyright (C) 2006-2020 Oracle Corporation +; +; This file is part of VirtualBox Open Source Edition (OSE), as +; available from http://www.virtualbox.org. This file is free software; +; you can redistribute it and/or modify it under the terms of the GNU +; General Public License (GPL) as published by the Free Software +; Foundation, in version 2 as it comes in the "COPYING" file of the +; VirtualBox OSE distribution. VirtualBox OSE is distributed in the +; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL) only, as it comes in the "COPYING.CDDL" file of the +; VirtualBox OSE 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. +; + +%include "iprt/asmdefs.mac" + + +;; +; Multiple a 32-bit by a 32-bit integer and divide the result by a 32-bit integer +; using a 64 bit intermediate result. +; +; @returns (u32A * u32B) / u32C. +; @param u32A/ecx/edi The 32-bit value (A). +; @param u32B/edx/esi The 32-bit value to multiple by A. +; @param u32C/r8d/edx The 32-bit value to divide A*B by. +; +; @cproto DECLASM(uint32_t) ASMMultU32ByU32DivByU32(uint32_t u32A, uint32_t u32B, uint32_t u32C); +; +BEGINPROC_EXPORTED ASMMultU32ByU32DivByU32 +%ifdef RT_ARCH_AMD64 + %ifdef ASM_CALL64_MSC + mov eax, ecx + mul edx + div r8d + %else + mov eax, edi + mov ecx, edx + mul esi + div ecx + %endif + +%elifdef RT_ARCH_X86 + mov eax, [esp + 04h] + mul dword [esp + 08h] + div dword [esp + 0ch] +%else + %error "Unsupported arch." + unsupported arch +%endif + + ret +ENDPROC ASMMultU32ByU32DivByU32 diff --git a/src/VBox/Runtime/common/asm/ASMMultU64ByU32DivByU32.asm b/src/VBox/Runtime/common/asm/ASMMultU64ByU32DivByU32.asm new file mode 100644 index 00000000..46a69930 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMMultU64ByU32DivByU32.asm @@ -0,0 +1,102 @@ +; $Id: ASMMultU64ByU32DivByU32.asm $ +;; @file +; IPRT - Assembly Functions, ASMMultU64ByU32DivByU32. +; + +; +; Copyright (C) 2006-2020 Oracle Corporation +; +; This file is part of VirtualBox Open Source Edition (OSE), as +; available from http://www.virtualbox.org. This file is free software; +; you can redistribute it and/or modify it under the terms of the GNU +; General Public License (GPL) as published by the Free Software +; Foundation, in version 2 as it comes in the "COPYING" file of the +; VirtualBox OSE distribution. VirtualBox OSE is distributed in the +; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL) only, as it comes in the "COPYING.CDDL" file of the +; VirtualBox OSE 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. +; + +%include "iprt/asmdefs.mac" + + +;; +; Multiple a 64-bit by a 32-bit integer and divide the result by a 32-bit integer +; using a 96 bit intermediate result. +; +; @returns (u64A * u32B) / u32C. +; @param u64A/rcx/rdi The 64-bit value. +; @param u32B/edx/esi The 32-bit value to multiple by A. +; @param u32C/r8d/edx The 32-bit value to divide A*B by. +; +; @cproto DECLASM(uint64_t) ASMMultU64ByU32DivByU32(uint64_t u64A, uint32_t u32B, uint32_t u32C); +; +BEGINPROC_EXPORTED ASMMultU64ByU32DivByU32 +%ifdef RT_ARCH_AMD64 + + %ifdef ASM_CALL64_MSC + mov rax, rcx ; rax = u64A + mov r9d, edx ; should check the specs wrt to the high bits one day... + mov r8d, r8d ; be paranoid for the time being. + %else + mov rax, rdi ; rax = u64A + mov r9d, esi ; r9d = u32B + mov r8d, edx ; r8d = u32C + %endif + mul r9 + div r8 + +%else ; X86 + ; + ; This implementation is converted from the GCC inline + ; version of the code. Nothing additional has been done + ; performance wise. + ; + push esi + push edi + +%define u64A_Lo [esp + 04h + 08h] +%define u64A_Hi [esp + 08h + 08h] +%define u32B [esp + 0ch + 08h] +%define u32C [esp + 10h + 08h] + + ; Load parameters into registers. + mov eax, u64A_Lo + mov esi, u64A_Hi + mov ecx, u32B + mov edi, u32C + + ; The body, just like the in + mul ecx ; eax = u64Lo.lo = (u64A.lo * u32B).lo + ; edx = u64Lo.hi = (u64A.lo * u32B).hi + xchg eax, esi ; esi = u64Lo.lo + ; eax = u64A.hi + xchg edx, edi ; edi = u64Low.hi + ; edx = u32C + xchg edx, ecx ; ecx = u32C + ; edx = u32B + mul edx ; eax = u64Hi.lo = (u64A.hi * u32B).lo + ; edx = u64Hi.hi = (u64A.hi * u32B).hi + add eax, edi ; u64Hi.lo += u64Lo.hi + adc edx, 0 ; u64Hi.hi += carry + div ecx ; eax = u64Hi / u32C + ; edx = u64Hi % u32C + mov edi, eax ; edi = u64Result.hi = u64Hi / u32C + mov eax, esi ; eax = u64Lo.lo + div ecx ; u64Result.lo + mov edx, edi ; u64Result.hi + + ; epilogue + pop edi + pop esi +%endif + ret +ENDPROC ASMMultU64ByU32DivByU32 + diff --git a/src/VBox/Runtime/common/asm/ASMNopPause.asm b/src/VBox/Runtime/common/asm/ASMNopPause.asm new file mode 100644 index 00000000..8afab68b --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMNopPause.asm @@ -0,0 +1,41 @@ +; $Id: ASMNopPause.asm $ +;; @file +; IPRT - ASMNopPause(). +; + +; +; Copyright (C) 2009-2020 Oracle Corporation +; +; This file is part of VirtualBox Open Source Edition (OSE), as +; available from http://www.virtualbox.org. This file is free software; +; you can redistribute it and/or modify it under the terms of the GNU +; General Public License (GPL) as published by the Free Software +; Foundation, in version 2 as it comes in the "COPYING" file of the +; VirtualBox OSE distribution. VirtualBox OSE is distributed in the +; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL) only, as it comes in the "COPYING.CDDL" file of the +; VirtualBox OSE 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. +; + +;******************************************************************************* +;* Header Files * +;******************************************************************************* +%include "iprt/asmdefs.mac" + +BEGINCODE + +;; +; The PAUSE variant of NOP for helping hyperthreaded CPUs detecting spin locks. +; +BEGINPROC_EXPORTED ASMNopPause + pause + ret +ENDPROC ASMNopPause + diff --git a/src/VBox/Runtime/common/asm/ASMRdMsrEx.asm b/src/VBox/Runtime/common/asm/ASMRdMsrEx.asm new file mode 100644 index 00000000..03c80347 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMRdMsrEx.asm @@ -0,0 +1,84 @@ +; $Id: ASMRdMsrEx.asm $ +;; @file +; IPRT - ASMRdMsrEx(). +; + +; +; Copyright (C) 2013-2020 Oracle Corporation +; +; This file is part of VirtualBox Open Source Edition (OSE), as +; available from http://www.virtualbox.org. This file is free software; +; you can redistribute it and/or modify it under the terms of the GNU +; General Public License (GPL) as published by the Free Software +; Foundation, in version 2 as it comes in the "COPYING" file of the +; VirtualBox OSE distribution. VirtualBox OSE is distributed in the +; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL) only, as it comes in the "COPYING.CDDL" file of the +; VirtualBox OSE 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. +; + +;******************************************************************************* +;* Header Files * +;******************************************************************************* +%include "iprt/asmdefs.mac" + +BEGINCODE + +;; +; Special version of ASMRdMsr that allow specifying the rdi value. +; +; @param uMsr msc=rcx, gcc=rdi, x86=[ebp+8] The MSR to read. +; @param uEdi msc=rdx, gcc=rsi, x86=[ebp+12] The EDI/RDI value. +; @returns MSR value in rax on amd64 and edx:eax on x86. +; +BEGINPROC_EXPORTED ASMRdMsrEx +%ifdef ASM_CALL64_MSC +proc_frame ASMRdMsrEx_DupWarningHack + push rdi + [pushreg rdi] +[endprolog] + and ecx, ecx ; serious paranoia + mov rdi, rdx + xor eax, eax + xor edx, edx + rdmsr + pop rdi + and eax, eax ; paranoia + shl rdx, 32 + or rax, rdx + ret +endproc_frame +%elifdef ASM_CALL64_GCC + mov ecx, edi + mov rdi, rsi + xor eax, eax + xor edx, edx + rdmsr + and eax, eax ; paranoia + shl rdx, 32 + or rax, rdx + ret +%elifdef RT_ARCH_X86 + push ebp + mov ebp, esp + push edi + xor eax, eax + xor edx, edx + mov ecx, [ebp + 8] + mov edi, [esp + 12] + rdmsr + pop edi + leave + ret +%else + %error "Undefined arch?" +%endif +ENDPROC ASMRdMsrEx + diff --git a/src/VBox/Runtime/common/asm/ASMSerializeInstruction-cpuid.asm b/src/VBox/Runtime/common/asm/ASMSerializeInstruction-cpuid.asm new file mode 100644 index 00000000..7c94e93c --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMSerializeInstruction-cpuid.asm @@ -0,0 +1,49 @@ +; $Id: ASMSerializeInstruction-cpuid.asm $ +;; @file +; IPRT - ASMSerializeInstruction() using cpuid. +; + +; +; Copyright (C) 2006-2020 Oracle Corporation +; +; This file is part of VirtualBox Open Source Edition (OSE), as +; available from http://www.virtualbox.org. This file is free software; +; you can redistribute it and/or modify it under the terms of the GNU +; General Public License (GPL) as published by the Free Software +; Foundation, in version 2 as it comes in the "COPYING" file of the +; VirtualBox OSE distribution. VirtualBox OSE is distributed in the +; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL) only, as it comes in the "COPYING.CDDL" file of the +; VirtualBox OSE 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. +; + + +;******************************************************************************* +;* Header Files * +;******************************************************************************* +%include "iprt/asmdefs.mac" + +BEGINCODE + + +;; +; Executes a seralizing instruction. +; +; The CPUID instruction isn't fast or slow, but it always triggers a VM EXIT in +; a virtualized environment, which is prohibitively expensive. +; +BEGINPROC_EXPORTED ASMSerializeInstructionCpuId + push xBX + xor eax, eax + cpuid + pop xBX + ret +ENDPROC ASMSerializeInstructionCpuId + diff --git a/src/VBox/Runtime/common/asm/ASMSerializeInstruction-iret.asm b/src/VBox/Runtime/common/asm/ASMSerializeInstruction-iret.asm new file mode 100644 index 00000000..b14a7d3b --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMSerializeInstruction-iret.asm @@ -0,0 +1,61 @@ +; $Id: ASMSerializeInstruction-iret.asm $ +;; @file +; IPRT - ASMSerializeInstruction() using iret. +; + +; +; Copyright (C) 2006-2020 Oracle Corporation +; +; This file is part of VirtualBox Open Source Edition (OSE), as +; available from http://www.virtualbox.org. This file is free software; +; you can redistribute it and/or modify it under the terms of the GNU +; General Public License (GPL) as published by the Free Software +; Foundation, in version 2 as it comes in the "COPYING" file of the +; VirtualBox OSE distribution. VirtualBox OSE is distributed in the +; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL) only, as it comes in the "COPYING.CDDL" file of the +; VirtualBox OSE 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. +; + + +;******************************************************************************* +;* Header Files * +;******************************************************************************* +%include "iprt/asmdefs.mac" + +BEGINCODE + + +;; +; Executes a seralizing instruction. +; +; The IRET instruction is rather expensive, but unlike the CPUID instruction it +; will not result in a VM EXIT when running in a virtual machine. +; +BEGINPROC_EXPORTED ASMSerializeInstructionIRet + pop xAX +%ifdef RT_ARCH_AMD64 + mov rdx, xSP + mov ecx, ss + push rcx + push rdx + pushfq + mov ecx, cs + push rcx + push rax + iretq +%elifdef RT_ARCH_X86 + pushf + push cs + push xAX + iret +%endif +ENDPROC ASMSerializeInstructionIRet + diff --git a/src/VBox/Runtime/common/asm/ASMSerializeInstruction-rdtscp.asm b/src/VBox/Runtime/common/asm/ASMSerializeInstruction-rdtscp.asm new file mode 100644 index 00000000..9ba3b106 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMSerializeInstruction-rdtscp.asm @@ -0,0 +1,46 @@ +; $Id: ASMSerializeInstruction-rdtscp.asm $ +;; @file +; IPRT - ASMSerializeInstruction() using rdtscp. +; + +; +; Copyright (C) 2006-2020 Oracle Corporation +; +; This file is part of VirtualBox Open Source Edition (OSE), as +; available from http://www.virtualbox.org. This file is free software; +; you can redistribute it and/or modify it under the terms of the GNU +; General Public License (GPL) as published by the Free Software +; Foundation, in version 2 as it comes in the "COPYING" file of the +; VirtualBox OSE distribution. VirtualBox OSE is distributed in the +; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL) only, as it comes in the "COPYING.CDDL" file of the +; VirtualBox OSE 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. +; + + +;******************************************************************************* +;* Header Files * +;******************************************************************************* +%include "iprt/asmdefs.mac" + +BEGINCODE + + +;; +; Executes a seralizing instruction. +; +; The RDTSCP instruction is fast, though it may trigger a VM EXIT if the VMM +; is intercepting TSC reads for some timing reason or in general. +; +BEGINPROC_EXPORTED ASMSerializeInstructionRdTscp + rdtscp + ret +ENDPROC ASMSerializeInstructionRdTscp + diff --git a/src/VBox/Runtime/common/asm/ASMSetFlags.asm b/src/VBox/Runtime/common/asm/ASMSetFlags.asm new file mode 100644 index 00000000..c364e48d --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMSetFlags.asm @@ -0,0 +1,59 @@ +; $Id: ASMSetFlags.asm $ +;; @file +; IPRT - ASMSetFlags(). +; + +; +; Copyright (C) 2006-2020 Oracle Corporation +; +; This file is part of VirtualBox Open Source Edition (OSE), as +; available from http://www.virtualbox.org. This file is free software; +; you can redistribute it and/or modify it under the terms of the GNU +; General Public License (GPL) as published by the Free Software +; Foundation, in version 2 as it comes in the "COPYING" file of the +; VirtualBox OSE distribution. VirtualBox OSE is distributed in the +; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL) only, as it comes in the "COPYING.CDDL" file of the +; VirtualBox OSE 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. +; + + +;******************************************************************************* +;* Header Files * +;******************************************************************************* +%include "iprt/asmdefs.mac" + +BEGINCODE + +;; +; @param rcx eflags +BEGINPROC_EXPORTED ASMSetFlags +%if ARCH_BITS == 64 + %ifdef ASM_CALL64_GCC + push rdi + %else + push rcx + %endif + popfq +%elif ARCH_BITS == 32 + push dword [esp + 4] + popfd +%elif ARCH_BITS == 16 + push bp + mov bp, sp + push word [bp + 2 + 2] + popf + leave +%else + %error ARCH_BITS +%endif + ret +ENDPROC ASMSetFlags + diff --git a/src/VBox/Runtime/common/asm/ASMSetGDTR.asm b/src/VBox/Runtime/common/asm/ASMSetGDTR.asm new file mode 100644 index 00000000..111374a3 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMSetGDTR.asm @@ -0,0 +1,52 @@ +; $Id: ASMSetGDTR.asm $ +;; @file +; IPRT - ASMSetGDTR(). +; + +; +; Copyright (C) 2006-2020 Oracle Corporation +; +; This file is part of VirtualBox Open Source Edition (OSE), as +; available from http://www.virtualbox.org. This file is free software; +; you can redistribute it and/or modify it under the terms of the GNU +; General Public License (GPL) as published by the Free Software +; Foundation, in version 2 as it comes in the "COPYING" file of the +; VirtualBox OSE distribution. VirtualBox OSE is distributed in the +; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL) only, as it comes in the "COPYING.CDDL" file of the +; VirtualBox OSE 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. +; + +;******************************************************************************* +;* Header Files * +;******************************************************************************* +%include "iprt/asmdefs.mac" + +BEGINCODE + +;; +; Sets the content of the GDTR CPU register. +; @param pGdtr Where to load the GDTR contents from. +; msc=rcx, gcc=rdi, x86=[esp+4] +; +BEGINPROC_EXPORTED ASMSetGDTR +%ifdef ASM_CALL64_MSC + mov rax, rcx +%elifdef ASM_CALL64_GCC + mov rax, rdi +%elifdef RT_ARCH_X86 + mov eax, [esp + 4] +%else + %error "Undefined arch?" +%endif + lgdt [xAX] + ret +ENDPROC ASMSetGDTR + diff --git a/src/VBox/Runtime/common/asm/ASMSetIDTR.asm b/src/VBox/Runtime/common/asm/ASMSetIDTR.asm new file mode 100644 index 00000000..f8572658 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMSetIDTR.asm @@ -0,0 +1,52 @@ +; $Id: ASMSetIDTR.asm $ +;; @file +; IPRT - ASMSetIDTR(). +; + +; +; Copyright (C) 2006-2020 Oracle Corporation +; +; This file is part of VirtualBox Open Source Edition (OSE), as +; available from http://www.virtualbox.org. This file is free software; +; you can redistribute it and/or modify it under the terms of the GNU +; General Public License (GPL) as published by the Free Software +; Foundation, in version 2 as it comes in the "COPYING" file of the +; VirtualBox OSE distribution. VirtualBox OSE is distributed in the +; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL) only, as it comes in the "COPYING.CDDL" file of the +; VirtualBox OSE 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. +; + +;******************************************************************************* +;* Header Files * +;******************************************************************************* +%include "iprt/asmdefs.mac" + +BEGINCODE + +;; +; Sets the content of the IDTR CPU register. +; @param pIdtr Where to load the IDTR contents from. +; msc=rcx, gcc=rdi, x86=[esp+4] +; +BEGINPROC_EXPORTED ASMSetIDTR +%ifdef ASM_CALL64_MSC + mov rax, rcx +%elifdef ASM_CALL64_GCC + mov rax, rdi +%elifdef RT_ARCH_X86 + mov eax, [esp + 4] +%else + %error "Undefined arch?" +%endif + lidt [xAX] + ret +ENDPROC ASMSetIDTR + diff --git a/src/VBox/Runtime/common/asm/ASMSetXcr0.asm b/src/VBox/Runtime/common/asm/ASMSetXcr0.asm new file mode 100644 index 00000000..a282270d --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMSetXcr0.asm @@ -0,0 +1,70 @@ +; $Id: ASMSetXcr0.asm $ +;; @file +; IPRT - ASMSetXcr0(). +; + +; +; Copyright (C) 2006-2020 Oracle Corporation +; +; This file is part of VirtualBox Open Source Edition (OSE), as +; available from http://www.virtualbox.org. This file is free software; +; you can redistribute it and/or modify it under the terms of the GNU +; General Public License (GPL) as published by the Free Software +; Foundation, in version 2 as it comes in the "COPYING" file of the +; VirtualBox OSE distribution. VirtualBox OSE is distributed in the +; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL) only, as it comes in the "COPYING.CDDL" file of the +; VirtualBox OSE 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. +; + +;******************************************************************************* +;* Header Files * +;******************************************************************************* +%define RT_ASM_WITH_SEH64 +%include "iprt/asmdefs.mac" + +BEGINCODE + +;; +; Sets the content of the Xcr0 CPU register. +; @param uXcr0 The new XCR0 content. +; msc=rcx, gcc=rdi, x86=[esp+4] +; +BEGINPROC_EXPORTED ASMSetXcr0 +SEH64_END_PROLOGUE +%ifdef ASM_CALL64_MSC + mov rdx, rcx + shr rdx, 32 + mov eax, ecx +%elifdef ASM_CALL64_GCC + mov rdx, rdi + shr rdx, 32 + mov eax, edi +%elif ARCH_BITS == 32 + mov eax, [esp + 4] + mov edx, [esp + 8] +%elif ARCH_BITS == 16 + push bp + mov bp, sp + mov eax, [bp + 4] + mov edx, [bp + 8] +%else + %error "Undefined arch?" +%endif + + xor ecx, ecx + xsetbv + +%if ARCH_BITS == 16 + leave +%endif + ret +ENDPROC ASMSetXcr0 + diff --git a/src/VBox/Runtime/common/asm/ASMWrMsrEx.asm b/src/VBox/Runtime/common/asm/ASMWrMsrEx.asm new file mode 100644 index 00000000..ee5c6a46 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMWrMsrEx.asm @@ -0,0 +1,79 @@ +; $Id: ASMWrMsrEx.asm $ +;; @file +; IPRT - ASMWrMsrEx(). +; + +; +; Copyright (C) 2013-2020 Oracle Corporation +; +; This file is part of VirtualBox Open Source Edition (OSE), as +; available from http://www.virtualbox.org. This file is free software; +; you can redistribute it and/or modify it under the terms of the GNU +; General Public License (GPL) as published by the Free Software +; Foundation, in version 2 as it comes in the "COPYING" file of the +; VirtualBox OSE distribution. VirtualBox OSE is distributed in the +; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL) only, as it comes in the "COPYING.CDDL" file of the +; VirtualBox OSE 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. +; + +;******************************************************************************* +;* Header Files * +;******************************************************************************* +%include "iprt/asmdefs.mac" + +BEGINCODE + +;; +; Special version of ASMRdMsr that allow specifying the rdi value. +; +; @param uMsr msc=rcx, gcc=rdi, x86=[ebp+8] The MSR to read. +; @param uXDI msc=rdx, gcc=rsi, x86=[ebp+12] The EDI/RDI value. +; @param uValue msc=r8, gcc=rdx, x86=[ebp+16] The 64-bit value to write. +; +BEGINPROC_EXPORTED ASMWrMsrEx +%ifdef ASM_CALL64_MSC +proc_frame ASMWrMsrEx_DupWarningHack + push rdi + [pushreg rdi] +[endprolog] + and ecx, ecx ; serious paranoia + mov rdi, rdx + mov eax, r8d + mov rdx, r8 + shr rdx, 32 + wrmsr + pop rdi + ret +endproc_frame +%elifdef ASM_CALL64_GCC + mov ecx, edi + mov rdi, rsi + mov eax, edx + shr edx, 32 + wrmsr + ret +%elifdef RT_ARCH_X86 + push ebp + mov ebp, esp + push edi + mov ecx, [ebp + 8] + mov edi, [esp + 12] + mov eax, [esp + 16] + mov edx, [esp + 20] + wrmsr + pop edi + leave + ret +%else + %error "Undefined arch?" +%endif +ENDPROC ASMWrMsrEx + diff --git a/src/VBox/Runtime/common/asm/ASMXRstor.asm b/src/VBox/Runtime/common/asm/ASMXRstor.asm new file mode 100644 index 00000000..d9c3c7b7 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMXRstor.asm @@ -0,0 +1,63 @@ +; $Id: ASMXRstor.asm $ +;; @file +; IPRT - ASMXRstor(). +; + +; +; Copyright (C) 2006-2020 Oracle Corporation +; +; This file is part of VirtualBox Open Source Edition (OSE), as +; available from http://www.virtualbox.org. This file is free software; +; you can redistribute it and/or modify it under the terms of the GNU +; General Public License (GPL) as published by the Free Software +; Foundation, in version 2 as it comes in the "COPYING" file of the +; VirtualBox OSE distribution. VirtualBox OSE is distributed in the +; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL) only, as it comes in the "COPYING.CDDL" file of the +; VirtualBox OSE 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. +; + +;******************************************************************************* +;* Header Files * +;******************************************************************************* +%define RT_ASM_WITH_SEH64 +%include "iprt/asmdefs.mac" + +BEGINCODE + +;; +; Loads extended CPU state. +; @param pXStateArea Pointer to the XRSTOR state area. +; msc=rcx, gcc=rdi, x86=[esp+4] +; @param fMask The 64-bit state component mask. +; msc=rdx, gcc=rsi, x86=[esp+8] +; +BEGINPROC_EXPORTED ASMXRstor +SEH64_END_PROLOGUE +%ifdef ASM_CALL64_MSC + mov eax, edx + shr rdx, 32 + xrstor [rcx] +%elifdef ASM_CALL64_GCC + mov rdx, rsi + shr rdx, 32 + mov eax, esi + xrstor [rdi] +%elifdef RT_ARCH_X86 + mov ecx, [esp + 4] + mov eax, [esp + 8] + mov edx, [esp + 12] + xrstor [ecx] +%else + %error "Undefined arch?" +%endif + ret +ENDPROC ASMXRstor + diff --git a/src/VBox/Runtime/common/asm/ASMXSave.asm b/src/VBox/Runtime/common/asm/ASMXSave.asm new file mode 100644 index 00000000..95d7b81a --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMXSave.asm @@ -0,0 +1,63 @@ +; $Id: ASMXSave.asm $ +;; @file +; IPRT - ASMXSave(). +; + +; +; Copyright (C) 2006-2020 Oracle Corporation +; +; This file is part of VirtualBox Open Source Edition (OSE), as +; available from http://www.virtualbox.org. This file is free software; +; you can redistribute it and/or modify it under the terms of the GNU +; General Public License (GPL) as published by the Free Software +; Foundation, in version 2 as it comes in the "COPYING" file of the +; VirtualBox OSE distribution. VirtualBox OSE is distributed in the +; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL) only, as it comes in the "COPYING.CDDL" file of the +; VirtualBox OSE 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. +; + +;******************************************************************************* +;* Header Files * +;******************************************************************************* +%define RT_ASM_WITH_SEH64 +%include "iprt/asmdefs.mac" + +BEGINCODE + +;; +; Saves extended CPU state. +; @param pXStateArea Pointer to the XSAVE state area. +; msc=rcx, gcc=rdi, x86=[esp+4] +; @param fComponents The 64-bit state component mask. +; msc=rdx, gcc=rsi, x86=[esp+8] +; +BEGINPROC_EXPORTED ASMXSave +SEH64_END_PROLOGUE +%ifdef ASM_CALL64_MSC + mov eax, edx + shr rdx, 32 + xsave [rcx] +%elifdef ASM_CALL64_GCC + mov rdx, rsi + shr rdx, 32 + mov eax, esi + xsave [rdi] +%elifdef RT_ARCH_X86 + mov ecx, [esp + 4] + mov eax, [esp + 8] + mov edx, [esp + 12] + xsave [ecx] +%else + %error "Undefined arch?" +%endif + ret +ENDPROC ASMXSave + diff --git a/src/VBox/Runtime/common/asm/Makefile.kup b/src/VBox/Runtime/common/asm/Makefile.kup new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/src/VBox/Runtime/common/asm/Makefile.kup diff --git a/src/VBox/Runtime/common/asm/asm-fake.cpp b/src/VBox/Runtime/common/asm/asm-fake.cpp new file mode 100644 index 00000000..13aa4039 --- /dev/null +++ b/src/VBox/Runtime/common/asm/asm-fake.cpp @@ -0,0 +1,500 @@ +/* $Id: asm-fake.cpp $ */ +/** @file + * IPRT - Fake asm.h routines for use early in a new port. + */ + +/* + * Copyright (C) 2010-2020 Oracle Corporation + * + * This file is part of VirtualBox Open Source Edition (OSE), as + * available from http://www.virtualbox.org. This file is free software; + * you can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) as published by the Free Software + * Foundation, in version 2 as it comes in the "COPYING" file of the + * VirtualBox OSE distribution. VirtualBox OSE is distributed in the + * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL) only, as it comes in the "COPYING.CDDL" file of the + * VirtualBox OSE 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. + */ + + +/********************************************************************************************************************************* +* Header Files * +*********************************************************************************************************************************/ +#include <iprt/asm.h> +#include "internal/iprt.h" + +#include <iprt/string.h> +#include <iprt/param.h> + + +RTDECL(uint8_t) ASMAtomicXchgU8(volatile uint8_t *pu8, uint8_t u8) +{ + uint8_t u8Ret = *pu8; + *pu8 = u8; + return u8Ret; +} + +RTDECL(uint16_t) ASMAtomicXchgU16(volatile uint16_t *pu16, uint16_t u16) +{ + uint16_t u16Ret = *pu16; + *pu16 = u16; + return u16Ret; +} + +RTDECL(uint32_t) ASMAtomicXchgU32(volatile uint32_t *pu32, uint32_t u32) +{ + uint32_t u32Ret = *pu32; + *pu32 = u32; + return u32Ret; +} + +RTDECL(uint64_t) ASMAtomicXchgU64(volatile uint64_t *pu64, uint64_t u64) +{ + uint64_t u64Ret = *pu64; + *pu64 = u64; + return u64Ret; +} + +RTDECL(bool) ASMAtomicCmpXchgU8(volatile uint8_t *pu8, const uint8_t u8New, const uint8_t u8Old) +{ + if (*pu8 == u8Old) + { + *pu8 = u8New; + return true; + } + return false; +} + +RTDECL(bool) ASMAtomicCmpXchgU32(volatile uint32_t *pu32, const uint32_t u32New, const uint32_t u32Old) +{ + if (*pu32 == u32Old) + { + *pu32 = u32New; + return true; + } + return false; +} + +RTDECL(bool) ASMAtomicCmpXchgU64(volatile uint64_t *pu64, const uint64_t u64New, const uint64_t u64Old) +{ + if (*pu64 == u64Old) + { + *pu64 = u64New; + return true; + } + return false; +} + +RTDECL(bool) ASMAtomicCmpXchgExU32(volatile uint32_t *pu32, const uint32_t u32New, const uint32_t u32Old, uint32_t *pu32Old) +{ + uint32_t u32Cur = *pu32; + if (u32Cur == u32Old) + { + *pu32 = u32New; + *pu32Old = u32Old; + return true; + } + *pu32Old = u32Cur; + return false; +} + +RTDECL(bool) ASMAtomicCmpXchgExU64(volatile uint64_t *pu64, const uint64_t u64New, const uint64_t u64Old, uint64_t *pu64Old) +{ + uint64_t u64Cur = *pu64; + if (u64Cur == u64Old) + { + *pu64 = u64New; + *pu64Old = u64Old; + return true; + } + *pu64Old = u64Cur; + return false; +} + +RTDECL(uint32_t) ASMAtomicAddU32(uint32_t volatile *pu32, uint32_t u32) +{ + uint32_t u32Old = *pu32; + *pu32 = u32Old + u32; + return u32Old; +} + +RTDECL(uint64_t) ASMAtomicAddU64(uint64_t volatile *pu64, uint64_t u64) +{ + uint64_t u64Old = *pu64; + *pu64 = u64Old + u64; + return u64Old; +} + +RTDECL(uint32_t) ASMAtomicIncU32(uint32_t volatile *pu32) +{ + return *pu32 += 1; +} + +RTDECL(uint32_t) ASMAtomicUoIncU32(uint32_t volatile *pu32) +{ + return *pu32 += 1; +} + +RTDECL(uint32_t) ASMAtomicDecU32(uint32_t volatile *pu32) +{ + return *pu32 -= 1; +} + +RTDECL(uint32_t) ASMAtomicUoDecU32(uint32_t volatile *pu32) +{ + return *pu32 -= 1; +} + +RTDECL(uint64_t) ASMAtomicIncU64(uint64_t volatile *pu64) +{ + return *pu64 += 1; +} + +RTDECL(uint64_t) ASMAtomicDecU64(uint64_t volatile *pu64) +{ + return *pu64 -= 1; +} + +RTDECL(void) ASMAtomicOrU32(uint32_t volatile *pu32, uint32_t u32) +{ + *pu32 |= u32; +} + +RTDECL(void) ASMAtomicUoOrU32(uint32_t volatile *pu32, uint32_t u32) +{ + *pu32 |= u32; +} + +RTDECL(void) ASMAtomicAndU32(uint32_t volatile *pu32, uint32_t u32) +{ + *pu32 &= u32; +} + +RTDECL(void) ASMAtomicUoAndU32(uint32_t volatile *pu32, uint32_t u32) +{ + *pu32 &= u32; +} + +RTDECL(void) ASMAtomicOrU64(uint64_t volatile *pu64, uint64_t u64) +{ + *pu64 |= u64; +} + +RTDECL(void) ASMAtomicAndU64(uint64_t volatile *pu64, uint64_t u64) +{ + *pu64 &= u64; +} + +RTDECL(void) ASMSerializeInstruction(void) +{ + +} + +RTDECL(uint64_t) ASMAtomicReadU64(volatile uint64_t *pu64) +{ + return *pu64; +} + +RTDECL(uint64_t) ASMAtomicUoReadU64(volatile uint64_t *pu64) +{ + return *pu64; +} + +RTDECL(void) ASMMemZeroPage(volatile void *pv) +{ + uintptr_t volatile *puPtr = (uintptr_t volatile *)pv; + uint32_t cbLeft = PAGE_SIZE / sizeof(uintptr_t); + while (cbLeft-- > 0) + *puPtr++ = 0; +} + +RTDECL(void) ASMMemZero32(volatile void *pv, size_t cb) +{ + uint32_t volatile *pu32 = (uint32_t volatile *)pv; + uint32_t cbLeft = cb / sizeof(uint32_t); + while (cbLeft-- > 0) + *pu32++ = 0; +} + +RTDECL(void) ASMMemFill32(volatile void *pv, size_t cb, uint32_t u32) +{ + uint32_t volatile *pu32 = (uint32_t volatile *)pv; + while (cb > 0) + { + *pu32 = u32; + cb -= sizeof(uint32_t); + pu32++; + } +} + +RTDECL(uint8_t) ASMProbeReadByte(const void *pvByte) +{ + return *(volatile uint8_t *)pvByte; +} + +#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86) +RTDECL(void) ASMNopPause(void) +{ +} +#endif + +RTDECL(void) ASMBitSet(volatile void *pvBitmap, int32_t iBit) +{ + uint8_t volatile *pau8Bitmap = (uint8_t volatile *)pvBitmap; + pau8Bitmap[iBit / 8] |= (uint8_t)RT_BIT_32(iBit & 7); +} + +RTDECL(void) ASMAtomicBitSet(volatile void *pvBitmap, int32_t iBit) +{ + ASMBitSet(pvBitmap, iBit); +} + +RTDECL(void) ASMBitClear(volatile void *pvBitmap, int32_t iBit) +{ + uint8_t volatile *pau8Bitmap = (uint8_t volatile *)pvBitmap; + pau8Bitmap[iBit / 8] &= ~((uint8_t)RT_BIT_32(iBit & 7)); +} + +RTDECL(void) ASMAtomicBitClear(volatile void *pvBitmap, int32_t iBit) +{ + ASMBitClear(pvBitmap, iBit); +} + +RTDECL(void) ASMBitToggle(volatile void *pvBitmap, int32_t iBit) +{ + uint8_t volatile *pau8Bitmap = (uint8_t volatile *)pvBitmap; + pau8Bitmap[iBit / 8] ^= (uint8_t)RT_BIT_32(iBit & 7); +} + +RTDECL(void) ASMAtomicBitToggle(volatile void *pvBitmap, int32_t iBit) +{ + ASMBitToggle(pvBitmap, iBit); +} + +RTDECL(bool) ASMBitTestAndSet(volatile void *pvBitmap, int32_t iBit) +{ + if (ASMBitTest(pvBitmap, iBit)) + return true; + ASMBitSet(pvBitmap, iBit); + return false; +} + +RTDECL(bool) ASMAtomicBitTestAndSet(volatile void *pvBitmap, int32_t iBit) +{ + return ASMBitTestAndSet(pvBitmap, iBit); +} + +RTDECL(bool) ASMBitTestAndClear(volatile void *pvBitmap, int32_t iBit) +{ + if (!ASMBitTest(pvBitmap, iBit)) + return false; + ASMBitClear(pvBitmap, iBit); + return true; +} + +RTDECL(bool) ASMAtomicBitTestAndClear(volatile void *pvBitmap, int32_t iBit) +{ + return ASMBitTestAndClear(pvBitmap, iBit); +} + +RTDECL(bool) ASMBitTestAndToggle(volatile void *pvBitmap, int32_t iBit) +{ + bool fRet = ASMBitTest(pvBitmap, iBit); + ASMBitToggle(pvBitmap, iBit); + return fRet; +} + +RTDECL(bool) ASMAtomicBitTestAndToggle(volatile void *pvBitmap, int32_t iBit) +{ + return ASMBitTestAndToggle(pvBitmap, iBit); +} + +RTDECL(bool) ASMBitTest(const volatile void *pvBitmap, int32_t iBit) +{ + uint8_t volatile *pau8Bitmap = (uint8_t volatile *)pvBitmap; + return pau8Bitmap[iBit / 8] & (uint8_t)RT_BIT_32(iBit & 7) ? true : false; +} + +RTDECL(int) ASMBitFirstClear(const volatile void *pvBitmap, uint32_t cBits) +{ + uint32_t iBit = 0; + uint8_t volatile *pu8 = (uint8_t volatile *)pvBitmap; + + while (iBit < cBits) + { + uint8_t u8 = *pu8; + if (u8 != UINT8_MAX) + { + while (u8 & 1) + { + u8 >>= 1; + iBit++; + } + if (iBit >= cBits) + return -1; + return iBit; + } + + iBit += 8; + pu8++; + } + return -1; +} + +RTDECL(int) ASMBitNextClear(const volatile void *pvBitmap, uint32_t cBits, uint32_t iBitPrev) +{ + const volatile uint8_t *pau8Bitmap = (const volatile uint8_t *)pvBitmap; + int iBit = ++iBitPrev & 7; + if (iBit) + { + /* + * Inspect the byte containing the unaligned bit. + */ + uint8_t u8 = ~pau8Bitmap[iBitPrev / 8] >> iBit; + if (u8) + { + iBit = 0; + while (!(u8 & 1)) + { + u8 >>= 1; + iBit++; + } + return iBitPrev + iBit; + } + + /* + * Skip ahead and see if there is anything left to search. + */ + iBitPrev |= 7; + iBitPrev++; + if (cBits <= iBitPrev) + return -1; + } + + /* + * Byte search, let ASMBitFirstClear do the dirty work. + */ + iBit = ASMBitFirstClear(&pau8Bitmap[iBitPrev / 8], cBits - iBitPrev); + if (iBit >= 0) + iBit += iBitPrev; + return iBit; +} + +RTDECL(int) ASMBitFirstSet(const volatile void *pvBitmap, uint32_t cBits) +{ + uint32_t iBit = 0; + uint8_t volatile *pu8 = (uint8_t volatile *)pvBitmap; + while (iBit < cBits) + { + uint8_t u8 = *pu8; + if (u8 != 0) + { + while (!(u8 & 1)) + { + u8 >>= 1; + iBit++; + } + if (iBit >= cBits) + return -1; + return iBit; + } + + iBit += 8; + pu8++; + } + return -1; +} + +RTDECL(int) ASMBitNextSet(const volatile void *pvBitmap, uint32_t cBits, uint32_t iBitPrev) +{ + const volatile uint8_t *pau8Bitmap = (const volatile uint8_t *)pvBitmap; + int iBit = ++iBitPrev & 7; + if (iBit) + { + /* + * Inspect the byte containing the unaligned bit. + */ + uint8_t u8 = pau8Bitmap[iBitPrev / 8] >> iBit; + if (u8) + { + iBit = 0; + while (!(u8 & 1)) + { + u8 >>= 1; + iBit++; + } + return iBitPrev + iBit; + } + + /* + * Skip ahead and see if there is anything left to search. + */ + iBitPrev |= 7; + iBitPrev++; + if (cBits <= iBitPrev) + return -1; + } + + /* + * Byte search, let ASMBitFirstSet do the dirty work. + */ + iBit = ASMBitFirstSet(&pau8Bitmap[iBitPrev / 8], cBits - iBitPrev); + if (iBit >= 0) + iBit += iBitPrev; + return iBit; +} + +RTDECL(unsigned) ASMBitFirstSetU32(uint32_t u32) +{ + uint32_t iBit; + for (iBit = 0; iBit < 32; iBit++) + if (u32 & RT_BIT_32(iBit)) + return iBit + 1; + return 0; +} + +RTDECL(unsigned) ASMBitLastSetU32(uint32_t u32) +{ + uint32_t iBit = 32; + while (iBit-- > 0) + if (u32 & RT_BIT_32(iBit)) + return iBit + 1; + return 0; +} + +RTDECL(unsigned) ASMBitFirstSetU64(uint64_t u64) +{ + uint32_t iBit; + for (iBit = 0; iBit < 64; iBit++) + if (u64 & RT_BIT_64(iBit)) + return iBit + 1; + return 0; +} + +RTDECL(unsigned) ASMBitLastSetU64(uint64_t u64) +{ + uint32_t iBit = 64; + while (iBit-- > 0) + if (u64 & RT_BIT_64(iBit)) + return iBit + 1; + return 0; +} + +RTDECL(uint16_t) ASMByteSwapU16(uint16_t u16) +{ + return RT_MAKE_U16(RT_HIBYTE(u16), RT_LOBYTE(u16)); +} + +RTDECL(uint32_t) ASMByteSwapU32(uint32_t u32) +{ + return RT_MAKE_U32_FROM_U8(RT_BYTE4(u32), RT_BYTE3(u32), RT_BYTE2(u32), RT_BYTE1(u32)); +} + |