BitScanForward

General FreeBASIC programming questions.
schooner
Posts: 30
Joined: Jul 27, 2015 20:53

BitScanForward

Postby schooner » Jul 29, 2015 18:32

Is there an example of how to access the special hardware instructions BitScanForward, BitScanReverse, and SSE4 PopCount? When checking the FB source code, the keywordTb() words "bsf" and "bsr" can be found, but seem to be inaccessible. SSE4 "popcnt" should be on the to-do list for the programmers. Here is an example of something that does not work:

Function BitScanForward32 naked cdecl (ByVal num as uinteger) As Integer
Asm
bsf eax,dword Ptr [esp+4]
ret
End Asm
End Function
dkl
Site Admin
Posts: 3209
Joined: Jul 28, 2005 14:45
Location: Germany

Re: BitScanForward

Postby dkl » Jul 29, 2015 19:11

Hm, it seems to work for me on both win32 and linux-x86, FB 1.03.0. It compiles and runs without problems.

Code: Select all

Function BitScanForward32 naked cdecl (ByVal num as uinteger) As Integer
   Asm
      bsf eax, dword ptr [esp+4]
      ret
   End Asm
End Function

print BitScanForward32(&b100)

output wrote:2


Do you get an error message, or unexpected output, or something else?
D.J.Peters
Posts: 7808
Joined: May 28, 2005 3:28

Re: BitScanForward

Postby D.J.Peters » Jul 29, 2015 19:21

What do you mean with "does not work" ?

No problem here on old PENTIUM 4.

Joshy

Code: Select all

Function BitScanForward32 naked cdecl (ByVal num as ulong) As ulong
  Asm
    bsf eax,dword Ptr [esp+4]
    ret
  End Asm
End Function

Function BitScanReverse32 naked cdecl (ByVal num as ulong) As ulong
  Asm
    bsr eax,dword Ptr [esp+4]
    ret
  End Asm
End Function

print BitScanForward32(&B1)
print BitScanForward32(&B10)
print BitScanForward32(&B100)
print BitScanForward32(&B1000)
print BitScanForward32(&B10000)
print BitScanForward32(&B100000)
print BitScanForward32(&B0)
sleep
0
1
2
3
4
5
0
schooner
Posts: 30
Joined: Jul 27, 2015 20:53

Re: BitScanForward

Postby schooner » Jul 29, 2015 19:36

My apologies. Bit scans seem to be working fine now here. I do not know why they did not function in my earlier test program. Murphys law I guess.
schooner
Posts: 30
Joined: Jul 27, 2015 20:53

Re: BitScanForward

Postby schooner » Jul 30, 2015 14:02

dkl wrote "...FB 1.03.0. It compiles and runs without problems."

That must be for the 32-bit version. Is it possible to compile any assembly instructions yet in 64-bit? It seems to try. The documentation was not clear that inline assembly was ready, or perhaps some extra flags have to be set to get the documented examples to compile.

Here is a method to bit scan ulongs for FB 32-bit versions. It is approximately 10 times faster than software methods.

Code: Select all

#define BSF64(a) BitScanForward32_long(cuint(a),cuint(a shr 32))

Function BitScanForward32_long cdecl (ByVal num_lo as uinteger, ByVal num_hi as uinteger) as uinteger
Asm
   bsf eax,[num_lo]
   jnz bsf1
   bsf eax,[num_hi]
   jz bsf1
   add eax,32
bsf1:
   mov [Function], eax
End Asm
End Function

print BSF64(&b100ull)
print BSF64(&b100000000000000000000000000000000000000ull)
Last edited by schooner on Jul 30, 2015 17:22, edited 1 time in total.
dkl
Site Admin
Posts: 3209
Joined: Jul 28, 2005 14:45
Location: Germany

Re: BitScanForward

Postby dkl » Jul 30, 2015 14:50

In general, this style of inline ASM should also work with FB 64bit since version 1.02.0. Due to the use of the C backend, not everything works yet though.
schooner
Posts: 30
Joined: Jul 27, 2015 20:53

Re: BitScanForward

Postby schooner » Jul 30, 2015 15:33

Is there a simple 64-bit "Hello World!" type example just to get started? I cannot get the asm AddFive() example in the documentation to compile. It replies:

"addfive.asm:18: Error: incorrect register 'eax' used with 'q' suffix"
MrSwiss
Posts: 3214
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: BitScanForward

Postby MrSwiss » Jul 30, 2015 15:43

schooner wrote:"addfive.asm:18: Error: incorrect register 'eax' used with 'q' suffix"

EAX = 32bit
q suffix refers to q (quad Word) = 64 bits
You'll have to use 64bit reference to register too ... RAX in this case.
Last edited by MrSwiss on Jul 30, 2015 15:54, edited 1 time in total.
fxm
Posts: 9123
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: BitScanForward

Postby fxm » Jul 30, 2015 15:44

Can you try with this:

Code: Select all

Function AddFive(ByVal num As Long) As Long
    Asm
        mov eax, [num]
        add eax, 5
        mov [Function], eax
    End Asm
End Function

Dim i As Long = 4

Print "4 + 5 ="; AddFive(i)
MrSwiss
Posts: 3214
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: BitScanForward

Postby MrSwiss » Jul 30, 2015 15:58

An introduction to x64 assembly can be found here:
http://lomont.org/Math/Papers/2009/Introduction%20to%20x64%20Assembly.pdf
schooner
Posts: 30
Joined: Jul 27, 2015 20:53

Re: BitScanForward

Postby schooner » Jul 30, 2015 16:04

MrSwiss,
Thank you but I have already tried other stuff. I was looking for someone to show me code.

fxm,
Thank you, but that is exactly the example that produced the error. There is a 32-bit version of gcc installed at the root directory. I wonder if that could be overriding the FB compiler directives?
fxm
Posts: 9123
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: BitScanForward

Postby fxm » Jul 30, 2015 16:12

schooner wrote:fxm,
Thank you, but that is exactly the example that produced the error.

No.
I replaced "Integer" (64-bit) with "Long" (32-bit)!
MrSwiss
Posts: 3214
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: BitScanForward

Postby MrSwiss » Jul 30, 2015 16:16

Just a rewrite of fxm example in x64:

Code: Select all

Function AddFive(ByVal num As LongInt) As LongInt  ' the same as Integer in x64
    Asm
        mov rax, [num]
        add rax, 5
        mov [Function], rax
    End Asm
End Function

Dim i As LongInt = 4

Print "4 + 5 = "; AddFive(i)
sleep
schooner
Posts: 30
Joined: Jul 27, 2015 20:53

Re: BitScanForward

Postby schooner » Jul 30, 2015 16:25

fmx,
Worked!!! I noticed in the asm output that all values are converted to longs (e.g. no integers), so that may be the trick to asm compilation.

I have run across this type of error before when trying to convert an unsigned long to signed integer in the FB 64-bit assembly. It will not do it properly.
schooner
Posts: 30
Joined: Jul 27, 2015 20:53

Re: BitScanForward

Postby schooner » Jul 30, 2015 16:36

MrSwiss,
That is a good example.

How would you translate this C function for BitScanForward?

__CRT_INLINE BOOLEAN BSF(DWORD *Index,DWORD64 Mask) {
LONG64 t;
__asm__ ("bsfq %0,%1" : "=r" (Mask),"=r" (t));
*Index = t;
return Mask!=0;
}

Return to “General”

Who is online

Users browsing this forum: No registered users and 5 guests