Преглед изворни кода

+ implemented the sar/shl/shr/rol/ror inline modify-in-place nodes; the actual
optimization of "i:=i shl/shr k", etc statements is not performed yet

git-svn-id: trunk@35780 -

nickysn пре 8 година
родитељ
комит
f514657e45
4 измењених фајлова са 43 додато и 15 уклоњено
  1. 1 2
      compiler/compinnr.inc
  2. 18 7
      compiler/ncginl.pas
  3. 19 6
      compiler/ninl.pas
  4. 5 0
      rtl/inc/innr.inc

+ 1 - 2
compiler/compinnr.inc

@@ -96,12 +96,11 @@ const
    in_and_assign_x_y    = 86;
    in_or_assign_x_y     = 87;
    in_xor_assign_x_y    = 88;
-{  todo: planned, but not implemented yet:
    in_sar_assign_x_y    = 89;
    in_shl_assign_x_y    = 90;
    in_shr_assign_x_y    = 91;
    in_rol_assign_x_y    = 92;
-   in_ror_assign_x_y    = 93;}
+   in_ror_assign_x_y    = 93;
    in_neg_assign_x      = 94;
    in_not_assign_x      = 95;
 

+ 18 - 7
compiler/ncginl.pas

@@ -35,7 +35,7 @@ interface
           procedure second_length;virtual;
           procedure second_predsucc;virtual;
           procedure second_incdec;virtual;
-          procedure second_AndOrXor_assign;virtual;
+          procedure second_AndOrXorShiftRot_assign;virtual;
           procedure second_NegNot_assign;virtual;
           procedure second_typeinfo;virtual;
           procedure second_includeexclude;virtual;
@@ -203,8 +203,13 @@ implementation
                second_fma;
             in_and_assign_x_y,
             in_or_assign_x_y,
-            in_xor_assign_x_y:
-               second_AndOrXor_assign;
+            in_xor_assign_x_y,
+            in_sar_assign_x_y,
+            in_shl_assign_x_y,
+            in_shr_assign_x_y,
+            in_rol_assign_x_y,
+            in_ror_assign_x_y:
+               second_AndOrXorShiftRot_assign;
             in_neg_assign_x,
             in_not_assign_x:
                second_NegNot_assign;
@@ -427,11 +432,12 @@ implementation
 
 
 {*****************************************************************************
-                     AND/OR/XOR ASSIGN GENERIC HANDLING
+              AND/OR/XOR/SHIFT/ROTATE ASSIGN GENERIC HANDLING
 *****************************************************************************}
-      procedure tcginlinenode.second_AndOrXor_assign;
+      procedure tcginlinenode.second_AndOrXorShiftRot_assign;
         const
-          andorxorop:array[in_and_assign_x_y..in_xor_assign_x_y] of TOpCG=(OP_AND,OP_OR,OP_XOR);
+          andorxorop:array[in_and_assign_x_y..in_ror_assign_x_y] of TOpCG=
+            (OP_AND,OP_OR,OP_XOR,OP_SAR,OP_SHL,OP_SHR,OP_ROL,OP_ROR);
         var
           maskvalue : TConstExprInt;
           maskconstant : boolean;
@@ -467,9 +473,14 @@ implementation
 {$endif not cpu64bitalu}
               maskconstant:=false;
             end;
-          { write the and/or/xor instruction }
+          { write the and/or/xor/sar/shl/shr/rol/ror instruction }
           if maskconstant then
             begin
+              if inlinenumber in [in_sar_assign_x_y,in_shl_assign_x_y,in_shr_assign_x_y,in_rol_assign_x_y,in_ror_assign_x_y] then
+                if def_cgsize(left.resultdef) in [OS_64,OS_S64] then
+                  maskvalue:=maskvalue and 63
+                else
+                  maskvalue:=maskvalue and 31;
 {$ifndef cpu64bitalu}
               if def_cgsize(left.resultdef) in [OS_64,OS_S64] then
                 cg64.a_op64_const_loc(current_asmdata.CurrAsmList,andorxorop[inlinenumber],def_cgsize(tcallparanode(left).right.resultdef),maskvalue.svalue,tcallparanode(tcallparanode(left).right).left.location)

+ 19 - 6
compiler/ninl.pas

@@ -91,7 +91,7 @@ interface
           function first_seg: tnode; virtual;
           function first_sar: tnode; virtual;
           function first_fma : tnode; virtual;
-          function first_AndOrXor_assign: tnode; virtual;
+          function first_AndOrXorShiftRot_assign: tnode; virtual;
           function first_NegNot_assign: tnode; virtual;
         private
           function handle_str: tnode;
@@ -3032,7 +3032,12 @@ implementation
 
               in_and_assign_x_y,
               in_or_assign_x_y,
-              in_xor_assign_x_y:
+              in_xor_assign_x_y,
+              in_sar_assign_x_y,
+              in_shl_assign_x_y,
+              in_shr_assign_x_y,
+              in_rol_assign_x_y,
+              in_ror_assign_x_y:
                 begin
                   resultdef:=voidtype;
                   if not(df_generic in current_procinfo.procdef.defoptions) then
@@ -3060,7 +3065,10 @@ implementation
                               { these nodes shouldn't be created, when range checking is on }
                               if [cs_check_range,cs_check_overflow]*current_settings.localswitches<>[] then
                                 internalerror(2017032701);
-                              inserttypeconv(tcallparanode(left).left,tcallparanode(tcallparanode(left).right).left.resultdef);
+                              if inlinenumber in [in_sar_assign_x_y,in_shl_assign_x_y,in_shr_assign_x_y,in_rol_assign_x_y,in_ror_assign_x_y] then
+                                inserttypeconv(tcallparanode(left).left,sinttype)
+                              else
+                                inserttypeconv(tcallparanode(left).left,tcallparanode(tcallparanode(left).right).left.resultdef);
                             end
                           else
                             CGMessagePos(left.fileinfo,type_e_ordinal_expr_expected);
@@ -3629,9 +3637,14 @@ implementation
 
           in_and_assign_x_y,
           in_or_assign_x_y,
-          in_xor_assign_x_y:
+          in_xor_assign_x_y,
+          in_sar_assign_x_y,
+          in_shl_assign_x_y,
+          in_shr_assign_x_y,
+          in_rol_assign_x_y,
+          in_ror_assign_x_y:
             begin
-              result:=first_AndOrXor_assign;
+              result:=first_AndOrXorShiftRot_assign;
             end;
 
           in_neg_assign_x,
@@ -4655,7 +4668,7 @@ implementation
        end;
 
 
-     function tinlinenode.first_AndOrXor_assign: tnode;
+     function tinlinenode.first_AndOrXorShiftRot_assign: tnode;
        begin
          result:=nil;
          expectloc:=tcallparanode(tcallparanode(left).right).left.expectloc;

+ 5 - 0
rtl/inc/innr.inc

@@ -97,6 +97,11 @@ const
    fpc_in_and_assign_x_y    = 86;
    fpc_in_or_assign_x_y     = 87;
    fpc_in_xor_assign_x_y    = 88;
+   fpc_in_sar_assign_x_y    = 89;
+   fpc_in_shl_assign_x_y    = 90;
+   fpc_in_shr_assign_x_y    = 91;
+   fpc_in_rol_assign_x_y    = 92;
+   fpc_in_ror_assign_x_y    = 93;
    fpc_in_neg_assign_x      = 94;
    fpc_in_not_assign_x      = 95;