VirtualBox

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

Last change on this file since 79570 was 76553, checked in by vboxsync, 6 years ago

scm --update-copyright-year

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

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette