Browse Source

* 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 -

nickysn 8 years ago
parent
commit
9e8cc127b0
1 changed files with 14 additions and 6 deletions
  1. 14 6
      compiler/x86/nx86mat.pas

+ 14 - 6
compiler/x86/nx86mat.pas

@@ -421,12 +421,20 @@ interface
                     { no jumps, but more operations }
                     { no jumps, but more operations }
                     hreg2:=cg.getintregister(current_asmdata.CurrAsmList,cgsize);
                     hreg2:=cg.getintregister(current_asmdata.CurrAsmList,cgsize);
                     emit_reg_reg(A_MOV,opsize,hreg1,hreg2);
                     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 }
                     { add to the left value }
                     emit_reg_reg(A_ADD,opsize,hreg2,hreg1);
                     emit_reg_reg(A_ADD,opsize,hreg2,hreg1);
                     { do the shift }
                     { do the shift }