Page 1 of 1

generalized shift

PostPosted: 13 Jan 2007, 12:08
by Gerd Isenberg
Since rot64 works like a generalized shift with positive or negative shift amount, it might be applied to get pawn-attacks for both sides - or a Kogge-Stone fill with a direction parameter and small lookups for shift amount and wrap ands, instead of multiple code for eight directions.

Code: Select all
u64 occludedFill (u64 gen, u64 pro, u32 dir8)
{
   u8 r = shift[dir8]; // {+-1,7,8,9}
   pro  = pro &  avoidWrap[dir8];
   gen |= pro & _rotl64(gen, r);
   pro  = pro & _rotl64(pro, r);
   gen |= pro & _rotl64(gen, 2*r);
   pro  = pro & _rotl64(pro, 2*r);
   gen |= pro & _rotl64(gen, 4*r);
   return gen;
}

u64 shiftOne (u64 b, u32 dir8)
{
   u8 r = shift[dir8]; // {+-1,7,8,9}
   return _rotl64(b, r) & avoidWrap[dir8];
}

u64 slidingAttacks (u64 sliders, u64 empty, u32 dir8)
{
   u64 fill = occludedFill(slider, empty, dir8)
   return shiftOne(fill, dir8);
}

// positve left, negative right shifts
u8 shift[8] = {9, 1,-7,-8,-9,-1, 7, 8};

u64 avoidWrap[8] =
{
   0xfefefefefefefe00,
   0xfefefefefefefefe,
   0x00fefefefefefefe,
   0x00ffffffffffffff,
   0x007f7f7f7f7f7f7f,
   0x7f7f7f7f7f7f7f7f,
   0x7f7f7f7f7f7f7f00,
   0xffffffffffffff00,
};

Of course generalized shift will be a bit slower due to lookups and using cl as the shift amount register.

Gerd