inline assembly -> Windows to Linux port

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

selectany

inline assembly -> Windows to Linux port

Post by selectany »

Hi!

I'd like to port my existing source code of chess to work on Linux using GCC.
The problem is with inline assembler code for LSB routine.
The following code works properly only in Debug mode.
If I use some kind of optimization, the result of routine is bogus:
- in Release build routine always returns 0;
- if I force inlining with __inline__ __attribute__((always_inline)) ), the result of the routine is random.

Here is the code:

Code: Select all

int LSB(unsigned long long arg1)
{
        int hword = (int)(arg1 >> 32);

        asm(
        "bsfl %0,%%eax               \n\t"
        "jnz 1f                      \n\t"
        "bsfl %1,%%eax               \n\t"
        "addl $32,%%eax              \n\t"
        "1:                          \n\t"
        :
        :"m"(arg1),"m"(hword)
        :"%eax");
}
PP: Platform: ArchLinux, IDE: NetBeans
tvrzsky
Posts: 128
Joined: Sat Sep 23, 2006 7:10 pm
Location: Prague

Re: inline assembly -> Windows to Linux port

Post by tvrzsky »

Try this:

Code: Select all

int LSBssf(unsigned long long arg1) 
{ 
        int hword = (int)(arg1 >> 32); 
        int retval;
        asm(
        "bsfl %1,%0               \n\t" 
        "jnz 1f                      \n\t" 
        "bsfl %2,%0               \n\t" 
        "addl $32,%0              \n\t" 
        "1:                          \n\t" 
        : "=&q" (retval)
        :"m"(arg1),"q"(hword) 
        : );
        return retval;
}
Or this:

Code: Select all

int LSBb(unsigned long long arg)
{
    if ((int)arg) return __builtin_ctz((arg));
    else return (__builtin_ctz((arg>>32)));
}
tvrzsky
Posts: 128
Joined: Sat Sep 23, 2006 7:10 pm
Location: Prague

Re: inline assembly -> Windows to Linux port

Post by tvrzsky »

Oops, of course I meant:

Code: Select all

int LSBb(unsigned long long arg)
{
    if ((int)arg) return __builtin_ctz((arg));
    else return (__builtin_ctz((arg>>32))) + 32;
}
selectany

Re: inline assembly -> Windows to Linux port

Post by selectany »

Thanks :)

I didn't know about these built-in things.
I found even more suitable one: __builtin_ctzll.
Is it better to use it?
tvrzsky
Posts: 128
Joined: Sat Sep 23, 2006 7:10 pm
Location: Prague

Re: inline assembly -> Windows to Linux port

Post by tvrzsky »

selectany wrote:Thanks :)

I didn't know about these built-in things.
I found even more suitable one: __builtin_ctzll.
Is it better to use it?
Surely, I did not take notice of this one. At least migration to 64bits will be effortless.