Browse Source

* i8086 optimizations in op_const_reg for 32-bit OP_SHL and OP_SHR with const >= 16

git-svn-id: trunk@24756 -
nickysn 12 years ago
parent
commit
55a071692e
1 changed files with 23 additions and 1 deletions
  1. 23 1
      compiler/i8086/cgcpu.pas

+ 23 - 1
compiler/i8086/cgcpu.pas

@@ -213,7 +213,29 @@ unit cgcpu;
               OP_SHR,OP_SHL,OP_SAR:
                 begin
                   a:=a and 31;
-                  if a<>0 then
+                  { for shl with const >= 16, we can just move the low register
+                    to the high reg, then zero the low register, then do the
+                    remaining part of the shift (by const-16) in 16 bit on the
+                    high register. the same thing applies to shr with low and high
+                    reversed. }
+                  if (op in [OP_SHR,OP_SHL]) and (a >= 16) then
+                    case op of
+                      OP_SHR:
+                        begin
+                          a_load_reg_reg(list,OS_16,OS_16,GetNextReg(reg),reg);
+                          a_load_const_reg(list,OS_16,0,GetNextReg(reg));
+                          a_op_const_reg(list,OP_SHR,OS_16,a-16,reg);
+                        end;
+                      OP_SHL:
+                        begin
+                          a_load_reg_reg(list,OS_16,OS_16,reg,GetNextReg(reg));
+                          a_load_const_reg(list,OS_16,0,reg);
+                          a_op_const_reg(list,OP_SHL,OS_16,a-16,GetNextReg(reg));
+                        end;
+                      else
+                        internalerror(2013060201);
+                    end
+                  else if a<>0 then
                     begin
                       use_loop:=a>2;