* improved the code, generated for signed division by 2 on i386 and x86_64 by

replacing the sequence
    sar reg, 31 (or 63)
    and reg, 1
  with:
    shr reg, 31 (or 63)

git-svn-id: trunk@36800 -
This commit is contained in:
nickysn 2017-07-27 16:02:30 +00:00
parent bb7cd4866d
commit 9e8cc127b0

View File

@ -421,12 +421,20 @@ interface
{ no jumps, but more operations }
hreg2:=cg.getintregister(current_asmdata.CurrAsmList,cgsize);
emit_reg_reg(A_MOV,opsize,hreg1,hreg2);
{If the left value is negative, hreg2=$ffffffff, otherwise 0.}
emit_const_reg(A_SAR,opsize,resultdef.size*8-1,hreg2);
{If negative, hreg2=right value-1, otherwise 0.}
{ (don't use emit_const_reg, because if value>high(longint)
then it must first be loaded into a register) }
cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_AND,cgsize,tordconstnode(right).value-1,hreg2);
if tordconstnode(right).value=2 then
begin
{If the left value is negative, hreg2=(right value-1)=1, otherwise 0.}
emit_const_reg(A_SHR,opsize,resultdef.size*8-1,hreg2);
end
else
begin
{If the left value is negative, hreg2=$ffffffff, otherwise 0.}
emit_const_reg(A_SAR,opsize,resultdef.size*8-1,hreg2);
{If negative, hreg2=right value-1, otherwise 0.}
{ (don't use emit_const_reg, because if value>high(longint)
then it must first be loaded into a register) }
cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_AND,cgsize,tordconstnode(right).value-1,hreg2);
end;
{ add to the left value }
emit_reg_reg(A_ADD,opsize,hreg2,hreg1);
{ do the shift }