ソースを参照

+ perform the optimization in tmoddivnode.firstoptimize also for div/mod by
negative powers of 2 as well

git-svn-id: trunk@36930 -

nickysn 8 年 前
コミット
b41762d1bf
1 ファイル変更20 行追加8 行削除
  1. 20 8
      compiler/nmat.pas

+ 20 - 8
compiler/nmat.pas

@@ -494,11 +494,12 @@ implementation
         statements : tstatementnode;
         temp,resulttemp : ttempcreatenode;
         masknode : tnode;
+        invertsign: Boolean;
       begin
         result := nil;
         { divide/mod a number by a constant which is a power of 2? }
         if (right.nodetype = ordconstn) and
-          ispowerof2(tordconstnode(right).value,power) and
+          isabspowerof2(tordconstnode(right).value,power) and
 {$ifdef cpu64bitalu}
           { for 64 bit, we leave the optimization to the cg }
             (not is_signed(resultdef)) then
@@ -512,6 +513,7 @@ implementation
               begin
                 if is_signed(resultdef) then
                   begin
+                    invertsign:=tordconstnode(right).value<0;
                     if is_64bitint(left.resultdef) then
                       if not (cs_opt_size in current_settings.optimizerswitches) then
                         shiftval:=63
@@ -550,13 +552,23 @@ implementation
                             right.resultdef,false)
                         );
 
-                    addstatement(statements,cassignmentnode.create(ctemprefnode.create(resulttemp),
-                      cinlinenode.create(in_sar_x_y,false,
-                        ccallparanode.create(cordconstnode.create(power,u8inttype,false),
-                        ccallparanode.create(caddnode.create(addn,ctemprefnode.create(temp),
-                          masknode),nil
-                        ))))
-                    );
+                    if invertsign then
+                      addstatement(statements,cassignmentnode.create(ctemprefnode.create(resulttemp),
+                        cunaryminusnode.create(
+                          cinlinenode.create(in_sar_x_y,false,
+                            ccallparanode.create(cordconstnode.create(power,u8inttype,false),
+                            ccallparanode.create(caddnode.create(addn,ctemprefnode.create(temp),
+                              masknode),nil
+                            )))))
+                      )
+                    else
+                      addstatement(statements,cassignmentnode.create(ctemprefnode.create(resulttemp),
+                        cinlinenode.create(in_sar_x_y,false,
+                          ccallparanode.create(cordconstnode.create(power,u8inttype,false),
+                          ccallparanode.create(caddnode.create(addn,ctemprefnode.create(temp),
+                            masknode),nil
+                          ))))
+                      );
                     addstatement(statements,ctempdeletenode.create(temp));
                     addstatement(statements,ctempdeletenode.create_normal_temp(resulttemp));
                     addstatement(statements,ctemprefnode.create(resulttemp));