BitScanForward
BitScanForward
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
Function BitScanForward32 naked cdecl (ByVal num as uinteger) As Integer
Asm
bsf eax,dword Ptr [esp+4]
ret
End Asm
End Function
Re: BitScanForward
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)
Do you get an error message, or unexpected output, or something else?output wrote:2
-
- Posts: 8586
- Joined: May 28, 2005 3:28
- Contact:
Re: BitScanForward
What do you mean with "does not work" ?
No problem here on old PENTIUM 4.
Joshy
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
Re: BitScanForward
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.
Re: BitScanForward
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.
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.
Re: BitScanForward
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.
Re: BitScanForward
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"
"addfive.asm:18: Error: incorrect register 'eax' used with 'q' suffix"
Re: BitScanForward
EAX = 32bitschooner wrote:"addfive.asm:18: Error: incorrect register 'eax' used with 'q' suffix"
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.
Re: BitScanForward
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)
Re: BitScanForward
An introduction to x64 assembly can be found here:
http://lomont.org/Math/Papers/2009/Intr ... sembly.pdf
http://lomont.org/Math/Papers/2009/Intr ... sembly.pdf
Re: BitScanForward
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?
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?
Re: BitScanForward
No.schooner wrote:fxm,
Thank you, but that is exactly the example that produced the error.
I replaced "Integer" (64-bit) with "Long" (32-bit)!
Re: BitScanForward
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
Re: BitScanForward
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.
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.
Re: BitScanForward
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;
}
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;
}