* generate better i386 code for 64-bit shl/shr, by masking the shift count by

63, instead of comparing it to 64 and branching. Note that, although this
  changes the behaviour of 64-bit shifts by values larger than 64 (when stored
  in a variable), it actually makes them consistent with both the code,
  generated on x86_64, as well as with 64-bit shift by constant on i386 itself.

git-svn-id: trunk@35727 -
This commit is contained in:
nickysn 2017-04-04 16:28:54 +00:00
parent 76cb419241
commit 6580dfee39

View File

@ -119,7 +119,7 @@ implementation
var
hreg64hi,hreg64lo:Tregister;
v : TConstExprInt;
l1,l2,l3:Tasmlabel;
l2,l3:Tasmlabel;
begin
location_reset(location,LOC_REGISTER,def_cgsize(resultdef));
@ -177,15 +177,9 @@ implementation
{ the damned shift instructions work only til a count of 32 }
{ so we've to do some tricks here }
current_asmdata.getjumplabel(l1);
current_asmdata.getjumplabel(l2);
current_asmdata.getjumplabel(l3);
emit_const_reg(A_CMP,S_L,64,NR_ECX);
cg.a_jmp_flags(current_asmdata.CurrAsmList,F_L,l1);
emit_reg_reg(A_XOR,S_L,hreg64lo,hreg64lo);
emit_reg_reg(A_XOR,S_L,hreg64hi,hreg64hi);
cg.a_jmp_always(current_asmdata.CurrAsmList,l3);
cg.a_label(current_asmdata.CurrAsmList,l1);
emit_const_reg(A_AND,S_L,63,NR_ECX);
emit_const_reg(A_CMP,S_L,32,NR_ECX);
cg.a_jmp_flags(current_asmdata.CurrAsmList,F_L,l2);
emit_const_reg(A_SUB,S_L,32,NR_ECX);