diff options
Diffstat (limited to 'src/VBox/Runtime/common/asm')
71 files changed, 6419 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..bdecbeb3 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMAddFlags.asm @@ -0,0 +1,80 @@ +; $Id: ASMAddFlags.asm $ +;; @file +; IPRT - ASMSetFlags(). +; + +; +; Copyright (C) 2006-2023 Oracle and/or its affiliates. +; +; This file is part of VirtualBox base platform packages, as +; available from https://www.virtualbox.org. +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; as published by the Free Software Foundation, in version 3 of the +; License. +; +; This program is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, see <https://www.gnu.org/licenses>. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included +; in the VirtualBox distribution, in which case the provisions of the +; CDDL are applicable instead of those of the GPL. +; +; You may elect to license modified versions of this file under the +; terms and conditions of either the GPL or the CDDL or both. +; +; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 +; + + +;******************************************************************************* +;* Header Files * +;******************************************************************************* +%include "iprt/asmdefs.mac" + +BEGINCODE + +;; +; @param rcx/rdi eflags to add +RT_BEGINPROC 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..0cab24b5 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMAtomicCmpXchgExU64.asm @@ -0,0 +1,94 @@ +; $Id: ASMAtomicCmpXchgExU64.asm $ +;; @file +; IPRT - ASMAtomicCmpXchgExU64(). +; + +; +; Copyright (C) 2006-2023 Oracle and/or its affiliates. +; +; This file is part of VirtualBox base platform packages, as +; available from https://www.virtualbox.org. +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; as published by the Free Software Foundation, in version 3 of the +; License. +; +; This program is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, see <https://www.gnu.org/licenses>. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included +; in the VirtualBox distribution, in which case the provisions of the +; CDDL are applicable instead of those of the GPL. +; +; You may elect to license modified versions of this file under the +; terms and conditions of either the GPL or the CDDL or both. +; +; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 +; + +;******************************************************************************* +;* 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 +; +RT_BEGINPROC 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..5476de4f --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMAtomicCmpXchgU16.asm @@ -0,0 +1,73 @@ +; $Id: ASMAtomicCmpXchgU16.asm $ +;; @file +; IPRT - ASMAtomicCmpXchgU16(). +; + +; +; Copyright (C) 2006-2023 Oracle and/or its affiliates. +; +; This file is part of VirtualBox base platform packages, as +; available from https://www.virtualbox.org. +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; as published by the Free Software Foundation, in version 3 of the +; License. +; +; This program is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, see <https://www.gnu.org/licenses>. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included +; in the VirtualBox distribution, in which case the provisions of the +; CDDL are applicable instead of those of the GPL. +; +; You may elect to license modified versions of this file under the +; terms and conditions of either the GPL or the CDDL or both. +; +; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 +; + +;******************************************************************************* +;* 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 +; +RT_BEGINPROC 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..d63b0333 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMAtomicCmpXchgU64.asm @@ -0,0 +1,88 @@ +; $Id: ASMAtomicCmpXchgU64.asm $ +;; @file +; IPRT - ASMAtomicCmpXchgU64(). +; + +; +; Copyright (C) 2006-2023 Oracle and/or its affiliates. +; +; This file is part of VirtualBox base platform packages, as +; available from https://www.virtualbox.org. +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; as published by the Free Software Foundation, in version 3 of the +; License. +; +; This program is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, see <https://www.gnu.org/licenses>. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included +; in the VirtualBox distribution, in which case the provisions of the +; CDDL are applicable instead of those of the GPL. +; +; You may elect to license modified versions of this file under the +; terms and conditions of either the GPL or the CDDL or both. +; +; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 +; + +;******************************************************************************* +;* 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 +; +RT_BEGINPROC 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..c4a030ff --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMAtomicCmpXchgU8.asm @@ -0,0 +1,73 @@ +; $Id: ASMAtomicCmpXchgU8.asm $ +;; @file +; IPRT - ASMAtomicCmpXchgU8(). +; + +; +; Copyright (C) 2006-2023 Oracle and/or its affiliates. +; +; This file is part of VirtualBox base platform packages, as +; available from https://www.virtualbox.org. +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; as published by the Free Software Foundation, in version 3 of the +; License. +; +; This program is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, see <https://www.gnu.org/licenses>. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included +; in the VirtualBox distribution, in which case the provisions of the +; CDDL are applicable instead of those of the GPL. +; +; You may elect to license modified versions of this file under the +; terms and conditions of either the GPL or the CDDL or both. +; +; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 +; + +;******************************************************************************* +;* 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 +; +RT_BEGINPROC 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..8214838e --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMAtomicReadU64.asm @@ -0,0 +1,81 @@ +; $Id: ASMAtomicReadU64.asm $ +;; @file +; IPRT - ASMAtomicReadU64(). +; + +; +; Copyright (C) 2006-2023 Oracle and/or its affiliates. +; +; This file is part of VirtualBox base platform packages, as +; available from https://www.virtualbox.org. +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; as published by the Free Software Foundation, in version 3 of the +; License. +; +; This program is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, see <https://www.gnu.org/licenses>. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included +; in the VirtualBox distribution, in which case the provisions of the +; CDDL are applicable instead of those of the GPL. +; +; You may elect to license modified versions of this file under the +; terms and conditions of either the GPL or the CDDL or both. +; +; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 +; + +;******************************************************************************* +;* Header Files * +;******************************************************************************* +%include "iprt/asmdefs.mac" + +BEGINCODE + +;; +; Atomically reads 64-bit value. +; +; @param pu64 x86:ebp+8 +; +; @returns The current value. (x86:eax+edx) +; +; +RT_BEGINPROC 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..4bc47b18 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMAtomicUoAndU32.asm @@ -0,0 +1,66 @@ +; $Id: ASMAtomicUoAndU32.asm $ +;; @file +; IPRT - ASMAtomicUoAndU32(). +; + +; +; Copyright (C) 2013-2023 Oracle and/or its affiliates. +; +; This file is part of VirtualBox base platform packages, as +; available from https://www.virtualbox.org. +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; as published by the Free Software Foundation, in version 3 of the +; License. +; +; This program is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, see <https://www.gnu.org/licenses>. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included +; in the VirtualBox distribution, in which case the provisions of the +; CDDL are applicable instead of those of the GPL. +; +; You may elect to license modified versions of this file under the +; terms and conditions of either the GPL or the CDDL or both. +; +; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 +; + +;******************************************************************************* +;* 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 +; +RT_BEGINPROC 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..1266e3bc --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMAtomicUoAndU64.asm @@ -0,0 +1,86 @@ +; $Id: ASMAtomicUoAndU64.asm $ +;; @file +; IPRT - ASMAtomicUoAndU64(). +; + +; +; Copyright (C) 2013-2023 Oracle and/or its affiliates. +; +; This file is part of VirtualBox base platform packages, as +; available from https://www.virtualbox.org. +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; as published by the Free Software Foundation, in version 3 of the +; License. +; +; This program is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, see <https://www.gnu.org/licenses>. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included +; in the VirtualBox distribution, in which case the provisions of the +; CDDL are applicable instead of those of the GPL. +; +; You may elect to license modified versions of this file under the +; terms and conditions of either the GPL or the CDDL or both. +; +; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 +; + +;******************************************************************************* +;* 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 +; +RT_BEGINPROC 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..469bc69f --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMAtomicUoDecU32.asm @@ -0,0 +1,66 @@ +; $Id: ASMAtomicUoDecU32.asm $ +;; @file +; IPRT - ASMAtomicUoDecU32(). +; + +; +; Copyright (C) 2014-2023 Oracle and/or its affiliates. +; +; This file is part of VirtualBox base platform packages, as +; available from https://www.virtualbox.org. +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; as published by the Free Software Foundation, in version 3 of the +; License. +; +; This program is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, see <https://www.gnu.org/licenses>. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included +; in the VirtualBox distribution, in which case the provisions of the +; CDDL are applicable instead of those of the GPL. +; +; You may elect to license modified versions of this file under the +; terms and conditions of either the GPL or the CDDL or both. +; +; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 +; + +;******************************************************************************* +;* 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. +; +RT_BEGINPROC 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..50ce19a0 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMAtomicUoIncU32.asm @@ -0,0 +1,66 @@ +; $Id: ASMAtomicUoIncU32.asm $ +;; @file +; IPRT - ASMAtomicUoIncU32(). +; + +; +; Copyright (C) 2014-2023 Oracle and/or its affiliates. +; +; This file is part of VirtualBox base platform packages, as +; available from https://www.virtualbox.org. +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; as published by the Free Software Foundation, in version 3 of the +; License. +; +; This program is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, see <https://www.gnu.org/licenses>. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included +; in the VirtualBox distribution, in which case the provisions of the +; CDDL are applicable instead of those of the GPL. +; +; You may elect to license modified versions of this file under the +; terms and conditions of either the GPL or the CDDL or both. +; +; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 +; + +;******************************************************************************* +;* 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. +; +RT_BEGINPROC 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..360e9abd --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMAtomicUoOrU32.asm @@ -0,0 +1,66 @@ +; $Id: ASMAtomicUoOrU32.asm $ +;; @file +; IPRT - ASMAtomicUoOrU32(). +; + +; +; Copyright (C) 2013-2023 Oracle and/or its affiliates. +; +; This file is part of VirtualBox base platform packages, as +; available from https://www.virtualbox.org. +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; as published by the Free Software Foundation, in version 3 of the +; License. +; +; This program is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, see <https://www.gnu.org/licenses>. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included +; in the VirtualBox distribution, in which case the provisions of the +; CDDL are applicable instead of those of the GPL. +; +; You may elect to license modified versions of this file under the +; terms and conditions of either the GPL or the CDDL or both. +; +; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 +; + +;******************************************************************************* +;* 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 +; +RT_BEGINPROC 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..a4a9cc42 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMAtomicUoOrU64.asm @@ -0,0 +1,86 @@ +; $Id: ASMAtomicUoOrU64.asm $ +;; @file +; IPRT - ASMAtomicUoOrU64(). +; + +; +; Copyright (C) 2013-2023 Oracle and/or its affiliates. +; +; This file is part of VirtualBox base platform packages, as +; available from https://www.virtualbox.org. +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; as published by the Free Software Foundation, in version 3 of the +; License. +; +; This program is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, see <https://www.gnu.org/licenses>. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included +; in the VirtualBox distribution, in which case the provisions of the +; CDDL are applicable instead of those of the GPL. +; +; You may elect to license modified versions of this file under the +; terms and conditions of either the GPL or the CDDL or both. +; +; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 +; + +;******************************************************************************* +;* 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 +; +RT_BEGINPROC 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..0b789ba5 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMAtomicUoReadU64.asm @@ -0,0 +1,80 @@ +; $Id: ASMAtomicUoReadU64.asm $ +;; @file +; IPRT - ASMAtomicUoReadU64(). +; + +; +; Copyright (C) 2006-2023 Oracle and/or its affiliates. +; +; This file is part of VirtualBox base platform packages, as +; available from https://www.virtualbox.org. +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; as published by the Free Software Foundation, in version 3 of the +; License. +; +; This program is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, see <https://www.gnu.org/licenses>. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included +; in the VirtualBox distribution, in which case the provisions of the +; CDDL are applicable instead of those of the GPL. +; +; You may elect to license modified versions of this file under the +; terms and conditions of either the GPL or the CDDL or both. +; +; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 +; + +;******************************************************************************* +;* Header Files * +;******************************************************************************* +%include "iprt/asmdefs.mac" + +BEGINCODE + +;; +; Atomically reads 64-bit value. +; +; @param pu64 x86:ebp+8 +; +; @returns The current value. (x86:eax+edx) +; +; +RT_BEGINPROC 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/ASMAtomicUoXorU32.asm b/src/VBox/Runtime/common/asm/ASMAtomicUoXorU32.asm new file mode 100644 index 00000000..07da0096 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMAtomicUoXorU32.asm @@ -0,0 +1,66 @@ +; $Id: ASMAtomicUoXorU32.asm $ +;; @file +; IPRT - ASMAtomicUoXorU32(). +; + +; +; Copyright (C) 2013-2023 Oracle and/or its affiliates. +; +; This file is part of VirtualBox base platform packages, as +; available from https://www.virtualbox.org. +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; as published by the Free Software Foundation, in version 3 of the +; License. +; +; This program is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, see <https://www.gnu.org/licenses>. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included +; in the VirtualBox distribution, in which case the provisions of the +; CDDL are applicable instead of those of the GPL. +; +; You may elect to license modified versions of this file under the +; terms and conditions of either the GPL or the CDDL or both. +; +; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 +; + +;******************************************************************************* +;* Header Files * +;******************************************************************************* +%include "iprt/asmdefs.mac" + +BEGINCODE + +;; +; Atomically XOR 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 +; +RT_BEGINPROC ASMAtomicUoXorU32 +%ifdef RT_ARCH_AMD64 + %ifdef ASM_CALL64_MSC + xor [rcx], edx + %else + xor [rdi], esi + %endif +%elifdef RT_ARCH_X86 + mov ecx, [esp + 04h] + mov edx, [esp + 08h] + xor [ecx], edx +%endif + ret +ENDPROC ASMAtomicUoXorU32 + diff --git a/src/VBox/Runtime/common/asm/ASMAtomicXchgU16.asm b/src/VBox/Runtime/common/asm/ASMAtomicXchgU16.asm new file mode 100644 index 00000000..c1d7fbc0 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMAtomicXchgU16.asm @@ -0,0 +1,70 @@ +; $Id: ASMAtomicXchgU16.asm $ +;; @file +; IPRT - ASMAtomicXchgU16(). +; + +; +; Copyright (C) 2006-2023 Oracle and/or its affiliates. +; +; This file is part of VirtualBox base platform packages, as +; available from https://www.virtualbox.org. +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; as published by the Free Software Foundation, in version 3 of the +; License. +; +; This program is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, see <https://www.gnu.org/licenses>. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included +; in the VirtualBox distribution, in which case the provisions of the +; CDDL are applicable instead of those of the GPL. +; +; You may elect to license modified versions of this file under the +; terms and conditions of either the GPL or the CDDL or both. +; +; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 +; + +;******************************************************************************* +;* 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). +; +RT_BEGINPROC 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..a137d351 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMAtomicXchgU64.asm @@ -0,0 +1,80 @@ +; $Id: ASMAtomicXchgU64.asm $ +;; @file +; IPRT - ASMAtomicXchgU64(). +; + +; +; Copyright (C) 2006-2023 Oracle and/or its affiliates. +; +; This file is part of VirtualBox base platform packages, as +; available from https://www.virtualbox.org. +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; as published by the Free Software Foundation, in version 3 of the +; License. +; +; This program is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, see <https://www.gnu.org/licenses>. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included +; in the VirtualBox distribution, in which case the provisions of the +; CDDL are applicable instead of those of the GPL. +; +; You may elect to license modified versions of this file under the +; terms and conditions of either the GPL or the CDDL or both. +; +; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 +; + +;******************************************************************************* +;* 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) +; +RT_BEGINPROC 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-generic.cpp b/src/VBox/Runtime/common/asm/ASMBitFirstClear-generic.cpp new file mode 100644 index 00000000..84444616 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMBitFirstClear-generic.cpp @@ -0,0 +1,107 @@ +/* $Id: ASMBitFirstClear-generic.cpp $ */ +/** @file + * IPRT - ASMBitFirstClear - generic C implementation. + */ + +/* + * Copyright (C) 2006-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + + +/********************************************************************************************************************************* +* Header Files * +*********************************************************************************************************************************/ +#include <iprt/asm.h> +#include "internal/iprt.h" + +#include <iprt/assert.h> + + +RTDECL(int32_t) ASMBitFirstClear(const volatile void RT_FAR *pvBitmap, uint32_t cBits) RT_NOTHROW_DEF +{ + const volatile size_t RT_FAR *pu = (const volatile size_t RT_FAR *)pvBitmap; + Assert(!(cBits & 31)); + Assert(!((uintptr_t)pvBitmap & 3)); + +#if ARCH_BITS > 32 + /* Deal with misaligned bitmaps (happens all the time via ASMBitNextClear()). */ + if (!((uintptr_t)pvBitmap & 7) && cBits >= 32) + { + uint32_t u32 = *(const volatile uint32_t RT_FAR *)pu; + if (u32 != UINT32_MAX) + { + size_t const iBaseBit = ((uintptr_t)pu - (uintptr_t)pvBitmap) * 8; + return iBaseBit + ASMBitFirstSetU32(~RT_LE2H_U32(u32)) - 1; + } + pu = (const volatile size_t RT_FAR *)((uintptr_t)pu + sizeof(uint32_t)); + cBits -= 32; + } +#endif + + /* Main search loop: */ + while (cBits >= sizeof(size_t) * 8) + { + size_t u = *pu; + if (u == ~(size_t)0) + { } + else + { + size_t const iBaseBit = ((uintptr_t)pu - (uintptr_t)pvBitmap) * 8; +#if ARCH_BITS == 32 + return iBaseBit + ASMBitFirstSetU32(~RT_LE2H_U32(u)) - 1; +#elif ARCH_BITS == 64 + return iBaseBit + ASMBitFirstSetU64(~RT_LE2H_U64(u)) - 1; +#else +# error "ARCH_BITS is not supported" +#endif + } + + pu++; + cBits -= sizeof(size_t) * 8; + } + +#if ARCH_BITS > 32 + /* Final 32-bit item (unlikely)? */ + if (cBits < 32) + { } + else + { + uint32_t u32 = *(const volatile uint32_t RT_FAR *)pu; + if (u32 != UINT32_MAX) + { + size_t const iBaseBit = ((uintptr_t)pu - (uintptr_t)pvBitmap) * 8; + return iBaseBit + ASMBitFirstSetU32(~RT_LE2H_U32(u32)) - 1; + } + } +#endif + + return -1; +} + diff --git a/src/VBox/Runtime/common/asm/ASMBitFirstClear.asm b/src/VBox/Runtime/common/asm/ASMBitFirstClear.asm new file mode 100644 index 00000000..f7b95632 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMBitFirstClear.asm @@ -0,0 +1,137 @@ +; $Id: ASMBitFirstClear.asm $ +;; @file +; IPRT - ASMBitFirstClear(). +; + +; +; Copyright (C) 2006-2023 Oracle and/or its affiliates. +; +; This file is part of VirtualBox base platform packages, as +; available from https://www.virtualbox.org. +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; as published by the Free Software Foundation, in version 3 of the +; License. +; +; This program is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, see <https://www.gnu.org/licenses>. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included +; in the VirtualBox distribution, in which case the provisions of the +; CDDL are applicable instead of those of the GPL. +; +; You may elect to license modified versions of this file under the +; terms and conditions of either the GPL or the CDDL or both. +; +; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 +; + + +;******************************************************************************* +;* 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. +; +RT_BEGINPROC 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-generic.cpp b/src/VBox/Runtime/common/asm/ASMBitFirstSet-generic.cpp new file mode 100644 index 00000000..308f33d7 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMBitFirstSet-generic.cpp @@ -0,0 +1,107 @@ +/* $Id: ASMBitFirstSet-generic.cpp $ */ +/** @file + * IPRT - ASMBitFirstSet - generic C implementation. + */ + +/* + * Copyright (C) 2006-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + + +/********************************************************************************************************************************* +* Header Files * +*********************************************************************************************************************************/ +#include <iprt/asm.h> +#include "internal/iprt.h" + +#include <iprt/assert.h> + + +RTDECL(int32_t) ASMBitFirstSet(const volatile void RT_FAR *pvBitmap, uint32_t cBits) RT_NOTHROW_DEF +{ + const volatile size_t RT_FAR *pu = (const volatile size_t RT_FAR *)pvBitmap; + Assert(!(cBits & 31)); + Assert(!((uintptr_t)pvBitmap & 3)); + +#if ARCH_BITS > 32 + /* Deal with misaligned bitmaps (happens all the time via ASMBitNextClear()). */ + if (!((uintptr_t)pvBitmap & 7) && cBits >= 32) + { + uint32_t u32 = *(const volatile uint32_t RT_FAR *)pu; + if (u32 != 0) + { + size_t const iBaseBit = ((uintptr_t)pu - (uintptr_t)pvBitmap) * 8; + return iBaseBit + ASMBitFirstSetU32(RT_LE2H_U32(u32)) - 1; + } + pu = (const volatile size_t RT_FAR *)((uintptr_t)pu + sizeof(uint32_t)); + cBits -= 32; + } +#endif + + /* Main search loop: */ + while (cBits >= sizeof(size_t) * 8) + { + size_t u = *pu; + if (u == 0) + { } + else + { + size_t const iBaseBit = ((uintptr_t)pu - (uintptr_t)pvBitmap) * 8; +#if ARCH_BITS == 32 + return iBaseBit + ASMBitFirstSetU32(RT_LE2H_U32(u)) - 1; +#elif ARCH_BITS == 64 + return iBaseBit + ASMBitFirstSetU64(RT_LE2H_U64(u)) - 1; +#else +# error "ARCH_BITS is not supported" +#endif + } + + pu++; + cBits -= sizeof(size_t) * 8; + } + +#if ARCH_BITS > 32 + /* Final 32-bit item (unlikely)? */ + if (cBits < 32) + { } + else + { + uint32_t u32 = *(const volatile uint32_t RT_FAR *)pu; + if (u32 != 0) + { + size_t const iBaseBit = ((uintptr_t)pu - (uintptr_t)pvBitmap) * 8; + return iBaseBit + ASMBitFirstSetU32(RT_LE2H_U32(u32)) - 1; + } + } +#endif + + return -1; +} + diff --git a/src/VBox/Runtime/common/asm/ASMBitFirstSet.asm b/src/VBox/Runtime/common/asm/ASMBitFirstSet.asm new file mode 100644 index 00000000..c72d70af --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMBitFirstSet.asm @@ -0,0 +1,137 @@ +; $Id: ASMBitFirstSet.asm $ +;; @file +; IPRT - ASMBitFirstSet(). +; + +; +; Copyright (C) 2006-2023 Oracle and/or its affiliates. +; +; This file is part of VirtualBox base platform packages, as +; available from https://www.virtualbox.org. +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; as published by the Free Software Foundation, in version 3 of the +; License. +; +; This program is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, see <https://www.gnu.org/licenses>. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included +; in the VirtualBox distribution, in which case the provisions of the +; CDDL are applicable instead of those of the GPL. +; +; You may elect to license modified versions of this file under the +; terms and conditions of either the GPL or the CDDL or both. +; +; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 +; + + +;******************************************************************************* +;* 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. +; +RT_BEGINPROC 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..d60fa120 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMBitFirstSetU16.asm @@ -0,0 +1,103 @@ +; $Id: ASMBitFirstSetU16.asm $ +;; @file +; IPRT - ASMBitFirstSetU16(). +; + +; +; Copyright (C) 2006-2023 Oracle and/or its affiliates. +; +; This file is part of VirtualBox base platform packages, as +; available from https://www.virtualbox.org. +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; as published by the Free Software Foundation, in version 3 of the +; License. +; +; This program is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, see <https://www.gnu.org/licenses>. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included +; in the VirtualBox distribution, in which case the provisions of the +; CDDL are applicable instead of those of the GPL. +; +; You may elect to license modified versions of this file under the +; terms and conditions of either the GPL or the CDDL or both. +; +; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 +; + + +;******************************************************************************* +;* 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); +; +RT_BEGINPROC 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..f394201d --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMBitFirstSetU32.asm @@ -0,0 +1,107 @@ +; $Id: ASMBitFirstSetU32.asm $ +;; @file +; IPRT - ASMBitFirstSetU32(). +; + +; +; Copyright (C) 2006-2023 Oracle and/or its affiliates. +; +; This file is part of VirtualBox base platform packages, as +; available from https://www.virtualbox.org. +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; as published by the Free Software Foundation, in version 3 of the +; License. +; +; This program is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, see <https://www.gnu.org/licenses>. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included +; in the VirtualBox distribution, in which case the provisions of the +; CDDL are applicable instead of those of the GPL. +; +; You may elect to license modified versions of this file under the +; terms and conditions of either the GPL or the CDDL or both. +; +; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 +; + + +;******************************************************************************* +;* 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); +; +RT_BEGINPROC 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..aee25890 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMBitFirstSetU64.asm @@ -0,0 +1,126 @@ +; $Id: ASMBitFirstSetU64.asm $ +;; @file +; IPRT - ASMBitFirstSetU64(). +; + +; +; Copyright (C) 2006-2023 Oracle and/or its affiliates. +; +; This file is part of VirtualBox base platform packages, as +; available from https://www.virtualbox.org. +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; as published by the Free Software Foundation, in version 3 of the +; License. +; +; This program is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, see <https://www.gnu.org/licenses>. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included +; in the VirtualBox distribution, in which case the provisions of the +; CDDL are applicable instead of those of the GPL. +; +; You may elect to license modified versions of this file under the +; terms and conditions of either the GPL or the CDDL or both. +; +; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 +; + + +;******************************************************************************* +;* 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); +; +RT_BEGINPROC 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..446e1fb5 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMBitLastSetU16.asm @@ -0,0 +1,101 @@ +; $Id: ASMBitLastSetU16.asm $ +;; @file +; IPRT - ASMBitLastSetU16(). +; + +; +; Copyright (C) 2006-2023 Oracle and/or its affiliates. +; +; This file is part of VirtualBox base platform packages, as +; available from https://www.virtualbox.org. +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; as published by the Free Software Foundation, in version 3 of the +; License. +; +; This program is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, see <https://www.gnu.org/licenses>. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included +; in the VirtualBox distribution, in which case the provisions of the +; CDDL are applicable instead of those of the GPL. +; +; You may elect to license modified versions of this file under the +; terms and conditions of either the GPL or the CDDL or both. +; +; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 +; + + +;******************************************************************************* +;* 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); +; +RT_BEGINPROC 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..fb3f5ab9 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMBitLastSetU32.asm @@ -0,0 +1,107 @@ +; $Id: ASMBitLastSetU32.asm $ +;; @file +; IPRT - ASMBitLastSetU32(). +; + +; +; Copyright (C) 2006-2023 Oracle and/or its affiliates. +; +; This file is part of VirtualBox base platform packages, as +; available from https://www.virtualbox.org. +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; as published by the Free Software Foundation, in version 3 of the +; License. +; +; This program is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, see <https://www.gnu.org/licenses>. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included +; in the VirtualBox distribution, in which case the provisions of the +; CDDL are applicable instead of those of the GPL. +; +; You may elect to license modified versions of this file under the +; terms and conditions of either the GPL or the CDDL or both. +; +; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 +; + + +;******************************************************************************* +;* 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); +; +RT_BEGINPROC 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..2d6cb38e --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMBitLastSetU64.asm @@ -0,0 +1,130 @@ +; $Id: ASMBitLastSetU64.asm $ +;; @file +; IPRT - ASMBitLastSetU64(). +; + +; +; Copyright (C) 2006-2023 Oracle and/or its affiliates. +; +; This file is part of VirtualBox base platform packages, as +; available from https://www.virtualbox.org. +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; as published by the Free Software Foundation, in version 3 of the +; License. +; +; This program is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, see <https://www.gnu.org/licenses>. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included +; in the VirtualBox distribution, in which case the provisions of the +; CDDL are applicable instead of those of the GPL. +; +; You may elect to license modified versions of this file under the +; terms and conditions of either the GPL or the CDDL or both. +; +; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 +; + + +;******************************************************************************* +;* 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); +; +RT_BEGINPROC 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-generic.cpp b/src/VBox/Runtime/common/asm/ASMBitNextClear-generic.cpp new file mode 100644 index 00000000..0d3280af --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMBitNextClear-generic.cpp @@ -0,0 +1,79 @@ +/* $Id: ASMBitNextClear-generic.cpp $ */ +/** @file + * IPRT - ASMBitNextClear - generic C implementation. + */ + +/* + * Copyright (C) 2006-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + + +/********************************************************************************************************************************* +* Header Files * +*********************************************************************************************************************************/ +#include <iprt/asm.h> +#include "internal/iprt.h" + +#include <iprt/assert.h> + + +RTDECL(int) ASMBitNextClear(const volatile void RT_FAR *pvBitmap, uint32_t cBits, uint32_t iBitPrev) RT_NOTHROW_DEF +{ + const volatile uint32_t RT_FAR *pau32Bitmap = (const volatile uint32_t RT_FAR *)pvBitmap; + int iBit = ++iBitPrev & 31; + Assert(!(cBits & 31)); + Assert(!((uintptr_t)pvBitmap & 3)); + if (iBit) + { + /* + * Inspect the 32-bit word containing the unaligned bit. + */ + uint32_t u32 = ~RT_LE2H_U32(pau32Bitmap[iBitPrev / 32]) >> iBit; + if (u32) + return iBitPrev + ASMBitFirstSetU32(u32) - 1; + + /* + * Skip ahead and see if there is anything left to search. + */ + iBitPrev |= 31; + iBitPrev++; + if (cBits <= (uint32_t)iBitPrev) + return -1; + } + + /* + * 32-bit aligned search, let ASMBitFirstClear do the dirty work. + */ + iBit = ASMBitFirstClear(&pau32Bitmap[iBitPrev / 32], cBits - iBitPrev); + if (iBit >= 0) + iBit += iBitPrev; + return iBit; +} + diff --git a/src/VBox/Runtime/common/asm/ASMBitNextClear.asm b/src/VBox/Runtime/common/asm/ASMBitNextClear.asm new file mode 100644 index 00000000..f6dcb3f4 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMBitNextClear.asm @@ -0,0 +1,183 @@ +; $Id: ASMBitNextClear.asm $ +;; @file +; IPRT - ASMBitNextClear(). +; + +; +; Copyright (C) 2006-2023 Oracle and/or its affiliates. +; +; This file is part of VirtualBox base platform packages, as +; available from https://www.virtualbox.org. +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; as published by the Free Software Foundation, in version 3 of the +; License. +; +; This program is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, see <https://www.gnu.org/licenses>. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included +; in the VirtualBox distribution, in which case the provisions of the +; CDDL are applicable instead of those of the GPL. +; +; You may elect to license modified versions of this file under the +; terms and conditions of either the GPL or the CDDL or both. +; +; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 +; + + +;******************************************************************************* +;* 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. +; +RT_BEGINPROC 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-generic.cpp b/src/VBox/Runtime/common/asm/ASMBitNextSet-generic.cpp new file mode 100644 index 00000000..8233de1b --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMBitNextSet-generic.cpp @@ -0,0 +1,79 @@ +/* $Id: ASMBitNextSet-generic.cpp $ */ +/** @file + * IPRT - ASMBitNextSet - generic C implementation. + */ + +/* + * Copyright (C) 2006-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + + +/********************************************************************************************************************************* +* Header Files * +*********************************************************************************************************************************/ +#include <iprt/asm.h> +#include "internal/iprt.h" + +#include <iprt/assert.h> + + +RTDECL(int) ASMBitNextSet(const volatile void RT_FAR *pvBitmap, uint32_t cBits, uint32_t iBitPrev) RT_NOTHROW_DEF +{ + const volatile uint32_t RT_FAR *pau32Bitmap = (const volatile uint32_t RT_FAR *)pvBitmap; + int iBit = ++iBitPrev & 31; + Assert(!(cBits & 31)); + Assert(!((uintptr_t)pvBitmap & 3)); + if (iBit) + { + /* + * Inspect the 32-bit word containing the unaligned bit. + */ + uint32_t u32 = RT_LE2H_U32(pau32Bitmap[iBitPrev / 32]) >> iBit; + if (u32) + return iBitPrev + ASMBitFirstSetU32(u32) - 1; + + /* + * Skip ahead and see if there is anything left to search. + */ + iBitPrev |= 31; + iBitPrev++; + if (cBits <= (uint32_t)iBitPrev) + return -1; + } + + /* + * 32-bit aligned search, let ASMBitFirstSet do the dirty work. + */ + iBit = ASMBitFirstSet(&pau32Bitmap[iBitPrev / 32], cBits - iBitPrev); + if (iBit >= 0) + iBit += iBitPrev; + return iBit; +} + diff --git a/src/VBox/Runtime/common/asm/ASMBitNextSet.asm b/src/VBox/Runtime/common/asm/ASMBitNextSet.asm new file mode 100644 index 00000000..c2ab4e75 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMBitNextSet.asm @@ -0,0 +1,183 @@ +; $Id: ASMBitNextSet.asm $ +;; @file +; IPRT - ASMBitNextSet(). +; + +; +; Copyright (C) 2006-2023 Oracle and/or its affiliates. +; +; This file is part of VirtualBox base platform packages, as +; available from https://www.virtualbox.org. +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; as published by the Free Software Foundation, in version 3 of the +; License. +; +; This program is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, see <https://www.gnu.org/licenses>. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included +; in the VirtualBox distribution, in which case the provisions of the +; CDDL are applicable instead of those of the GPL. +; +; You may elect to license modified versions of this file under the +; terms and conditions of either the GPL or the CDDL or both. +; +; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 +; + + +;******************************************************************************* +;* 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. +; +RT_BEGINPROC 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..62c31426 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMCpuId.asm @@ -0,0 +1,121 @@ +; $Id: ASMCpuId.asm $ +;; @file +; IPRT - ASMCpuIdExSlow(). +; + +; +; Copyright (C) 2012-2023 Oracle and/or its affiliates. +; +; This file is part of VirtualBox base platform packages, as +; available from https://www.virtualbox.org. +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; as published by the Free Software Foundation, in version 3 of the +; License. +; +; This program is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, see <https://www.gnu.org/licenses>. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included +; in the VirtualBox distribution, in which case the provisions of the +; CDDL are applicable instead of those of the GPL. +; +; You may elect to license modified versions of this file under the +; terms and conditions of either the GPL or the CDDL or both. +; +; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 +; + +;******************************************************************************* +;* 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); +; +RT_BEGINPROC 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..aab68727 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMCpuIdExSlow.asm @@ -0,0 +1,181 @@ +; $Id: ASMCpuIdExSlow.asm $ +;; @file +; IPRT - ASMCpuIdExSlow(). +; + +; +; Copyright (C) 2012-2023 Oracle and/or its affiliates. +; +; This file is part of VirtualBox base platform packages, as +; available from https://www.virtualbox.org. +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; as published by the Free Software Foundation, in version 3 of the +; License. +; +; This program is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, see <https://www.gnu.org/licenses>. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included +; in the VirtualBox distribution, in which case the provisions of the +; CDDL are applicable instead of those of the GPL. +; +; You may elect to license modified versions of this file under the +; terms and conditions of either the GPL or the CDDL or both. +; +; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 +; + +;******************************************************************************* +;* 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 +; +RT_BEGINPROC 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..5ddb47de --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMCpuId_Idx_ECX.asm @@ -0,0 +1,126 @@ +; $Id: ASMCpuId_Idx_ECX.asm $ +;; @file +; IPRT - ASMCpuId_Idx_ECX(). +; + +; +; Copyright (C) 2012-2023 Oracle and/or its affiliates. +; +; This file is part of VirtualBox base platform packages, as +; available from https://www.virtualbox.org. +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; as published by the Free Software Foundation, in version 3 of the +; License. +; +; This program is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, see <https://www.gnu.org/licenses>. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included +; in the VirtualBox distribution, in which case the provisions of the +; CDDL are applicable instead of those of the GPL. +; +; You may elect to license modified versions of this file under the +; terms and conditions of either the GPL or the CDDL or both. +; +; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 +; + +;******************************************************************************* +;* 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 +; +RT_BEGINPROC 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..cb492048 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMFxRstor.asm @@ -0,0 +1,74 @@ +; $Id: ASMFxRstor.asm $ +;; @file +; IPRT - ASMFxRstor(). +; + +; +; Copyright (C) 2006-2023 Oracle and/or its affiliates. +; +; This file is part of VirtualBox base platform packages, as +; available from https://www.virtualbox.org. +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; as published by the Free Software Foundation, in version 3 of the +; License. +; +; This program is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, see <https://www.gnu.org/licenses>. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included +; in the VirtualBox distribution, in which case the provisions of the +; CDDL are applicable instead of those of the GPL. +; +; You may elect to license modified versions of this file under the +; terms and conditions of either the GPL or the CDDL or both. +; +; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 +; + +;******************************************************************************* +;* 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] +; +RT_BEGINPROC 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..e2298ed8 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMFxSave.asm @@ -0,0 +1,74 @@ +; $Id: ASMFxSave.asm $ +;; @file +; IPRT - ASMFxSave(). +; + +; +; Copyright (C) 2006-2023 Oracle and/or its affiliates. +; +; This file is part of VirtualBox base platform packages, as +; available from https://www.virtualbox.org. +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; as published by the Free Software Foundation, in version 3 of the +; License. +; +; This program is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, see <https://www.gnu.org/licenses>. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included +; in the VirtualBox distribution, in which case the provisions of the +; CDDL are applicable instead of those of the GPL. +; +; You may elect to license modified versions of this file under the +; terms and conditions of either the GPL or the CDDL or both. +; +; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 +; + +;******************************************************************************* +;* 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] +; +RT_BEGINPROC 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/ASMGetFSBase.asm b/src/VBox/Runtime/common/asm/ASMGetFSBase.asm new file mode 100644 index 00000000..e565fc2a --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMGetFSBase.asm @@ -0,0 +1,54 @@ +; $Id: ASMGetFSBase.asm $ +;; @file +; IPRT - ASMGetFSBase(). +; + +; +; Copyright (C) 2006-2023 Oracle and/or its affiliates. +; +; This file is part of VirtualBox base platform packages, as +; available from https://www.virtualbox.org. +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; as published by the Free Software Foundation, in version 3 of the +; License. +; +; This program is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, see <https://www.gnu.org/licenses>. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included +; in the VirtualBox distribution, in which case the provisions of the +; CDDL are applicable instead of those of the GPL. +; +; You may elect to license modified versions of this file under the +; terms and conditions of either the GPL or the CDDL or both. +; +; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 +; + +;******************************************************************************* +;* Header Files * +;******************************************************************************* +%define RT_ASM_WITH_SEH64 +%include "iprt/asmdefs.mac" + +BEGINCODE + +;; +; Get the FS base register. +; @returns FS base +; +RT_BEGINPROC ASMGetFSBase + SEH64_END_PROLOGUE + rdfsbase rax + ret +ENDPROC ASMGetFSBase + diff --git a/src/VBox/Runtime/common/asm/ASMGetFlags.asm b/src/VBox/Runtime/common/asm/ASMGetFlags.asm new file mode 100644 index 00000000..1db37859 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMGetFlags.asm @@ -0,0 +1,53 @@ +; $Id: ASMGetFlags.asm $ +;; @file +; IPRT - ASMGetFlags(). +; + +; +; Copyright (C) 2006-2023 Oracle and/or its affiliates. +; +; This file is part of VirtualBox base platform packages, as +; available from https://www.virtualbox.org. +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; as published by the Free Software Foundation, in version 3 of the +; License. +; +; This program is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, see <https://www.gnu.org/licenses>. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included +; in the VirtualBox distribution, in which case the provisions of the +; CDDL are applicable instead of those of the GPL. +; +; You may elect to license modified versions of this file under the +; terms and conditions of either the GPL or the CDDL or both. +; +; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 +; + +;******************************************************************************* +;* Header Files * +;******************************************************************************* +%include "iprt/asmdefs.mac" + +BEGINCODE + +RT_BEGINPROC 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..30593f9f --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMGetGDTR.asm @@ -0,0 +1,62 @@ +; $Id: ASMGetGDTR.asm $ +;; @file +; IPRT - ASMGetGDTR(). +; + +; +; Copyright (C) 2006-2023 Oracle and/or its affiliates. +; +; This file is part of VirtualBox base platform packages, as +; available from https://www.virtualbox.org. +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; as published by the Free Software Foundation, in version 3 of the +; License. +; +; This program is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, see <https://www.gnu.org/licenses>. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included +; in the VirtualBox distribution, in which case the provisions of the +; CDDL are applicable instead of those of the GPL. +; +; You may elect to license modified versions of this file under the +; terms and conditions of either the GPL or the CDDL or both. +; +; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 +; + +;******************************************************************************* +;* 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] +; +RT_BEGINPROC 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/ASMGetGSBase.asm b/src/VBox/Runtime/common/asm/ASMGetGSBase.asm new file mode 100644 index 00000000..79080c92 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMGetGSBase.asm @@ -0,0 +1,54 @@ +; $Id: ASMGetGSBase.asm $ +;; @file +; IPRT - ASMGetGSBase(). +; + +; +; Copyright (C) 2006-2023 Oracle and/or its affiliates. +; +; This file is part of VirtualBox base platform packages, as +; available from https://www.virtualbox.org. +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; as published by the Free Software Foundation, in version 3 of the +; License. +; +; This program is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, see <https://www.gnu.org/licenses>. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included +; in the VirtualBox distribution, in which case the provisions of the +; CDDL are applicable instead of those of the GPL. +; +; You may elect to license modified versions of this file under the +; terms and conditions of either the GPL or the CDDL or both. +; +; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 +; + +;******************************************************************************* +;* Header Files * +;******************************************************************************* +%define RT_ASM_WITH_SEH64 +%include "iprt/asmdefs.mac" + +BEGINCODE + +;; +; Get the GS base register. +; @returns GS base +; +RT_BEGINPROC ASMGetGSBase + SEH64_END_PROLOGUE + rdgsbase rax + ret +ENDPROC ASMGetGSBase + diff --git a/src/VBox/Runtime/common/asm/ASMGetIDTR.asm b/src/VBox/Runtime/common/asm/ASMGetIDTR.asm new file mode 100644 index 00000000..0c3618b8 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMGetIDTR.asm @@ -0,0 +1,62 @@ +; $Id: ASMGetIDTR.asm $ +;; @file +; IPRT - ASMGetIDTR(). +; + +; +; Copyright (C) 2006-2023 Oracle and/or its affiliates. +; +; This file is part of VirtualBox base platform packages, as +; available from https://www.virtualbox.org. +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; as published by the Free Software Foundation, in version 3 of the +; License. +; +; This program is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, see <https://www.gnu.org/licenses>. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included +; in the VirtualBox distribution, in which case the provisions of the +; CDDL are applicable instead of those of the GPL. +; +; You may elect to license modified versions of this file under the +; terms and conditions of either the GPL or the CDDL or both. +; +; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 +; + +;******************************************************************************* +;* 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] +; +RT_BEGINPROC 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..7f4fb55e --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMGetIdtrLimit.asm @@ -0,0 +1,58 @@ +; $Id: ASMGetIdtrLimit.asm $ +;; @file +; IPRT - ASMGetIdtrLimit(). +; + +; +; Copyright (C) 2006-2023 Oracle and/or its affiliates. +; +; This file is part of VirtualBox base platform packages, as +; available from https://www.virtualbox.org. +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; as published by the Free Software Foundation, in version 3 of the +; License. +; +; This program is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, see <https://www.gnu.org/licenses>. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included +; in the VirtualBox distribution, in which case the provisions of the +; CDDL are applicable instead of those of the GPL. +; +; You may elect to license modified versions of this file under the +; terms and conditions of either the GPL or the CDDL or both. +; +; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 +; + +;******************************************************************************* +;* 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 +; +RT_BEGINPROC 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..f1dff4f9 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMGetLDTR.asm @@ -0,0 +1,53 @@ +; $Id: ASMGetLDTR.asm $ +;; @file +; IPRT - ASMGetLDTR(). +; + +; +; Copyright (C) 2006-2023 Oracle and/or its affiliates. +; +; This file is part of VirtualBox base platform packages, as +; available from https://www.virtualbox.org. +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; as published by the Free Software Foundation, in version 3 of the +; License. +; +; This program is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, see <https://www.gnu.org/licenses>. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included +; in the VirtualBox distribution, in which case the provisions of the +; CDDL are applicable instead of those of the GPL. +; +; You may elect to license modified versions of this file under the +; terms and conditions of either the GPL or the CDDL or both. +; +; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 +; + +;******************************************************************************* +;* Header Files * +;******************************************************************************* +%include "iprt/asmdefs.mac" + +BEGINCODE + +;; +; Get the LDTR register. +; @returns LDTR. +; +RT_BEGINPROC 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..bc8dfbef --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMGetSegAttr.asm @@ -0,0 +1,71 @@ +; $Id: ASMGetSegAttr.asm $ +;; @file +; IPRT - ASMGetSegAttr(). +; + +; +; Copyright (C) 2013-2023 Oracle and/or its affiliates. +; +; This file is part of VirtualBox base platform packages, as +; available from https://www.virtualbox.org. +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; as published by the Free Software Foundation, in version 3 of the +; License. +; +; This program is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, see <https://www.gnu.org/licenses>. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included +; in the VirtualBox distribution, in which case the provisions of the +; CDDL are applicable instead of those of the GPL. +; +; You may elect to license modified versions of this file under the +; terms and conditions of either the GPL or the CDDL or both. +; +; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 +; + +;******************************************************************************* +;* 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). +; +RT_BEGINPROC 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..e10933f8 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMGetTR.asm @@ -0,0 +1,53 @@ +; $Id: ASMGetTR.asm $ +;; @file +; IPRT - ASMGetTR(). +; + +; +; Copyright (C) 2006-2023 Oracle and/or its affiliates. +; +; This file is part of VirtualBox base platform packages, as +; available from https://www.virtualbox.org. +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; as published by the Free Software Foundation, in version 3 of the +; License. +; +; This program is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, see <https://www.gnu.org/licenses>. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included +; in the VirtualBox distribution, in which case the provisions of the +; CDDL are applicable instead of those of the GPL. +; +; You may elect to license modified versions of this file under the +; terms and conditions of either the GPL or the CDDL or both. +; +; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 +; + +;******************************************************************************* +;* Header Files * +;******************************************************************************* +%include "iprt/asmdefs.mac" + +BEGINCODE + +;; +; Get the TR register. +; @returns TR. +; +RT_BEGINPROC 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..0da411b9 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMGetXcr0.asm @@ -0,0 +1,66 @@ +; $Id: ASMGetXcr0.asm $ +;; @file +; IPRT - ASMGetXcr0(). +; + +; +; Copyright (C) 2006-2023 Oracle and/or its affiliates. +; +; This file is part of VirtualBox base platform packages, as +; available from https://www.virtualbox.org. +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; as published by the Free Software Foundation, in version 3 of the +; License. +; +; This program is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, see <https://www.gnu.org/licenses>. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included +; in the VirtualBox distribution, in which case the provisions of the +; CDDL are applicable instead of those of the GPL. +; +; You may elect to license modified versions of this file under the +; terms and conditions of either the GPL or the CDDL or both. +; +; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 +; + +;******************************************************************************* +;* 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). +; +RT_BEGINPROC 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/ASMMemFill32-generic.cpp b/src/VBox/Runtime/common/asm/ASMMemFill32-generic.cpp new file mode 100644 index 00000000..ecb01ab3 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMMemFill32-generic.cpp @@ -0,0 +1,74 @@ +/* $Id: ASMMemFill32-generic.cpp $ */ +/** @file + * IPRT - ASMMemZeroPage - generic C implementation. + */ + +/* + * Copyright (C) 2021-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + + +/********************************************************************************************************************************* +* Header Files * +*********************************************************************************************************************************/ +#include <iprt/asm.h> +#include "internal/iprt.h" + +#include <iprt/string.h> +#include <iprt/assert.h> + + +RTDECL(void) ASMMemFill32(volatile void RT_FAR *pv, size_t cb, uint32_t u32) RT_NOTHROW_DEF +{ + Assert(!(cb & 3)); + size_t cFills = cb / sizeof(uint32_t); + uint32_t *pu32Dst = (uint32_t *)pv; + + while (cFills >= 8) + { + pu32Dst[0] = u32; + pu32Dst[1] = u32; + pu32Dst[2] = u32; + pu32Dst[3] = u32; + pu32Dst[4] = u32; + pu32Dst[5] = u32; + pu32Dst[6] = u32; + pu32Dst[7] = u32; + pu32Dst += 8; + cFills -= 8; + } + + while (cFills > 0) + { + *pu32Dst++ = u32; + cFills -= 1; + } +} + diff --git a/src/VBox/Runtime/common/asm/ASMMemFirstMismatchingU8-generic.cpp b/src/VBox/Runtime/common/asm/ASMMemFirstMismatchingU8-generic.cpp new file mode 100644 index 00000000..d9cfe5e0 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMMemFirstMismatchingU8-generic.cpp @@ -0,0 +1,55 @@ +/* $Id: ASMMemFirstMismatchingU8-generic.cpp $ */ +/** @file + * IPRT - ASMMemFirstMismatchingU8 - generic C implementation. + */ + +/* + * Copyright (C) 2006-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + + +/********************************************************************************************************************************* +* Header Files * +*********************************************************************************************************************************/ +#include <iprt/asm.h> +#include "internal/iprt.h" + + +RTDECL(void *) ASMMemFirstMismatchingU8(void const RT_FAR *pv, size_t cb, uint8_t u8) RT_NOTHROW_DEF +{ + uint8_t const *pb = (uint8_t const RT_FAR *)pv; + for (; cb; cb--, pb++) + if (RT_LIKELY(*pb == u8)) + { /* likely */ } + else + return (void *)pb; + return NULL; +} + diff --git a/src/VBox/Runtime/common/asm/ASMMemFirstMismatchingU8.asm b/src/VBox/Runtime/common/asm/ASMMemFirstMismatchingU8.asm new file mode 100644 index 00000000..39db08ce --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMMemFirstMismatchingU8.asm @@ -0,0 +1,355 @@ +; $Id: ASMMemFirstMismatchingU8.asm $ +;; @file +; IPRT - ASMMemFirstMismatchingU8(). +; + +; +; Copyright (C) 2006-2023 Oracle and/or its affiliates. +; +; This file is part of VirtualBox base platform packages, as +; available from https://www.virtualbox.org. +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; as published by the Free Software Foundation, in version 3 of the +; License. +; +; This program is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, see <https://www.gnu.org/licenses>. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included +; in the VirtualBox distribution, in which case the provisions of the +; CDDL are applicable instead of those of the GPL. +; +; You may elect to license modified versions of this file under the +; terms and conditions of either the GPL or the CDDL or both. +; +; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 +; + + +;******************************************************************************* +;* 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. +; +RT_BEGINPROC 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) +; +RT_BEGINPROC 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/ASMMemFirstNonZero-generic.cpp b/src/VBox/Runtime/common/asm/ASMMemFirstNonZero-generic.cpp new file mode 100644 index 00000000..6cfd9fef --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMMemFirstNonZero-generic.cpp @@ -0,0 +1,85 @@ +/* $Id: ASMMemFirstNonZero-generic.cpp $ */ +/** @file + * IPRT - ASMMemZeroPage - generic C implementation. + */ + +/* + * Copyright (C) 2006-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + + +/********************************************************************************************************************************* +* Header Files * +*********************************************************************************************************************************/ +#include <iprt/asm.h> +#include "internal/iprt.h" + + +RTDECL(void RT_FAR *) ASMMemFirstNonZero(void const RT_FAR *pv, size_t cb) RT_NOTHROW_DEF +{ + uint8_t const *pb = (uint8_t const RT_FAR *)pv; + + /* + * If we've got a large buffer to search, do it in larger units. + */ + if (cb >= sizeof(size_t) * 2) + { + /* Align the pointer: */ + while ((uintptr_t)pb & (sizeof(size_t) - 1)) + { + if (RT_LIKELY(*pb == 0)) + { /* likely */ } + else + return (void RT_FAR *)pb; + cb--; + pb++; + } + + /* Scan in size_t sized words: */ + while ( cb >= sizeof(size_t) + && *(size_t *)pb == 0) + { + pb += sizeof(size_t); + cb -= sizeof(size_t); + } + } + + /* + * Search byte by byte. + */ + for (; cb; cb--, pb++) + if (RT_LIKELY(*pb == 0)) + { /* likely */ } + else + return (void RT_FAR *)pb; + + return NULL; +} + diff --git a/src/VBox/Runtime/common/asm/ASMMemZero32-generic.cpp b/src/VBox/Runtime/common/asm/ASMMemZero32-generic.cpp new file mode 100644 index 00000000..fa0163da --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMMemZero32-generic.cpp @@ -0,0 +1,51 @@ +/* $Id: ASMMemZero32-generic.cpp $ */ +/** @file + * IPRT - ASMMemZero32 - generic C implementation. + */ + +/* + * Copyright (C) 2021-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + + +/********************************************************************************************************************************* +* Header Files * +*********************************************************************************************************************************/ +#include <iprt/asm.h> +#include "internal/iprt.h" + +#include <iprt/string.h> + + +RTDECL(void) ASMMemZero32(volatile void RT_FAR *pv, size_t cb) RT_NOTHROW_DEF +{ + memset((void *)pv, 0, cb); +} + diff --git a/src/VBox/Runtime/common/asm/ASMMemZeroPage-generic.cpp b/src/VBox/Runtime/common/asm/ASMMemZeroPage-generic.cpp new file mode 100644 index 00000000..aee19ae7 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMMemZeroPage-generic.cpp @@ -0,0 +1,51 @@ +/* $Id: ASMMemZeroPage-generic.cpp $ */ +/** @file + * IPRT - ASMMemZeroPage - generic C implementation. + */ + +/* + * Copyright (C) 2021-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + + +/********************************************************************************************************************************* +* Header Files * +*********************************************************************************************************************************/ +#include <iprt/asm.h> +#include "internal/iprt.h" + +#include <iprt/string.h> + + +RTDECL(void) ASMMemZeroPage(volatile void RT_FAR *pv) RT_NOTHROW_DEF +{ + memset((void *)pv, 0, RT_ASM_PAGE_SIZE); +} + diff --git a/src/VBox/Runtime/common/asm/ASMMultU32ByU32DivByU32.asm b/src/VBox/Runtime/common/asm/ASMMultU32ByU32DivByU32.asm new file mode 100644 index 00000000..02d86145 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMMultU32ByU32DivByU32.asm @@ -0,0 +1,74 @@ +; $Id: ASMMultU32ByU32DivByU32.asm $ +;; @file +; IPRT - Assembly Functions, ASMMultU32ByU32DivByU32. +; + +; +; Copyright (C) 2006-2023 Oracle and/or its affiliates. +; +; This file is part of VirtualBox base platform packages, as +; available from https://www.virtualbox.org. +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; as published by the Free Software Foundation, in version 3 of the +; License. +; +; This program is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, see <https://www.gnu.org/licenses>. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included +; in the VirtualBox distribution, in which case the provisions of the +; CDDL are applicable instead of those of the GPL. +; +; You may elect to license modified versions of this file under the +; terms and conditions of either the GPL or the CDDL or both. +; +; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 +; + +%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); +; +RT_BEGINPROC 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-generic.cpp b/src/VBox/Runtime/common/asm/ASMMultU64ByU32DivByU32-generic.cpp new file mode 100644 index 00000000..c4aa23a1 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMMultU64ByU32DivByU32-generic.cpp @@ -0,0 +1,56 @@ +/* $Id: ASMMultU64ByU32DivByU32-generic.cpp $ */ +/** @file + * IPRT - ASMMultU64ByU32DivByU32 - generic C implementation. + */ + +/* + * Copyright (C) 2006-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + + +/********************************************************************************************************************************* +* Header Files * +*********************************************************************************************************************************/ +#include <iprt/asm-math.h> +#include "internal/iprt.h" + + + +RTDECL(uint64_t) ASMMultU64ByU32DivByU32(uint64_t u64A, uint32_t u32B, uint32_t u32C) +{ + RTUINT64U u; + uint64_t u64Lo = (uint64_t)(u64A & 0xffffffff) * u32B; + uint64_t u64Hi = (uint64_t)(u64A >> 32) * u32B; + u64Hi += (u64Lo >> 32); + u.s.Hi = (uint32_t)(u64Hi / u32C); + u.s.Lo = (uint32_t)((((u64Hi % u32C) << 32) + (u64Lo & 0xffffffff)) / u32C); + return u.u; +} + diff --git a/src/VBox/Runtime/common/asm/ASMMultU64ByU32DivByU32.asm b/src/VBox/Runtime/common/asm/ASMMultU64ByU32DivByU32.asm new file mode 100644 index 00000000..bf2f284d --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMMultU64ByU32DivByU32.asm @@ -0,0 +1,141 @@ +; $Id: ASMMultU64ByU32DivByU32.asm $ +;; @file +; IPRT - Assembly Functions, ASMMultU64ByU32DivByU32. +; + +; +; Copyright (C) 2006-2023 Oracle and/or its affiliates. +; +; This file is part of VirtualBox base platform packages, as +; available from https://www.virtualbox.org. +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; as published by the Free Software Foundation, in version 3 of the +; License. +; +; This program is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, see <https://www.gnu.org/licenses>. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included +; in the VirtualBox distribution, in which case the provisions of the +; CDDL are applicable instead of those of the GPL. +; +; You may elect to license modified versions of this file under the +; terms and conditions of either the GPL or the CDDL or both. +; +; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 +; + +%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); +; +RT_BEGINPROC ASMMultU64ByU32DivByU32 +%if ARCH_BITS == 64 + + %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 ; 16 or 32 bit + ; + ; This implementation is converted from the GCC inline + ; version of the code. Nothing additional has been done + ; performance wise. + ; + %if ARCH_BITS == 16 + push bp + mov bp, sp + push eax ; push all return registers to preserve high value (paranoia) + push ebx + push ecx + push edx + %endif + push esi + push edi + + %if ARCH_BITS == 16 + %define u64A_Lo [bp + 4 + 04h] + %define u64A_Hi [bp + 4 + 08h] + %define u32B [bp + 4 + 0ch] + %define u32C [bp + 4 + 10h] + %else + %define u64A_Lo [esp + 04h + 08h] + %define u64A_Hi [esp + 08h + 08h] + %define u32B [esp + 0ch + 08h] + %define u32C [esp + 10h + 08h] + %endif + + ; 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 + %if ARCH_BITS == 16 + ; DX:CX:BX:AX, where DX holds bits 15:0, CX bits 31:16, BX bits 47:32, and AX bits 63:48. + mov ax, [bp - 4*4] ; dx = bits 15:0 + shr eax, 16 + mov ax, [bp - 3*4] ; cx = bits 31:16 + mov dx, [bp - 2*4] ; bx = bits 47:32 + shr edx, 16 + mov dx, [bp - 1*4] ; ax = bits 63:48 + pop edx + pop ecx + pop ebx + pop eax + leave + %endif +%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..f5264f6f --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMNopPause.asm @@ -0,0 +1,51 @@ +; $Id: ASMNopPause.asm $ +;; @file +; IPRT - ASMNopPause(). +; + +; +; Copyright (C) 2009-2023 Oracle and/or its affiliates. +; +; This file is part of VirtualBox base platform packages, as +; available from https://www.virtualbox.org. +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; as published by the Free Software Foundation, in version 3 of the +; License. +; +; This program is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, see <https://www.gnu.org/licenses>. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included +; in the VirtualBox distribution, in which case the provisions of the +; CDDL are applicable instead of those of the GPL. +; +; You may elect to license modified versions of this file under the +; terms and conditions of either the GPL or the CDDL or both. +; +; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 +; + +;******************************************************************************* +;* Header Files * +;******************************************************************************* +%include "iprt/asmdefs.mac" + +BEGINCODE + +;; +; The PAUSE variant of NOP for helping hyperthreaded CPUs detecting spin locks. +; +RT_BEGINPROC 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..441dd21f --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMRdMsrEx.asm @@ -0,0 +1,94 @@ +; $Id: ASMRdMsrEx.asm $ +;; @file +; IPRT - ASMRdMsrEx(). +; + +; +; Copyright (C) 2013-2023 Oracle and/or its affiliates. +; +; This file is part of VirtualBox base platform packages, as +; available from https://www.virtualbox.org. +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; as published by the Free Software Foundation, in version 3 of the +; License. +; +; This program is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, see <https://www.gnu.org/licenses>. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included +; in the VirtualBox distribution, in which case the provisions of the +; CDDL are applicable instead of those of the GPL. +; +; You may elect to license modified versions of this file under the +; terms and conditions of either the GPL or the CDDL or both. +; +; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 +; + +;******************************************************************************* +;* 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. +; +RT_BEGINPROC 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, [ebp + 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..f9825935 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMSerializeInstruction-cpuid.asm @@ -0,0 +1,59 @@ +; $Id: ASMSerializeInstruction-cpuid.asm $ +;; @file +; IPRT - ASMSerializeInstruction() using cpuid. +; + +; +; Copyright (C) 2006-2023 Oracle and/or its affiliates. +; +; This file is part of VirtualBox base platform packages, as +; available from https://www.virtualbox.org. +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; as published by the Free Software Foundation, in version 3 of the +; License. +; +; This program is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, see <https://www.gnu.org/licenses>. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included +; in the VirtualBox distribution, in which case the provisions of the +; CDDL are applicable instead of those of the GPL. +; +; You may elect to license modified versions of this file under the +; terms and conditions of either the GPL or the CDDL or both. +; +; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 +; + + +;******************************************************************************* +;* Header Files * +;******************************************************************************* +%include "iprt/asmdefs.mac" + +BEGINCODE + + +;; +; Executes a serializing instruction. +; +; The CPUID instruction isn't fast or slow, but it always triggers a VM EXIT in +; a virtualized environment, which is prohibitively expensive. +; +RT_BEGINPROC 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..8e1a68ab --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMSerializeInstruction-iret.asm @@ -0,0 +1,71 @@ +; $Id: ASMSerializeInstruction-iret.asm $ +;; @file +; IPRT - ASMSerializeInstruction() using iret. +; + +; +; Copyright (C) 2006-2023 Oracle and/or its affiliates. +; +; This file is part of VirtualBox base platform packages, as +; available from https://www.virtualbox.org. +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; as published by the Free Software Foundation, in version 3 of the +; License. +; +; This program is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, see <https://www.gnu.org/licenses>. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included +; in the VirtualBox distribution, in which case the provisions of the +; CDDL are applicable instead of those of the GPL. +; +; You may elect to license modified versions of this file under the +; terms and conditions of either the GPL or the CDDL or both. +; +; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 +; + + +;******************************************************************************* +;* Header Files * +;******************************************************************************* +%include "iprt/asmdefs.mac" + +BEGINCODE + + +;; +; Executes a serializing 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. +; +RT_BEGINPROC 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..0ff481ab --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMSerializeInstruction-rdtscp.asm @@ -0,0 +1,56 @@ +; $Id: ASMSerializeInstruction-rdtscp.asm $ +;; @file +; IPRT - ASMSerializeInstruction() using rdtscp. +; + +; +; Copyright (C) 2006-2023 Oracle and/or its affiliates. +; +; This file is part of VirtualBox base platform packages, as +; available from https://www.virtualbox.org. +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; as published by the Free Software Foundation, in version 3 of the +; License. +; +; This program is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, see <https://www.gnu.org/licenses>. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included +; in the VirtualBox distribution, in which case the provisions of the +; CDDL are applicable instead of those of the GPL. +; +; You may elect to license modified versions of this file under the +; terms and conditions of either the GPL or the CDDL or both. +; +; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 +; + + +;******************************************************************************* +;* Header Files * +;******************************************************************************* +%include "iprt/asmdefs.mac" + +BEGINCODE + + +;; +; Executes a serializing 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. +; +RT_BEGINPROC ASMSerializeInstructionRdTscp + rdtscp + ret +ENDPROC ASMSerializeInstructionRdTscp + diff --git a/src/VBox/Runtime/common/asm/ASMSetFSBase.asm b/src/VBox/Runtime/common/asm/ASMSetFSBase.asm new file mode 100644 index 00000000..ef324132 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMSetFSBase.asm @@ -0,0 +1,58 @@ +; $Id: ASMSetFSBase.asm $ +;; @file +; IPRT - ASMSetFSBase(). +; + +; +; Copyright (C) 2006-2023 Oracle and/or its affiliates. +; +; This file is part of VirtualBox base platform packages, as +; available from https://www.virtualbox.org. +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; as published by the Free Software Foundation, in version 3 of the +; License. +; +; This program is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, see <https://www.gnu.org/licenses>. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included +; in the VirtualBox distribution, in which case the provisions of the +; CDDL are applicable instead of those of the GPL. +; +; You may elect to license modified versions of this file under the +; terms and conditions of either the GPL or the CDDL or both. +; +; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 +; + +;******************************************************************************* +;* Header Files * +;******************************************************************************* +%define RT_ASM_WITH_SEH64 +%include "iprt/asmdefs.mac" + +BEGINCODE + +;; +; Set the FS base register. +; @param uNewBase msc:rcx gcc:rdi New FS base value. +; +RT_BEGINPROC ASMSetFSBase + SEH64_END_PROLOGUE +%ifdef ASM_CALL64_MSC + wrfsbase rcx +%else + wrfsbase rdi +%endif + ret +ENDPROC ASMSetFSBase + diff --git a/src/VBox/Runtime/common/asm/ASMSetFlags.asm b/src/VBox/Runtime/common/asm/ASMSetFlags.asm new file mode 100644 index 00000000..112f21ea --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMSetFlags.asm @@ -0,0 +1,69 @@ +; $Id: ASMSetFlags.asm $ +;; @file +; IPRT - ASMSetFlags(). +; + +; +; Copyright (C) 2006-2023 Oracle and/or its affiliates. +; +; This file is part of VirtualBox base platform packages, as +; available from https://www.virtualbox.org. +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; as published by the Free Software Foundation, in version 3 of the +; License. +; +; This program is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, see <https://www.gnu.org/licenses>. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included +; in the VirtualBox distribution, in which case the provisions of the +; CDDL are applicable instead of those of the GPL. +; +; You may elect to license modified versions of this file under the +; terms and conditions of either the GPL or the CDDL or both. +; +; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 +; + + +;******************************************************************************* +;* Header Files * +;******************************************************************************* +%include "iprt/asmdefs.mac" + +BEGINCODE + +;; +; @param rcx eflags +RT_BEGINPROC 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..8817d9c6 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMSetGDTR.asm @@ -0,0 +1,62 @@ +; $Id: ASMSetGDTR.asm $ +;; @file +; IPRT - ASMSetGDTR(). +; + +; +; Copyright (C) 2006-2023 Oracle and/or its affiliates. +; +; This file is part of VirtualBox base platform packages, as +; available from https://www.virtualbox.org. +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; as published by the Free Software Foundation, in version 3 of the +; License. +; +; This program is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, see <https://www.gnu.org/licenses>. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included +; in the VirtualBox distribution, in which case the provisions of the +; CDDL are applicable instead of those of the GPL. +; +; You may elect to license modified versions of this file under the +; terms and conditions of either the GPL or the CDDL or both. +; +; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 +; + +;******************************************************************************* +;* 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] +; +RT_BEGINPROC 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/ASMSetGSBase.asm b/src/VBox/Runtime/common/asm/ASMSetGSBase.asm new file mode 100644 index 00000000..cd5a77a7 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMSetGSBase.asm @@ -0,0 +1,58 @@ +; $Id: ASMSetGSBase.asm $ +;; @file +; IPRT - ASMSetGSBase(). +; + +; +; Copyright (C) 2006-2023 Oracle and/or its affiliates. +; +; This file is part of VirtualBox base platform packages, as +; available from https://www.virtualbox.org. +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; as published by the Free Software Foundation, in version 3 of the +; License. +; +; This program is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, see <https://www.gnu.org/licenses>. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included +; in the VirtualBox distribution, in which case the provisions of the +; CDDL are applicable instead of those of the GPL. +; +; You may elect to license modified versions of this file under the +; terms and conditions of either the GPL or the CDDL or both. +; +; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 +; + +;******************************************************************************* +;* Header Files * +;******************************************************************************* +%define RT_ASM_WITH_SEH64 +%include "iprt/asmdefs.mac" + +BEGINCODE + +;; +; Set the GS base register. +; @param uNewBase msc:rcx gcc:rdi New GS base value. +; +RT_BEGINPROC ASMSetGSBase + SEH64_END_PROLOGUE +%ifdef ASM_CALL64_MSC + wrgsbase rcx +%else + wrgsbase rdi +%endif + ret +ENDPROC ASMSetGSBase + diff --git a/src/VBox/Runtime/common/asm/ASMSetIDTR.asm b/src/VBox/Runtime/common/asm/ASMSetIDTR.asm new file mode 100644 index 00000000..be334905 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMSetIDTR.asm @@ -0,0 +1,62 @@ +; $Id: ASMSetIDTR.asm $ +;; @file +; IPRT - ASMSetIDTR(). +; + +; +; Copyright (C) 2006-2023 Oracle and/or its affiliates. +; +; This file is part of VirtualBox base platform packages, as +; available from https://www.virtualbox.org. +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; as published by the Free Software Foundation, in version 3 of the +; License. +; +; This program is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, see <https://www.gnu.org/licenses>. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included +; in the VirtualBox distribution, in which case the provisions of the +; CDDL are applicable instead of those of the GPL. +; +; You may elect to license modified versions of this file under the +; terms and conditions of either the GPL or the CDDL or both. +; +; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 +; + +;******************************************************************************* +;* 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] +; +RT_BEGINPROC 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..831cf351 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMSetXcr0.asm @@ -0,0 +1,80 @@ +; $Id: ASMSetXcr0.asm $ +;; @file +; IPRT - ASMSetXcr0(). +; + +; +; Copyright (C) 2006-2023 Oracle and/or its affiliates. +; +; This file is part of VirtualBox base platform packages, as +; available from https://www.virtualbox.org. +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; as published by the Free Software Foundation, in version 3 of the +; License. +; +; This program is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, see <https://www.gnu.org/licenses>. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included +; in the VirtualBox distribution, in which case the provisions of the +; CDDL are applicable instead of those of the GPL. +; +; You may elect to license modified versions of this file under the +; terms and conditions of either the GPL or the CDDL or both. +; +; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 +; + +;******************************************************************************* +;* 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] +; +RT_BEGINPROC 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/ASMWrMsr.asm b/src/VBox/Runtime/common/asm/ASMWrMsr.asm new file mode 100644 index 00000000..6e144d40 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMWrMsr.asm @@ -0,0 +1,99 @@ +; $Id: ASMWrMsr.asm $ +;; @file +; IPRT - ASMWrMsr(). +; + +; +; Copyright (C) 2013-2023 Oracle and/or its affiliates. +; +; This file is part of VirtualBox base platform packages, as +; available from https://www.virtualbox.org. +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; as published by the Free Software Foundation, in version 3 of the +; License. +; +; This program is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, see <https://www.gnu.org/licenses>. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included +; in the VirtualBox distribution, in which case the provisions of the +; CDDL are applicable instead of those of the GPL. +; +; You may elect to license modified versions of this file under the +; terms and conditions of either the GPL or the CDDL or both. +; +; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 +; + +;******************************************************************************* +;* 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 uValue msc=rdx, gcc=rsi, x86=[ebp+12] The 64-bit value to write. +; +RT_BEGINPROC ASMWrMsr +%ifdef ASM_CALL64_MSC + mov rdi, rdx + mov eax, edx + shr rdx, 32 + wrmsr + ret + +%elifdef ASM_CALL64_GCC + mov ecx, edi + mov eax, esi + mov rdx, rsi + shr edx, 32 + wrmsr + ret + +%elif ARCH_BITS == 32 + push ebp + mov ebp, esp + push edi + mov ecx, [ebp + 8] + mov eax, [ebp + 12] + mov edx, [ebp + 16] + wrmsr + pop edi + leave + ret + +%elif ARCH_BITS == 16 + push bp + mov bp, sp + push eax + push ecx + push edx + + mov ecx, [bp + 04h] + mov eax, [bp + 08h] + mov edx, [bp + 0ch] + wrmsr + + pop edx + pop ecx + pop eax + leave + ret +%else + %error "Undefined arch?" +%endif +ENDPROC ASMWrMsr + diff --git a/src/VBox/Runtime/common/asm/ASMWrMsrEx.asm b/src/VBox/Runtime/common/asm/ASMWrMsrEx.asm new file mode 100644 index 00000000..1c14f32f --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMWrMsrEx.asm @@ -0,0 +1,89 @@ +; $Id: ASMWrMsrEx.asm $ +;; @file +; IPRT - ASMWrMsrEx(). +; + +; +; Copyright (C) 2013-2023 Oracle and/or its affiliates. +; +; This file is part of VirtualBox base platform packages, as +; available from https://www.virtualbox.org. +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; as published by the Free Software Foundation, in version 3 of the +; License. +; +; This program is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, see <https://www.gnu.org/licenses>. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included +; in the VirtualBox distribution, in which case the provisions of the +; CDDL are applicable instead of those of the GPL. +; +; You may elect to license modified versions of this file under the +; terms and conditions of either the GPL or the CDDL or both. +; +; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 +; + +;******************************************************************************* +;* 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. +; +RT_BEGINPROC 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, [ebp + 12] + mov eax, [ebp + 16] + mov edx, [ebp + 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..fd4ab564 --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMXRstor.asm @@ -0,0 +1,73 @@ +; $Id: ASMXRstor.asm $ +;; @file +; IPRT - ASMXRstor(). +; + +; +; Copyright (C) 2006-2023 Oracle and/or its affiliates. +; +; This file is part of VirtualBox base platform packages, as +; available from https://www.virtualbox.org. +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; as published by the Free Software Foundation, in version 3 of the +; License. +; +; This program is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, see <https://www.gnu.org/licenses>. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included +; in the VirtualBox distribution, in which case the provisions of the +; CDDL are applicable instead of those of the GPL. +; +; You may elect to license modified versions of this file under the +; terms and conditions of either the GPL or the CDDL or both. +; +; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 +; + +;******************************************************************************* +;* 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] +; +RT_BEGINPROC 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..ba262cbf --- /dev/null +++ b/src/VBox/Runtime/common/asm/ASMXSave.asm @@ -0,0 +1,73 @@ +; $Id: ASMXSave.asm $ +;; @file +; IPRT - ASMXSave(). +; + +; +; Copyright (C) 2006-2023 Oracle and/or its affiliates. +; +; This file is part of VirtualBox base platform packages, as +; available from https://www.virtualbox.org. +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; as published by the Free Software Foundation, in version 3 of the +; License. +; +; This program is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, see <https://www.gnu.org/licenses>. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included +; in the VirtualBox distribution, in which case the provisions of the +; CDDL are applicable instead of those of the GPL. +; +; You may elect to license modified versions of this file under the +; terms and conditions of either the GPL or the CDDL or both. +; +; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 +; + +;******************************************************************************* +;* 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] +; +RT_BEGINPROC 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..64f1f37e --- /dev/null +++ b/src/VBox/Runtime/common/asm/asm-fake.cpp @@ -0,0 +1,354 @@ +/* $Id: asm-fake.cpp $ */ +/** @file + * IPRT - Fake asm.h routines for use early in a new port. + */ + +/* + * Copyright (C) 2010-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + + +/********************************************************************************************************************************* +* 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(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(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)); +} + |