00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00032 #include "common.h"
00033 #include "bitvector.h"
00034
00035
00036 void BitVectorPointer::Reset()
00037 {
00038 unsigned* bits = Bits;
00039 unsigned* bitsEnd = Bits+((Size+BitVectorIndexMask)>>BitVectorIndexShift);
00040 unsigned zero = 0;
00041 while(bits<bitsEnd)
00042 *bits++ = zero;
00043 }
00044
00045
00046 int BitVectorPointer::Test(unsigned index)
00047 {
00048 ASSERT_DEBUG(index<Size);
00049 return (Bits[index>>BitVectorIndexShift]>>(index&BitVectorIndexMask))&1;
00050 }
00051
00052
00053 void BitVectorPointer::Set(unsigned index)
00054 {
00055 ASSERT_DEBUG(index<Size);
00056 Bits[index>>BitVectorIndexShift] |= 1<<(index&BitVectorIndexMask);
00057 }
00058
00059
00060 void BitVectorPointer::Clear(unsigned index)
00061 {
00062 ASSERT_DEBUG(index<Size);
00063 Bits[index>>BitVectorIndexShift] &= ~(1<<(index&BitVectorIndexMask));
00064 }
00065
00066
00067 #if defined(__GNUC__) && defined(_ARM) // ARM assembler versions...
00068
00069
00070 #if defined(DEBUG) && !defined(LOCAL_ASSERTFAILED_DEFINED)
00071
00072 #define LOCAL_ASSERTFAILED_DEFINED
00073
00074 static int AssertFailed(int line)
00075 {
00076 return AssertFailed(__FILE__,line);
00077 }
00078
00079 #endif
00080
00081
00082 __attribute__((naked)) int BitVectorPointer::TestSet(unsigned , size_t )
00083 {
00084 #ifdef DEBUG
00085 asm("ldr r3, [r0, #%a0]" : : "i" (offsetof(BitVectorPointer,Size)));
00086 asm("add r12, r1, r2");
00087 asm("cmp r1, r3");
00088 asm("ldrhs r0, =%a0" : : "i" (__LINE__));
00089 asm("bhs %a0" : : "i" ((int(*)(int))AssertFailed));
00090 asm("cmp r12, r1");
00091 asm("ldrls r0, =%a0" : : "i" (__LINE__));
00092 asm("bls %a0" : : "i" ((int(*)(int))AssertFailed));
00093 asm("cmp r12, r3");
00094 asm("ldrhi r0, =%a0" : : "i" (__LINE__));
00095 asm("bhi %a0" : : "i" ((int(*)(int))AssertFailed));
00096 #endif
00097
00098 asm("ldr r12, [r0, #%a0]" : : "i" (offsetof(BitVectorPointer,Bits)));
00099 asm("mov r0, r1, lsr #5");
00100 asm("add r3, r12, r0, lsl #2");
00101 asm("and r0, r1, #31");
00102 asm("add r1, r1, r2");
00103 asm("sub r1, r1, #1");
00104 asm("mvn r2, #0");
00105 asm("mvn r2, r2, lsl r0");
00106
00107 asm("mvn r0, r1");
00108 asm("and r0, r0, #31");
00109 asm("mov r1, r1, lsr #5");
00110 asm("add r1, r12, r1, lsl #2");
00111 asm("mvn r12, #0");
00112 asm("mvn r12, r12, lsr r0");
00113
00114 asm("cmp r3, r1");
00115 asm("ldr r0, [r3], #4");
00116 asm("orreq r2, r2, r12");
00117 asm("orr r0, r0, r2");
00118 asm("beq 9f");
00119
00120 asm("cmp r3, r1");
00121 asm("0:");
00122 asm("ldrlo r2, [r3], #4");
00123 asm("andlo r0, r0, r2");
00124 asm("cmplo r3, r1");
00125 asm("blo 0b");
00126
00127 asm("ldr r2, [r3]");
00128 asm("orr r2, r2, r12");
00129 asm("and r0, r0, r2");
00130 asm("9:");
00131 asm("cmp r0, #0xffffffff");
00132 asm("moveq r0, #1");
00133 asm("movne r0, #0");
00134 asm("mov pc, lr");
00135 dummy_return(int);
00136 }
00137
00138
00139 __attribute__((naked)) int BitVectorPointer::TestClear(unsigned , size_t )
00140 {
00141 #ifdef DEBUG
00142 asm("ldr r3, [r0, #%a0]" : : "i" (offsetof(BitVectorPointer,Size)));
00143 asm("add r12, r1, r2");
00144 asm("cmp r1, r3");
00145 asm("ldrhs r0, =%a0" : : "i" (__LINE__));
00146 asm("bhs %a0" : : "i" ((int(*)(int))AssertFailed));
00147 asm("cmp r12, r1");
00148 asm("ldrlo r0, =%a0" : : "i" (__LINE__));
00149 asm("bls %a0" : : "i" ((int(*)(int))AssertFailed));
00150 asm("cmp r12, r3");
00151 asm("ldrhi r0, =%a0" : : "i" (__LINE__));
00152 asm("bhi %a0" : : "i" ((int(*)(int))AssertFailed));
00153 #endif
00154
00155 asm("ldr r12, [r0, #%a0]" : : "i" (offsetof(BitVectorPointer,Bits)));
00156 asm("mov r0, r1, lsr #5");
00157 asm("add r3, r12, r0, lsl #2");
00158 asm("and r0, r1, #31");
00159 asm("add r1, r1, r2");
00160 asm("sub r1, r1, #1");
00161 asm("mvn r2, #0");
00162 asm("mov r2, r2, lsl r0");
00163
00164 asm("mvn r0, r1");
00165 asm("and r0, r0, #31");
00166 asm("mov r1, r1, lsr #5");
00167 asm("add r1, r12, r1, lsl #2");
00168 asm("mvn r12, #0");
00169 asm("mov r12, r12, lsr r0");
00170
00171 asm("cmp r3, r1");
00172 asm("ldr r0, [r3], #4");
00173 asm("andeq r2, r2, r12");
00174 asm("and r0, r0, r2");
00175 asm("beq 9f");
00176
00177 asm("cmp r3, r1");
00178 asm("0:");
00179 asm("ldrlo r2, [r3], #4");
00180 asm("orrlo r0, r0, r2");
00181 asm("cmplo r3, r1");
00182 asm("blo 0b");
00183
00184 asm("ldr r2, [r3]");
00185 asm("and r2, r2, r12");
00186 asm("orr r0, r0, r2");
00187 asm("9:");
00188 asm("cmp r0, #0");
00189 asm("moveq r0, #1");
00190 asm("movne r0, #0");
00191 asm("mov pc, lr");
00192 dummy_return(int);
00193 }
00194
00195
00196 __attribute__((naked)) void BitVectorPointer::Set(unsigned , size_t )
00197 {
00198 #ifdef DEBUG
00199 asm("ldr r3, [r0, #%a0]" : : "i" (offsetof(BitVectorPointer,Size)));
00200 asm("add r12, r1, r2");
00201 asm("cmp r1, r3");
00202 asm("ldrhs r0, =%a0" : : "i" (__LINE__));
00203 asm("bhs %a0" : : "i" ((int(*)(int))AssertFailed));
00204 asm("cmp r12, r1");
00205 asm("ldrlo r0, =%a0" : : "i" (__LINE__));
00206 asm("blo %a0" : : "i" ((int(*)(int))AssertFailed));
00207 asm("cmp r12, r3");
00208 asm("ldrhi r0, =%a0" : : "i" (__LINE__));
00209 asm("bhi %a0" : : "i" ((int(*)(int))AssertFailed));
00210 #endif
00211 asm("cmp r2, #0");
00212 asm("moveq pc, lr");
00213
00214 asm("ldr r12, [r0, #%a0]" : : "i" (offsetof(BitVectorPointer,Bits)));
00215 asm("mov r0, r1, lsr #5");
00216 asm("add r3, r12, r0, lsl #2");
00217 asm("and r0, r1, #31");
00218 asm("add r1, r1, r2");
00219 asm("sub r1, r1, #1");
00220 asm("mvn r2, #0");
00221 asm("mov r2, r2, lsl r0");
00222
00223 asm("mvn r0, r1");
00224 asm("and r0, r0, #31");
00225 asm("mov r1, r1, lsr #5");
00226 asm("add r1, r12, r1, lsl #2");
00227 asm("mvn r12, #0");
00228 asm("mov r12, r12, lsr r0");
00229
00230 asm("ldr r0, [r3]");
00231 asm("cmp r3, r1");
00232 asm("andeq r2, r2, r12");
00233 asm("orr r0, r0, r2");
00234 asm("str r0, [r3], #4");
00235 asm("moveq pc, lr");
00236
00237 asm("mvn r0, #0");
00238 asm("cmp r3, r1");
00239 asm("0:");
00240 asm("strlo r0, [r3], #4");
00241 asm("cmplo r3, r1");
00242 asm("blo 0b");
00243
00244 asm("ldr r0, [r3]");
00245 asm("orr r0, r0, r12");
00246 asm("str r0, [r3]");
00247 asm("mov pc, lr");
00248 }
00249
00250
00251 __attribute__((naked)) void BitVectorPointer::Clear(unsigned , size_t )
00252 {
00253 #ifdef DEBUG
00254 asm("ldr r3, [r0, #%a0]" : : "i" (offsetof(BitVectorPointer,Size)));
00255 asm("add r12, r1, r2");
00256 asm("cmp r1, r3");
00257 asm("ldrhs r0, =%a0" : : "i" (__LINE__));
00258 asm("bhs %a0" : : "i" ((int(*)(int))AssertFailed));
00259 asm("cmp r12, r1");
00260 asm("ldrlo r0, =%a0" : : "i" (__LINE__));
00261 asm("blo %a0" : : "i" ((int(*)(int))AssertFailed));
00262 asm("cmp r12, r3");
00263 asm("ldrhi r0, =%a0" : : "i" (__LINE__));
00264 asm("bhi %a0" : : "i" ((int(*)(int))AssertFailed));
00265 #endif
00266 asm("cmp r2, #0");
00267 asm("moveq pc, lr");
00268
00269 asm("ldr r12, [r0, #%a0]" : : "i" (offsetof(BitVectorPointer,Bits)));
00270 asm("mov r0, r1, lsr #5");
00271 asm("add r3, r12, r0, lsl #2");
00272 asm("and r0, r1, #31");
00273 asm("add r1, r1, r2");
00274 asm("sub r1, r1, #1");
00275 asm("mvn r2, #0");
00276 asm("mov r2, r2, lsl r0");
00277
00278 asm("mvn r0, r1");
00279 asm("and r0, r0, #31");
00280 asm("mov r1, r1, lsr #5");
00281 asm("add r1, r12, r1, lsl #2");
00282 asm("mvn r12, #0");
00283 asm("mov r12, r12, lsr r0");
00284
00285 asm("ldr r0, [r3]");
00286 asm("cmp r3, r1");
00287 asm("andeq r2, r2, r12");
00288 asm("bic r0, r0, r2");
00289 asm("str r0, [r3], #4");
00290 asm("moveq pc, lr");
00291
00292 asm("mov r0, #0");
00293 asm("cmp r3, r1");
00294 asm("0:");
00295 asm("strlo r0, [r3], #4");
00296 asm("cmplo r3, r1");
00297 asm("blo 0b");
00298
00299 asm("ldr r0, [r3]");
00300 asm("bic r0, r0, r12");
00301 asm("str r0, [r3]");
00302 asm("mov pc, lr");
00303 }
00304
00305
00306 #else // C++ versions...
00307
00308
00309 int BitVectorPointer::TestSet(unsigned index, size_t count)
00310 {
00311 ASSERT_DEBUG(index<Size);
00312 ASSERT_DEBUG(index+count>index);
00313 ASSERT_DEBUG(index+count<=Size);
00314
00315 unsigned* ptr = Bits+(index>>BitVectorIndexShift);
00316 unsigned startMask = ~((~0u)<<(index&BitVectorIndexMask));
00317 index = index+count-1;
00318 unsigned* end = Bits+(index>>BitVectorIndexShift);
00319 unsigned endMask = ~((~0u)>>((~index)&BitVectorIndexMask));
00320
00321
00322
00323
00324
00325
00326
00327 unsigned result;
00328 if(ptr==end)
00329 {
00330 startMask |= endMask;
00331 result = *ptr|startMask;
00332 }
00333 else
00334 {
00335 result = *ptr++|startMask;
00336 while(ptr<end)
00337 result &= *ptr++;
00338 result &= *ptr|endMask;
00339 }
00340 return result==~0u;
00341 }
00342
00343
00344 int BitVectorPointer::TestClear(unsigned index, size_t count)
00345 {
00346 ASSERT_DEBUG(index<Size);
00347 ASSERT_DEBUG(index+count>index);
00348 ASSERT_DEBUG(index+count<=Size);
00349
00350 unsigned* ptr = Bits+(index>>BitVectorIndexShift);
00351 unsigned startMask = (~0u)<<(index&BitVectorIndexMask);
00352 index = index+count-1;
00353 unsigned* end = Bits+(index>>BitVectorIndexShift);
00354 unsigned endMask = (~0u)>>((~index)&BitVectorIndexMask);
00355
00356
00357
00358
00359
00360
00361
00362 unsigned result;
00363
00364 if(ptr==end)
00365 result = *ptr&startMask&endMask;
00366 else
00367 {
00368 result = *ptr++&startMask;
00369 while(ptr<end)
00370 result |= *ptr++;
00371 result |= *ptr&endMask;
00372 }
00373 return result==0;
00374 }
00375
00376
00377 void BitVectorPointer::Set(unsigned index, size_t count)
00378 {
00379 ASSERT_DEBUG(index<Size);
00380 ASSERT_DEBUG(index+count>=index);
00381 ASSERT_DEBUG(index+count<=Size);
00382
00383 if(!count)
00384 return;
00385
00386 unsigned* ptr = Bits+(index>>BitVectorIndexShift);
00387 unsigned startMask = (~0u)<<(index&BitVectorIndexMask);
00388 index = index+count-1;
00389 unsigned* end = Bits+(index>>BitVectorIndexShift);
00390 unsigned endMask = (~0u)>>((~index)&BitVectorIndexMask);
00391
00392
00393
00394
00395
00396
00397 if(ptr==end)
00398 {
00399 startMask &= endMask;
00400 *ptr |= startMask;
00401 }
00402 else
00403 {
00404 *ptr++ |= startMask;
00405 while(ptr<end)
00406 *ptr++ = ~0u;
00407 *ptr |= endMask;
00408 }
00409 }
00410
00411
00412 void BitVectorPointer::Clear(unsigned index, size_t count)
00413 {
00414 ASSERT_DEBUG(index<Size);
00415 ASSERT_DEBUG(index+count>=index);
00416 ASSERT_DEBUG(index+count<=Size);
00417
00418 if(!count)
00419 return;
00420
00421 unsigned* ptr = Bits+(index>>BitVectorIndexShift);
00422 unsigned startMask = (~0u)<<(index&BitVectorIndexMask);
00423 index = index+count-1;
00424 unsigned* end = Bits+(index>>BitVectorIndexShift);
00425 unsigned endMask = (~0u)>>((~index)&BitVectorIndexMask);
00426
00427
00428
00429
00430
00431
00432
00433 if(ptr==end)
00434 {
00435 startMask &= endMask;
00436 *ptr &= ~startMask;
00437 }
00438 else
00439 {
00440 *ptr++ &= ~startMask;
00441 while(ptr<end)
00442 *ptr++ = 0;
00443 *ptr &= ~endMask;
00444 }
00445 }
00446
00447 #endif
00448
00449
00450 int BitVectorPointer::Find(size_t count, unsigned state)
00451 {
00452 if(count>Size || !count)
00453 return -1;
00454
00455 unsigned* ptr = Bits;
00456 unsigned* end = ptr+((Size+BitVectorIndexMask)>>BitVectorIndexShift);
00457 unsigned bits;
00458 unsigned mask = 0;
00459 unsigned found = 0;
00460 if(state)
00461 state = ~0u;
00462
00463 _next_word:
00464 if(ptr>=end)
00465 goto _not_found;
00466 bits = state^*ptr++;
00467 mask = 1;
00468 if(bits&mask)
00469 {
00470 _skip_set:
00471 found = 0;
00472 if(bits+mask<mask)
00473 goto _next_word;
00474 do
00475 mask<<=1;
00476 while(bits&mask);
00477 }
00478 bits = ~bits;
00479 do
00480 {
00481 ++found;
00482 mask<<=1;
00483 }
00484 while(bits&mask);
00485 if(found>=count)
00486 goto _found;
00487 if(!mask)
00488 goto _next_word;
00489 bits = ~bits;
00490 goto _skip_set;
00491
00492 _found:
00493 {
00494 unsigned index = (ptr-Bits)<<BitVectorIndexShift;
00495 if(mask)
00496 do --index; while(mask<<=1);
00497 return index-found;
00498 }
00499
00500 _not_found:
00501 return -1;
00502 }
00503