VirtualBox

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

Last change on this file since 62477 was 62477, checked in by vboxsync, 8 years ago

(C) 2016

  • 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 62477 2016-07-22 18:27:37Z vboxsync $
2;; @file
3; IPRT - ASMBitNextClear().
4;
5
6;
7; Copyright (C) 2006-2016 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] ; edx=iPrevBit
69%elif ARCH_BITS == 16
70 mov ax, [bp + 4 + 2]
71 mov es, ax
72 mov di, [bp + 4] ; es:di=pvBits
73 mov ecx, [bp + 4 + 8] ; edx=iPrevBit
74%endif
75
76 ;
77 ; If iPrevBit and iPrevBit + 1 are in the same dword, inspect it for further bits.
78 ;
79 inc ecx
80 mov eax, ecx
81 shr eax, 5
82 shl eax, 2 ; eax=byte offset into bitmap of current dword.
83 add xDI, xAX ; xDI=current dword address (of iPrevBit + 1).
84 and ecx, 31
85 jz .scan_dwords
86
87%if ARCH_BITS == 16
88 mov edx, [es:di]
89%else
90 mov edx, [xDI]
91%endif
92 not edx ; edx = inverted current dword
93 shr edx, cl ; Shift out bits that we have searched.
94 jz .next_dword ; If zero, nothing to find. Go rep scasd.
95 shl edx, cl ; Shift it back so bsf will return the right index.
96
97 bsf edx, edx ; edx=index of first clear bit
98
99 shl eax, 3 ; Turn eax back into a bit offset of the current dword.
100 add eax, edx ; eax=bit offset
101
102.return:
103 pop xDI
104%if ARCH_BITS == 16
105 mov edx, eax
106 shr edx, 16
107 leave
108%endif
109 ret
110
111 ;
112 ; Do dword scan.
113 ;
114
115 ; Skip empty dword.
116.next_dword:
117 add xDI, 4 ; Skip the empty dword.
118 add eax, 4
119
120.scan_dwords:
121 ; First load and align bit count.
122%if ARCH_BITS == 64
123 %ifdef ASM_CALL64_GCC
124 mov ecx, esi
125 %else
126 mov ecx, r8d
127 %endif
128%elif ARCH_BITS == 32
129 mov ecx, [esp + 8 + 4]
130%elif ARCH_BITS == 16
131 mov ecx, [bp + 4 + 4]
132%endif
133 add ecx, 31
134 shr ecx, 5 ; ecx=bitmap size in dwords.
135
136 ; Adjust ecx to how many dwords there are left to scan. (eax = current byte offset)
137 shr eax, 2 ; eax=current dword offset.
138 sub ecx, eax
139 jbe .return_failure
140
141 ; Do the scanning.
142 mov eax, 0ffffffffh
143 repe scasd
144 je .return_failure
145
146 ; Find the bit in question.
147 sub xDI, 4 ; One step back.
148%if ARCH_BITS == 16
149 movzx edi, di
150 xor eax, [es:xDI]
151%else
152 xor eax, [xDI]
153%endif
154 bsf eax, eax
155 jz .return_failure ; race paranoia
156
157 ; Calc the bit offset.
158%if ARCH_BITS == 16
159 sub di, [bp + 4]
160 movzx edi, di
161%elif ARCH_BITS == 32
162 sub xDI, [esp + 4]
163%elif ARCH_BITS == 64
164 sub xDI, r9
165%endif
166 shl edi, 3 ; edi=bit offset of current dword.
167 add eax, edi
168 jmp .return
169
170.return_failure:
171 mov eax, 0ffffffffh
172 jmp .return
173ENDPROC ASMBitNextClear
174
175
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