Bit scan forward / back and popcount in pure Pascal? Porting from asm versions

329 Views Asked by At

I am porting a Delphi 32bit app to a Pascal Script - which does not support asm, and I only have 64bit machines so I cannot even run the code and mimic it.

{$ASMMODE INTEL}

function BitScanForward(var BB:Int64):Integer; assembler;
 asm
   bsf eax, dword ptr [BB]
   jnz @@2
 @@0: bsf eax, dword ptr [BB+04h]
   add eax, 20h
 @@2:
end;

function BitScanBackward(var BB:Int64):Integer; assembler;
 asm
   bsr eax, dword ptr [BB+04h]
   jz @@0
   add eax, 20h
   jnz @@2
 @@0: bsr eax, dword ptr [BB]
 @@2:
end;

function BitCountAsm(const BB:Int64): Integer; assembler;
 asm
   mov ecx, dword ptr BB
   xor eax, eax
   test ecx, ecx
   jz @@1
 @@0: lea edx, [ecx-1]
   inc eax
   and ecx, edx
   jnz @@0
 @@1: mov ecx, dword ptr BB+04h
   test ecx, ecx
   jz @@3
 @@2: lea edx, [ecx-1]
   inc eax
   and ecx, edx
   jnz @@2
 @@3:
end;

function BitScanForward2(BB:Int64): Integer; assembler;
asm
   bsf eax, dword ptr BB
   jnz @@2
 @@0: bsf eax, dword ptr BB+04h
   add eax, 20h
 @@2:
end;

I would like to get those in pure pascal. I also saw a YouTube video where someone demonstrates Asm->Pascal (but cannot find the app - is there one?).

1

There are 1 best solutions below

4
On

Something like:

 function BitScanForward(var BB:Int64):Integer;

 var i : integer;
     work:int64;
 begin
   Work:=bb;     
   i:=0;
   while (i<64) and ((bb and 1)=0) do
     begin
       inc(i);
       bb:=bb shr 1;
     end;
   result:=i;
 end;
 

BitscanBackward is the same but tests the highest bit. Probably best done unsigned, but I couldn't test that, so I leave that as an exercise to the reader. Probably the 64th bit is dangerous in the above version too, in that case make "work" uint64.

 function BitScanBackward(var BB:Int64):Integer;

 var i : integer;
     work:int64;
 begin
   Work:=bb;       result:=0;
   for i:=0 to 63 do
     begin
       if (bb and 1)=1 then
          inc(result);
       bb:=bb shr 1;  
     end;  
 end;