VirtualBox

source: vbox/trunk/src/VBox/Runtime/common/asm/ASMBitNextClear.asm

Last change on this file was 98103, checked in by vboxsync, 16 months ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 5.7 KB
Line 
1; $Id: ASMBitNextClear.asm 98103 2023-01-17 14:15:46Z vboxsync $
2;; @file
3; IPRT - ASMBitNextClear().
4;
5
6;
7; Copyright (C) 2006-2023 Oracle and/or its affiliates.
8;
9; This file is part of VirtualBox base platform packages, as
10; available from https://www.virtualbox.org.
11;
12; This program is free software; you can redistribute it and/or
13; modify it under the terms of the GNU General Public License
14; as published by the Free Software Foundation, in version 3 of the
15; License.
16;
17; This program is distributed in the hope that it will be useful, but
18; WITHOUT ANY WARRANTY; without even the implied warranty of
19; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20; General Public License for more details.
21;
22; You should have received a copy of the GNU General Public License
23; along with this program; if not, see <https://www.gnu.org/licenses>.
24;
25; The contents of this file may alternatively be used under the terms
26; of the Common Development and Distribution License Version 1.0
27; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
28; in the VirtualBox distribution, in which case the provisions of the
29; CDDL are applicable instead of those of the GPL.
30;
31; You may elect to license modified versions of this file under the
32; terms and conditions of either the GPL or the CDDL or both.
33;
34; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
35;
36
37
38;*******************************************************************************
39;* Header Files *
40;*******************************************************************************
41%include "iprt/asmdefs.mac"
42
43BEGINCODE
44
45;;
46; Finds the next clear bit in a bitmap.
47;
48; @returns (32/64:eax, 16:ax+dx) Index of the first zero bit.
49; @returns (32/64:eax, 16:ax+dx) -1 if no clear bit was found.
50; @param msc:rcx gcc:rdi pvBitmap Pointer to the bitmap.
51; @param msc:edx gcc:rsi cBits The number of bits in the bitmap. Multiple of 32.
52; @param msc:r8d gcc:rcx iBitPrev The previous bit, start searching after it.
53;
54; @remarks Not quite sure how much sense it makes to do this in assembly, but
55; it started out with the ASMBit* API, so that's why we still have it.
56;
57RT_BEGINPROC ASMBitNextClear
58%if ARCH_BITS == 16
59 push bp
60 mov bp, sp
61%endif
62 push xDI
63
64 ;
65 ; Align input registers: rdi=pvBitmap, ecx=iPrevBit
66 ;
67%if ARCH_BITS == 64
68 %ifdef ASM_CALL64_GCC
69 ; ecx = iBitPrev param, rdi=pvBitmap param.
70 %else
71 mov rdi, rcx ; rdi=pvBits
72 mov ecx, r8d ; ecx=iPrevBit
73 mov r8d, edx ; r8d=cBits (saved for .scan_dwords)
74 %endif
75 mov r9, rdi ; Save rdi for bit calculation.
76%elif ARCH_BITS == 32
77 mov edi, [esp + 8] ; edi=pvBits
78 mov ecx, [esp + 8 + 8] ; ecx=iPrevBit
79%elif ARCH_BITS == 16
80 les di, [bp + 4] ; es:di=pvBits
81 mov ecx, [bp + 4 + 8] ; ecx=iPrevBit
82%endif
83
84 ;
85 ; If iPrevBit and iPrevBit + 1 are in the same dword, inspect it for further bits.
86 ;
87 inc ecx
88 mov eax, ecx
89 shr eax, 5
90 shl eax, 2 ; eax=byte offset into bitmap of current dword.
91 add xDI, xAX ; xDI=current dword address (of iPrevBit + 1).
92 and ecx, 31
93 jz .scan_dwords
94
95%if ARCH_BITS == 16
96 mov edx, [es:di]
97%else
98 mov edx, [xDI]
99%endif
100 not edx ; edx = inverted current dword
101 shr edx, cl ; Shift out bits that we have searched.
102 jz .next_dword ; If zero, nothing to find. Go rep scasd.
103 shl edx, cl ; Shift it back so bsf will return the right index.
104
105 bsf edx, edx ; edx=index of first clear bit
106
107 shl eax, 3 ; Turn eax back into a bit offset of the current dword.
108 add eax, edx ; eax=bit offset
109
110.return:
111 pop xDI
112%if ARCH_BITS == 16
113 mov edx, eax
114 shr edx, 16
115 leave
116%endif
117 ret
118
119 ;
120 ; Do dword scan.
121 ;
122
123 ; Skip empty dword.
124.next_dword:
125 add xDI, 4 ; Skip the empty dword.
126 add eax, 4
127
128.scan_dwords:
129 ; First load and align bit count.
130%if ARCH_BITS == 64
131 %ifdef ASM_CALL64_GCC
132 mov ecx, esi
133 %else
134 mov ecx, r8d
135 %endif
136%elif ARCH_BITS == 32
137 mov ecx, [esp + 8 + 4]
138%elif ARCH_BITS == 16
139 mov ecx, [bp + 4 + 4]
140%endif
141 add ecx, 31
142 shr ecx, 5 ; ecx=bitmap size in dwords.
143
144 ; Adjust ecx to how many dwords there are left to scan. (eax = current byte offset)
145 shr eax, 2 ; eax=current dword offset.
146 sub ecx, eax
147 jbe .return_failure
148
149 ; Do the scanning.
150 cld
151 mov eax, 0ffffffffh
152 repe scasd
153 je .return_failure
154
155 ; Find the bit in question.
156 sub xDI, 4 ; One step back.
157%if ARCH_BITS == 16
158 movzx edi, di
159 xor eax, [es:xDI]
160%else
161 xor eax, [xDI]
162%endif
163 bsf eax, eax
164 jz .return_failure ; race paranoia
165
166 ; Calc the bit offset.
167%if ARCH_BITS == 16
168 sub di, [bp + 4]
169 movzx edi, di
170%elif ARCH_BITS == 32
171 sub xDI, [esp + 8]
172%elif ARCH_BITS == 64
173 sub xDI, r9
174%endif
175 shl edi, 3 ; edi=bit offset of current dword.
176 add eax, edi
177 jmp .return
178
179.return_failure:
180 mov eax, 0ffffffffh
181 jmp .return
182ENDPROC ASMBitNextClear
183
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use