| 411 | //========================================================================== |
| 412 | |
| 413 | int VMFunctionBuilder::RegAvailability::Get(int count) |
| 414 | { |
| 415 | VM_UWORD mask; |
| 416 | int i, firstbit; |
| 417 | |
| 418 | // Getting fewer than one register makes no sense, and |
| 419 | // the algorithm used here can only obtain ranges of up to 32 bits. |
| 420 | if (count < 1 || count > 32) |
| 421 | { |
| 422 | return -1; |
| 423 | } |
| 424 | |
| 425 | mask = count == 32 ? ~0u : (1 << count) - 1; |
| 426 | |
| 427 | for (i = 0; i < 256 / 32; ++i) |
| 428 | { |
| 429 | // Find the first word with free registers |
| 430 | VM_UWORD bits = Used[i]; |
| 431 | if (bits != ~0u) |
| 432 | { |
| 433 | // Are there enough consecutive bits to satisfy the request? |
| 434 | // Search by 16, then 8, then 1 bit at a time for the first |
| 435 | // free register. |
| 436 | if ((bits & 0xFFFF) == 0xFFFF) |
| 437 | { |
| 438 | firstbit = ((bits & 0xFF0000) == 0xFF0000) ? 24 : 16; |
| 439 | } |
| 440 | else |
| 441 | { |
| 442 | firstbit = ((bits & 0xFF) == 0xFF) ? 8 : 0; |
| 443 | } |
| 444 | for (; firstbit < 32; ++firstbit) |
| 445 | { |
| 446 | if (((bits >> firstbit) & mask) == 0) |
| 447 | { |
| 448 | if (firstbit + count <= 32) |
| 449 | { // Needed bits all fit in one word, so we got it. |
| 450 | if (i * 32 + firstbit + count > MostUsed) |
| 451 | { |
| 452 | MostUsed = i * 32 + firstbit + count; |
| 453 | } |
| 454 | Used[i] |= mask << firstbit; |
| 455 | return i * 32 + firstbit; |
| 456 | } |
| 457 | // Needed bits span two words, so check the next word. |
| 458 | else if (i < 256/32 - 1) |
| 459 | { // There is a next word. |
| 460 | if (((Used[i + 1]) & (mask >> (32 - firstbit))) == 0) |
| 461 | { // The next word has the needed open space, too. |
| 462 | if (i * 32 + firstbit + count > MostUsed) |
| 463 | { |
| 464 | MostUsed = i * 32 + firstbit + count; |
| 465 | } |
| 466 | Used[i] |= mask << firstbit; |
| 467 | Used[i + 1] |= mask >> (32 - firstbit); |
| 468 | return i * 32 + firstbit; |
| 469 | } |
| 470 | else |