Subversion Repositories Games.Chess Giants

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.      X86-64 inline functions for MSB(), LSB() and PopCnt().  Note
  3.      that these are 64 bit functions and they use 64 bit (quad-word)
  4.      X86-64 instructions.
  5. */
  6. /* *INDENT-OFF* */
  7. #if defined(UNIX)
  8. static __inline__ int MSB(uint64_t word) {
  9.   uint64_t dummy, dummy2;
  10.  
  11.   asm("          bsrq    %1, %0     " "\n\t"
  12.       :   "=&r"(dummy), "=&r" (dummy2)
  13.       :   "1"((uint64_t) (word))
  14.       :   "cc");
  15.   return (dummy);
  16. }
  17. static __inline__ int LSB(uint64_t word) {
  18.   uint64_t dummy, dummy2;
  19.  
  20.   asm("          bsfq    %1, %0     " "\n\t"
  21.       :   "=&r"(dummy), "=&r" (dummy2)
  22.       :   "1"((uint64_t) (word))
  23.       :   "cc");
  24.   return (dummy);
  25. }
  26. #if defined(POPCNT)
  27. static __inline__ int PopCnt(uint64_t word) {
  28.   uint64_t dummy, dummy2;
  29.  
  30.   asm("          popcnt  %1, %0     " "\n\t"
  31.       :   "=&r"(dummy), "=&r" (dummy2)
  32.       :   "1"((uint64_t) (word))
  33.       :   "cc");
  34.   return (dummy);
  35. }
  36. #else
  37. static __inline__ int PopCnt(uint64_t word) {
  38.   uint64_t dummy, dummy2, dummy3;
  39.  
  40. asm("          xorq    %0, %0    " "\n\t"
  41.     "          testq   %1, %1    " "\n\t"
  42.     "          jz      2f        " "\n\t"
  43.     "1:        leaq    -1(%1),%2 " "\n\t"
  44.     "          incq    %0        " "\n\t"
  45.     "          andq    %2, %1    " "\n\t"
  46.     "          jnz     1b        " "\n\t"
  47.     "2:                          " "\n\t"
  48. :   "=&r"(dummy), "=&r"(dummy2), "=&r"(dummy3)
  49. :   "1"((uint64_t) (word))
  50. :   "cc");
  51.   return (dummy);
  52. }
  53. #endif
  54. #else
  55. #if defined(POPCNT)
  56. #include <nmmintrin.h>
  57. __forceinline int PopCnt(uint64_t a) {
  58.   return _mm_popcnt_u64(a);
  59. }
  60. #else
  61.  
  62. __forceinline int PopCnt(uint64_t a) {
  63.   int c = 1;
  64.  
  65.   while (a &= a - 1)
  66.     c++;
  67.   return c;
  68. }
  69. #endif
  70.  
  71. __forceinline int MSB(uint64_t a) {
  72.   int v;
  73.  
  74.   _BitScanReverse64(&v, a);
  75.   return v;
  76. }
  77.  
  78. __forceinline int LSB(uint64_t a) {
  79.   int v;
  80.  
  81.   _BitScanForward64(&v, a);
  82.   return v;
  83. }
  84. #endif
  85.