VirtualBox

source: vbox/trunk/src/VBox/Runtime/common/asm/ASMBitNextSet.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: ASMBitNextSet.asm 98103 2023-01-17 14:15:46Z vboxsync $
2;; @file
3; IPRT - ASMBitNextSet().
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 set 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 set 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 ASMBitNextSet
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] ; edx=iPrevBit
79%elif ARCH_BITS == 16
80 mov ax, [bp + 4 + 2]
81 mov es, ax
82 mov di, [bp + 4] ; es:di=pvBits
83 mov ecx, [bp + 4 + 8] ; edx=iPrevBit
84%endif
85
86 ;
87 ; If iPrevBit and iPrevBit + 1 are in the same dword, inspect it for further bits.
88 ;
89 inc ecx
90 mov eax, ecx
91 shr eax, 5
92 shl eax, 2 ; eax=byte offset into bitmap of current dword.
93 add xDI, xAX ; xDI=current dword address (of iPrevBit + 1).
94 and ecx, 31
95 jz .scan_dwords
96
97%if ARCH_BITS == 16
98 mov edx, [es:di] ; edx = current dword
99%else
100 mov edx, [xDI] ; edx = current dword
101%endif
102 shr edx, cl ; Shift out bits that we have searched.
103 jz .next_dword ; If zero, nothing to find. Go rep scasd.
104 shl edx, cl ; Shift it back so bsf will return the right index.
105
106 bsf edx, edx ; edx=index of first set bit
107
108 shl eax, 3 ; Turn eax back into a bit offset of the current dword.
109 add eax, edx ; eax=bit offset
110
111.return:
112 pop xDI
113%if ARCH_BITS == 16
114 mov edx, eax
115 shr edx, 16
116 leave
117%endif
118 ret
119
120 ;
121 ; Do dword scan.
122 ;
123
124 ; Skip empty dword.
125.next_dword:
126 add xDI, 4 ; Skip the empty dword.
127 add eax, 4
128
129.scan_dwords:
130 ; First load and align bit count.
131%if ARCH_BITS == 64
132 %ifdef ASM_CALL64_GCC
133 mov ecx, esi
134 %else
135 mov ecx, r8d
136 %endif
137%elif ARCH_BITS == 32
138 mov ecx, [esp + 8 + 4]
139%elif ARCH_BITS == 16
140 mov ecx, [bp + 4 + 4]
141%endif
142 add ecx, 31
143 shr ecx, 5 ; ecx=bitmap size in dwords.
144
145 ; Adjust ecx to how many dwords there are left to scan. (eax = current byte offset)
146 shr eax, 2 ; eax=current dword offset.
147 sub ecx, eax
148 jbe .return_failure
149
150 ; Do the scanning.
151 xor eax, eax
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 mov eax, [es:xDI]
160%else
161 mov 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 + 4]
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 ASMBitNextSet
183
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use