* Bsf/Bsr on x86 handle now correctly 0 as argument, resolves #22783

* generic Bsf implementations handle now correctly 0 as argument
* test extended

git-svn-id: trunk@22327 -
This commit is contained in:
florian 2012-09-05 13:51:45 +00:00
parent 39e32a9b3e
commit 8818b58e5d
4 changed files with 74 additions and 7 deletions

View File

@ -1628,12 +1628,17 @@ unit cgx86;
procedure tcgx86.a_bit_scan_reg_reg(list: TAsmList; reverse: boolean; size: TCGSize; src, dst: TRegister);
var
opsize: topsize;
l : TAsmLabel;
begin
opsize:=tcgsize2opsize[size];
if not reverse then
list.concat(taicpu.op_reg_reg(A_BSF,opsize,src,dst))
else
list.concat(taicpu.op_reg_reg(A_BSR,opsize,src,dst));
current_asmdata.getjumplabel(l);
a_jmp_cond(list,OC_NE,l);
list.concat(taicpu.op_const_reg(A_MOV,opsize,$ff,dst));
a_label(list,l);
end;
{*************** compare instructructions ****************}

View File

@ -1564,8 +1564,12 @@ function BsfQWord(Const AValue : QWord): cardinal; assembler; nostackframe;
asm
bsfl 4(%esp),%eax
jnz .L2
.L1: bsfl 8(%esp),%eax
add $32,%eax
.L1:
bsfl 8(%esp),%eax
jnz .L3
movl $223,%eax
.L3:
addl $32,%eax
.L2:
end;
{$endif FPC_SYSTEM_HAS_BSF_QWORD}
@ -1579,7 +1583,10 @@ asm
jz .L1
add $32,%eax
jmp .L2
.L1: bsrl 4(%esp),%eax
.L1:
bsrl 4(%esp),%eax
jnz .L2
movl $255,%eax
.L2:
end;
{$endif FPC_SYSTEM_HAS_BSR_QWORD}

View File

@ -2381,9 +2381,10 @@ function BsrByte(Const AValue: Byte): Byte;
{$ifndef FPC_HAS_INTERNAL_BSF_WORD}
function BsfWord(Const AValue: Word): cardinal;
begin
result:=$ff;
if lo(AValue)<>0 then
result:=BsfByte(lo(AValue))
else
else if hi(AValue) <> 0 then
result:=BsfByte(hi(AValue))+8
end;
{$endif}
@ -2405,9 +2406,10 @@ function BsrWord(Const AValue: Word): cardinal;
{$ifndef FPC_SYSTEM_HAS_BSF_DWORD}
function BsfDWord(Const AValue : DWord): cardinal;
begin
result:=$ff;
if lo(AValue)<>0 then
result:=BsfWord(lo(AValue))
else
else if hi(AValue) <> 0 then
result:=BsfWord(hi(AValue))+16
end;
{$endif}
@ -2429,10 +2431,11 @@ end;
{$ifndef FPC_SYSTEM_HAS_BSF_QWORD}
function BsfQWord(Const AValue : QWord): cardinal;
begin
result:=$ff;
if lo(AValue) <> 0 then
result:=BsfDWord(lo(AValue))
else
result:=BsfDWord(hi(AValue)) + 32
else hi(AValue) <> 0 then
result:=BsfDWord(hi(AValue)) + 32;
end;
{$endif}
{$endif}

View File

@ -23,6 +23,19 @@ begin
exit(false);
end;
end;
x8:=0;
f:=BsfByte(x8);
if (f<>$ff) then
begin
writeln('BsfByte(',x8,') returned ',f,', should be ',$ff);
exit(false);
end;
r:=BsrByte(x8);
if r<>$ff then
begin
writeln('BsrByte(',x8,') returned ',f,', should be ',$ff);
exit(false);
end;
result:=true;
end;
@ -47,6 +60,19 @@ begin
exit(false);
end;
end;
x16:=0;
f:=BsfDWord(x16);
if (f<>$ff) then
begin
writeln('BsfWord(',x16,') returned ',f,', should be ',$ff);
exit(false);
end;
r:=BsrWord(x16);
if r<>$ff then
begin
writeln('BsrWord(',x16,') returned ',f,', should be ',$ff);
exit(false);
end;
result:=true;
end;
@ -71,6 +97,19 @@ begin
exit(false);
end;
end;
x32:=0;
f:=BsfDWord(x32);
if (f<>$ff) then
begin
writeln('BsfDWord(',x32,') returned ',f,', should be ',$ff);
exit(false);
end;
r:=BsrDWord(x32);
if r<>$ff then
begin
writeln('BsrDWord(',x32,') returned ',f,', should be ',$ff);
exit(false);
end;
result:=true;
end;
@ -93,6 +132,19 @@ begin
exit(false);
end;
end;
x64:=0;
f:=BsfQWord(x64);
if (f<>$ff) then
begin
writeln('BsfQWord(',x64,') returned ',f,', should be ',$ff);
exit(false);
end;
r:=BsrQWord(x64);
if r<>$ff then
begin
writeln('BsrQWord(',x64,') returned ',f,', should be ',$ff);
exit(false);
end;
result:=true;
end;