Computer Chess Club Archives


Search

Terms

Messages

Subject: Re: Beating Bitscan to Death -- redux

Author: Walter Faxon

Date: 12:40:30 01/05/03

Go up one level in this thread


Hi, Matt.

For bitscan, here is one last try using the masking logic.  Note the
(potential!) use of cmoves instead of setcc with shifts.

I have a question:  You've written several times about advanced x86's "renaming"
registers.  Does a compiler avoid register saves/restores by writing special
instructions to do this, or does the processor somehow do it on the fly?  Or
maybe I'm misunderstanding this entirely.

-- Walter


Code follows:
// ---------------------------------------------------------------------------
typedef unsigned long long u64_t;
typedef unsigned long u32_t;
typedef unsigned char u8_t;

// ---------------------------------------------------------------------------
// Find, remove, report index of least-significant set bit in 64-bit
// 'bitboard'.  Extra-pedantic code for late x86 32-bit architecture.
// Written January 2003 by Walter Faxon.  No copyright.  No warranty.
//
inline                              // force inline differs by compiler
int bitscan_yabs2( u64_t* p_bb )
    {
    u32_t* p_both;
    register u32_t low, high, bit;
    register union {
        u32_t index;
        u8_t i6;
        } ndx;
    register u8_t i5, i4, i3, i2, i1;

    // rename argument
    p_both = (u32*) p_bb;

    // read all 64 bits
    low = p_both[0];
    high = p_both[1];

    // find which half has low-order bit; save in low
    ndx.index = 0;              // (or prior update: ndx.index &= 0x000000FF;)
    ndx.i6 = (low == 0);        // setcc
    if (low == 0) low = high;   // cmove

    // extract low-order bit (or break)
    bit = -low;
    // When code written as macro, here can break out of a bit-scan loop:
    // if (bit == 0) break;
    bit &= low;

    // update bb
    p_both[ndx.index] = low ^ bit;

    // compute index of bit
    ndx.i6 <<= 5;
    i5 = i4 = i3 = i2 = 0;
    if ((bit & 0x0000FFFF) == 0) i5 = 0x10;     // cmoves to avoid shifts
    if ((bit & 0x00FF00FF) == 0) i4 = 0x08;
    if ((bit & 0x0F0F0F0F) == 0) i3 = 0x04;
    if ((bit & 0x33333333) == 0) i2 = 0x02;
    i1 = ((bit & 0x55555555) == 0);             // setcc
    ndx.i6 |= i5 | i4 | i3 | i2 | i1;           // hopefully will interleave
                                                // during above
    // done
    return (int)ndx.index;
    }



This page took 0.01 seconds to execute

Last modified: Thu, 15 Apr 21 08:11:13 -0700

Current Computer Chess Club Forums at Talkchess. This site by Sean Mintz.