Compile error on Fruit clone

Discussion of chess software programming and technical issues.

Moderator: Ras

User avatar
hgm
Posts: 28361
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Compile error on Fruit clone

Post by hgm »

I have a Fruit clone that does not print its move when running under a GUI, but runs OK from the command line. So apparently a buffering problem, which could be easily fixed by adding an fflush(stdout); n the right place.

But the problem is that it does not want to compile under g++ / Cygwin. I get an error message from a file random.cpp, where gcc finds the offending code:

Code: Select all

#include ".\random.h"

__forceinline unsigned long long_mul_mod(unsigned long multiplier, unsigned long multiplicand, unsigned long divisor) {
  unsigned long result;
  __asm {
    mov eax, multiplier;
    mul multiplicand;
    div divisor;
    mov result, edx;
  }
  return result;
}

inline unsigned long long_rand(unsigned long &seed, unsigned long multiplier = 16807) {
  seed = long_mul_mod(seed, multiplier, 0x7fffffff);
  return seed;
}
Apparently __forceinline is not g++, and I simply removed it. But g++ also does not understand the __asm stuff.

Does this piece of code normally occur in Fruit, and is it called so often that it has to be coded in assembler? How would I include the assembler in gcc?
tvrzsky
Posts: 128
Joined: Sat Sep 23, 2006 7:10 pm
Location: Prague

Re: Compile error on Fruit clone

Post by tvrzsky »

hgm wrote:I have a Fruit clone that does not print its move when running under a GUI, but runs OK from the command line. So apparently a buffering problem, which could be easily fixed by adding an fflush(stdout); n the right place.

But the problem is that it does not want to compile under g++ / Cygwin. I get an error message from a file random.cpp, where gcc finds the offending code:

Code: Select all

#include ".\random.h"

__forceinline unsigned long long_mul_mod(unsigned long multiplier, unsigned long multiplicand, unsigned long divisor) {
  unsigned long result;
  __asm {
    mov eax, multiplier;
    mul multiplicand;
    div divisor;
    mov result, edx;
  }
  return result;
}

inline unsigned long long_rand(unsigned long &seed, unsigned long multiplier = 16807) {
  seed = long_mul_mod(seed, multiplier, 0x7fffffff);
  return seed;
}
Apparently __forceinline is not g++, and I simply removed it. But g++ also does not understand the __asm stuff.

Does this piece of code normally occur in Fruit, and is it called so often that it has to be coded in assembler? How would I include the assembler in gcc?
try this:

Code: Select all

inline unsigned long long_mul_mod(unsigned long multiplier, unsigned long multiplicand, unsigned long divisor) (__attribute__ ((always_inline)))
{
  unsigned long result;
  asm ("movl %[MULTIPLIER], %%eax \n"
        "mull %[MULTIPLICAND]  \n"
        "divl %[DIVISOR] \n"
        "movl %%edx, %[RESULT] \n"
        : [RESULT] "=g" (result)
        : [MULTIPLIER] "g" (multiplier) ,[MULTIPLICAND] "g" (multiplicand),[DIVISOR] "g" (divisor)
        : "%eax", "%edx");
  return result;
}
Last edited by tvrzsky on Tue Mar 24, 2009 10:01 am, edited 1 time in total.
User avatar
sje
Posts: 4675
Joined: Mon Mar 13, 2006 7:43 pm

Re: Compile error on Fruit clone

Post by sje »

Try a header that uses "__inline__" like this:

Code: Select all

  // Find first zero in a 64 bit integer

  static __inline__ unsigned long long int __ffz64(unsigned long long int cbits)
  {
    __asm__("bsfq %1,%q0" : "=r" (cbits) :"r" (~cbits));
    return cbits;
  }
Edited to add: The 32 bit version of the above works under Cygwin.
bob
Posts: 20943
Joined: Mon Feb 27, 2006 7:30 pm
Location: Birmingham, AL

Re: Compile error on Fruit clone

Post by bob »

hgm wrote:I have a Fruit clone that does not print its move when running under a GUI, but runs OK from the command line. So apparently a buffering problem, which could be easily fixed by adding an fflush(stdout); n the right place.

But the problem is that it does not want to compile under g++ / Cygwin. I get an error message from a file random.cpp, where gcc finds the offending code:

Code: Select all

#include ".\random.h"

__forceinline unsigned long long_mul_mod(unsigned long multiplier, unsigned long multiplicand, unsigned long divisor) {
  unsigned long result;
  __asm {
    mov eax, multiplier;
    mul multiplicand;
    div divisor;
    mov result, edx;
  }
  return result;
}

inline unsigned long long_rand(unsigned long &seed, unsigned long multiplier = 16807) {
  seed = long_mul_mod(seed, multiplier, 0x7fffffff);
  return seed;
}
Apparently __forceinline is not g++, and I simply removed it. But g++ also does not understand the __asm stuff.

Does this piece of code normally occur in Fruit, and is it called so often that it has to be coded in assembler? How would I include the assembler in gcc?
Here's Crafty's MSB() function which uses BSR to find the most significant 1 bit that is set. Works for g++ and intel's icc.

Code: Select all

int static __inline__ MSB(long word)
{
  long dummy, dummy2;

asm("          bsrq    %1, %0     " "\n\t"
    "          jnz     1f         " "\n\t"
    "          movq    $64, %0    " "\n\t"
    "1:                           " "\n\t"
:   "=&r"(dummy), "=&r" (dummy2)
:   "1"((long) (word))
:   "cc");
  return (dummy);
}
Gerd Isenberg
Posts: 2251
Joined: Wed Mar 08, 2006 8:47 pm
Location: Hattingen, Germany

Re: Compile error on Fruit clone

Post by Gerd Isenberg »

MS inline assembly is even no longer possible in 64-bit mode. I bet a pure C-version is much faster with recent compilers.

Code: Select all

inline unsigned long long_rand(unsigned long &seed, unsigned long multiplier = 16807) {
  seed = (seed * multiplier) % 0x7fffffff;
  return seed;
}