2
0
Эх сурвалжийг харах

* optimizations and bugfix

Jonas Maebe 23 жил өмнө
parent
commit
856d8f9150
1 өөрчлөгдсөн 70 нэмэгдсэн , 92 устгасан
  1. 70 92
      compiler/ncgset.pas

+ 70 - 92
compiler/ncgset.pas

@@ -48,16 +48,16 @@ interface
           procedure emit_bit_test_reg_reg(list : taasmoutput; bitnumber : tregister;
           procedure emit_bit_test_reg_reg(list : taasmoutput; bitnumber : tregister;
              value : tregister; __result :tregister);virtual;
              value : tregister; __result :tregister);virtual;
        end;
        end;
-       
+
        tcgcasenode = class(tcasenode)
        tcgcasenode = class(tcasenode)
-          { 
+          {
             Emits the case node statement. Contrary to the intel
             Emits the case node statement. Contrary to the intel
             80x86 version, this version does not emit jump tables,
             80x86 version, this version does not emit jump tables,
             because of portability problems.
             because of portability problems.
-          }  
+          }
           procedure pass_2;override;
           procedure pass_2;override;
        end;
        end;
-       
+
 
 
 implementation
 implementation
 
 
@@ -158,13 +158,13 @@ implementation
              compares,maxcompares:word;
              compares,maxcompares:word;
              i:byte;
              i:byte;
            begin
            begin
-         if Aset=[] then
-        {The expression...
-            if expr in []
-         ...is allways false. It should be optimized away in the
-         resulttype pass, and thus never occur here. Since we
-         do generate wrong code for it, do internalerror.}
-        internalerror(2002072301);
+             if Aset=[] then
+              {The expression...
+                  if expr in []
+               ...is allways false. It should be optimized away in the
+               resulttype pass, and thus never occur here. Since we
+               do generate wrong code for it, do internalerror.}
+              internalerror(2002072301);
              analizeset:=false;
              analizeset:=false;
              ranges:=false;
              ranges:=false;
              numparts:=0;
              numparts:=0;
@@ -262,11 +262,12 @@ implementation
          location_reset(location,LOC_REGISTER,OS_INT);
          location_reset(location,LOC_REGISTER,OS_INT);
          { allocate a register for the result }
          { allocate a register for the result }
          location.register := rg.getregisterint(exprasmlist);
          location.register := rg.getregisterint(exprasmlist);
-         { Get a label to jump to the end }
-         getlabel(l);
 
 
          if genjumps then
          if genjumps then
           begin
           begin
+            { Get a label to jump to the end }
+            getlabel(l);
+
             { clear the register value, indicating result is FALSE }
             { clear the register value, indicating result is FALSE }
             cg.a_load_const_reg(exprasmlist,OS_INT,0,location.register);
             cg.a_load_const_reg(exprasmlist,OS_INT,0,location.register);
             opsize := def_cgsize(left.resulttype.def);
             opsize := def_cgsize(left.resulttype.def);
@@ -413,22 +414,12 @@ implementation
                     else
                     else
                       internalerror(200203312);
                       internalerror(200203312);
                   end;
                   end;
-                 { then do AND with constant and register }
-                 cg.a_op_const_reg(exprasmlist,OP_AND,1 shl
-                    (tordconstnode(left).value and 31),hr);
-                 { if the value in the AND register is <> 0 then the value is equal. }
-                 cg.a_cmp_const_reg_label(exprasmlist,OS_32,OC_EQ,1 shl
-                    (tordconstnode(left).value and 31),hr,l);
-                 cg.free_scratch_reg(exprasmlist,hr);
-                 getlabel(l3);
-                 cg.a_jmp_always(exprasmlist,l3);
-                 { Now place the end label if IN success }
-                 cg.a_label(exprasmlist,l);
-                 { result register is 1 : LOC_JUMP }
-                 cg.a_load_const_reg(exprasmlist,OS_INT,1,location.register);
-                 { in case value is not found }
-                 cg.a_label(exprasmlist,l3);
                  location_release(exprasmlist,right.location);
                  location_release(exprasmlist,right.location);
+                 { then do SHR tge register }
+                 cg.a_op_const_reg(exprasmlist,OP_SHR,
+                    tordconstnode(left).value and 31,hr);
+                 { then extract the lowest bit }
+                 cg.a_op_const_reg(exprasmlist,OP_AND,1,hr);
                 end
                 end
                else
                else
                 begin
                 begin
@@ -498,20 +489,10 @@ implementation
                 begin
                 begin
                   { this section has not been tested!    }
                   { this section has not been tested!    }
                   { can it actually occur currently? CEC }
                   { can it actually occur currently? CEC }
-                  internalerror(20020610);
+                  { yes: "if bytevar in [1,3,5,7,9,11,13,15]" (JM) }
                   getlabel(l);
                   getlabel(l);
                   getlabel(l2);
                   getlabel(l2);
 
 
-                  { Is this treated in firstpass ?? }
-                  if left.nodetype=ordconstn then
-                    begin
-                      hr:=rg.getregisterint(exprasmlist);
-                      left.location.loc:=LOC_REGISTER;
-                      left.location.size:=OS_INT;
-                      left.location.register:=hr;
-                      cg.a_load_const_reg(exprasmlist,OS_INT,
-                            tordconstnode(left).value,hr);
-                    end;
                   case left.location.loc of
                   case left.location.loc of
                      LOC_REGISTER,
                      LOC_REGISTER,
                      LOC_CREGISTER:
                      LOC_CREGISTER:
@@ -527,20 +508,22 @@ implementation
                           hr2:=rg.getregisterint(exprasmlist);
                           hr2:=rg.getregisterint(exprasmlist);
                           cg.a_load_const_reg(exprasmlist,OS_INT,right.location.value,hr2);
                           cg.a_load_const_reg(exprasmlist,OS_INT,right.location.value,hr2);
                        end;
                        end;
-                  else
-                    begin
-                       cg.a_cmp_const_ref_label(exprasmlist,OS_8,OC_BE,31,left.location.reference,l);
-                       cg.a_jmp_always(exprasmlist,l2);
-                       cg.a_label(exprasmlist,l);
-                       location_release(exprasmlist,left.location);
-                       hr:=rg.getregisterint(exprasmlist);
-                       cg.a_load_ref_reg(exprasmlist,OS_32,left.location.reference,hr);
-                     { We have to load the value into a register because
-                       btl does not accept values only refs or regs (PFV) }
-                       hr2:=rg.getregisterint(exprasmlist);
-                       cg.a_load_const_reg(exprasmlist,OS_INT,
-                         right.location.value,hr2);
-                    end;
+                     LOC_REFERENCE,LOC_CREFERENCE:
+                       begin
+                          cg.a_cmp_const_ref_label(exprasmlist,OS_8,OC_BE,31,left.location.reference,l);
+                          cg.a_jmp_always(exprasmlist,l2);
+                          cg.a_label(exprasmlist,l);
+                          location_release(exprasmlist,left.location);
+                          hr:=rg.getregisterint(exprasmlist);
+                          cg.a_load_ref_reg(exprasmlist,OS_32,left.location.reference,hr);
+                        { We have to load the value into a register because
+                          btl does not accept values only refs or regs (PFV) }
+                          hr2:=rg.getregisterint(exprasmlist);
+                          cg.a_load_const_reg(exprasmlist,OS_INT,
+                            right.location.value,hr2);
+                       end;
+                     else
+                       internalerror(2002081002);
                   end;
                   end;
                   { emit bit test operation }
                   { emit bit test operation }
                   emit_bit_test_reg_reg(exprasmlist,hr,hr2,location.register);
                   emit_bit_test_reg_reg(exprasmlist,hr,hr2,location.register);
@@ -553,21 +536,13 @@ implementation
                  but also used if the left side contains higher values > 32 }
                  but also used if the left side contains higher values > 32 }
                else if left.nodetype=ordconstn then
                else if left.nodetype=ordconstn then
                 begin
                 begin
-                  getlabel(l2);
-                  getlabel(l);
                   { use location.register as scratch register here }
                   { use location.register as scratch register here }
                   inc(right.location.reference.offset,tordconstnode(left).value shr 3);
                   inc(right.location.reference.offset,tordconstnode(left).value shr 3);
                   cg.a_load_ref_reg(exprasmlist, OS_8, right.location.reference, location.register);
                   cg.a_load_ref_reg(exprasmlist, OS_8, right.location.reference, location.register);
-                  cg.a_op_const_reg(exprasmlist, OP_AND,1 shl (tordconstnode(left).value and 7),
-                     location.register);
-                  cg.a_cmp_const_reg_label(exprasmlist,OS_8, OC_NE,0,location.register,l2);
-                  cg.a_load_const_reg(exprasmlist, OS_INT,0, location.register);
-                  cg.a_jmp_always(exprasmlist,l);
-                  cg.a_label(exprasmlist,l2);
-                  cg.a_load_const_reg(exprasmlist, OS_INT,1, location.register);
-                  {emit_const_ref(A_TEST,S_B,1 shl (tordconstnode(left).value and 7),right.location.reference);}
-                  cg.a_label(exprasmlist,l);
                   location_release(exprasmlist,right.location);
                   location_release(exprasmlist,right.location);
+                  cg.a_op_const_reg(exprasmlist,OP_SHR, tordconstnode(left).value and 7,
+                    location.register);
+                  cg.a_op_const_reg(exprasmlist, OP_AND,1,location.register);
                 end
                 end
                else
                else
                 begin
                 begin
@@ -592,7 +567,7 @@ implementation
           end;
           end;
           location_freetemp(exprasmlist,right.location);
           location_freetemp(exprasmlist,right.location);
        end;
        end;
-       
+
 {*****************************************************************************
 {*****************************************************************************
                             TCGCASENODE
                             TCGCASENODE
 *****************************************************************************}
 *****************************************************************************}
@@ -601,7 +576,7 @@ implementation
       var
       var
          with_sign : boolean;
          with_sign : boolean;
          opsize : tcgsize;
          opsize : tcgsize;
-         jmp_gt,jmp_le,jmp_lee : topcmp;
+         jmp_gt,jmp_lt,jmp_le : topcmp;
          hp : tnode;
          hp : tnode;
          { register with case expression }
          { register with case expression }
          hregister,hregister2 : tregister;
          hregister,hregister2 : tregister;
@@ -637,14 +612,14 @@ implementation
                 end
                 end
               else
               else
                 begin
                 begin
-                  cg.a_cmp_const_reg_label(exprasmlist,OS_INT, jmp_le,p^._low,hregister, lesslabel);
+                  cg.a_cmp_const_reg_label(exprasmlist,OS_INT, jmp_lt,p^._low,hregister, lesslabel);
                   cg.a_cmp_const_reg_label(exprasmlist,OS_INT, jmp_gt,p^._low,hregister, greaterlabel);
                   cg.a_cmp_const_reg_label(exprasmlist,OS_INT, jmp_gt,p^._low,hregister, greaterlabel);
                 end;
                 end;
               cg.a_jmp_always(exprasmlist,p^.statement);
               cg.a_jmp_always(exprasmlist,p^.statement);
            end
            end
          else
          else
            begin
            begin
-              cg.a_cmp_const_reg_label(exprasmlist,OS_INT,jmp_le,p^._low, hregister, lesslabel);
+              cg.a_cmp_const_reg_label(exprasmlist,OS_INT,jmp_lt,p^._low, hregister, lesslabel);
               cg.a_cmp_const_reg_label(exprasmlist,OS_INT,jmp_gt,p^._high,hregister, greaterlabel);
               cg.a_cmp_const_reg_label(exprasmlist,OS_INT,jmp_gt,p^._high,hregister, greaterlabel);
               cg.a_jmp_always(exprasmlist,p^.statement);
               cg.a_jmp_always(exprasmlist,p^.statement);
            end;
            end;
@@ -679,23 +654,23 @@ implementation
                     end
                     end
                   else
                   else
                     begin
                     begin
-                       cg.a_cmp_const_reg_label(exprasmlist, OS_INT, OC_EQ,longint(t^._low) ,hregister, t^.statement);
+                       cg.a_cmp_const_reg_label(exprasmlist, OS_INT, OC_EQ, longint(t^._low),hregister, t^.statement);
                        last:=t^._low;
                        last:=t^._low;
                     end;
                     end;
                end
                end
              else
              else
                begin
                begin
-                  { if there is no unused label between the last and the }
-                  { present label then the lower limit can be checked    }
-                  { immediately. else check the range in between:        }
+                  { it begins with the smallest label, if the value }
+                  { is even smaller then jump immediately to the    }
+                  { ELSE-label                                }
                   if first or (t^._low-last>1) then
                   if first or (t^._low-last>1) then
                     begin
                     begin
                        if opsize in [OS_64,OS_S64] then
                        if opsize in [OS_64,OS_S64] then
                          begin
                          begin
                             getlabel(l1);
                             getlabel(l1);
-                            cg.a_cmp_const_reg_label(exprasmlist, OS_INT, jmp_le, longint(hi(int64(t^._low))), 
+                            cg.a_cmp_const_reg_label(exprasmlist, OS_INT, jmp_lt, longint(hi(int64(t^._low))),
                                  hregister2, elselabel);
                                  hregister2, elselabel);
-                            cg.a_cmp_const_reg_label(exprasmlist, OS_INT, jmp_gt, longint(hi(int64(t^._low))), 
+                            cg.a_cmp_const_reg_label(exprasmlist, OS_INT, jmp_gt, longint(hi(int64(t^._low))),
                                  hregister2, l1);
                                  hregister2, l1);
                             { the comparisation of the low dword must be always unsigned! }
                             { the comparisation of the low dword must be always unsigned! }
                             cg.a_cmp_const_reg_label(exprasmlist, OS_INT, OC_B, longint(lo(int64(t^._low))), hregister, elselabel);
                             cg.a_cmp_const_reg_label(exprasmlist, OS_INT, OC_B, longint(lo(int64(t^._low))), hregister, elselabel);
@@ -703,7 +678,7 @@ implementation
                          end
                          end
                        else
                        else
                          begin
                          begin
-                          cg.a_cmp_const_reg_label(exprasmlist, OS_INT, jmp_le, longint(t^._low), hregister, 
+                          cg.a_cmp_const_reg_label(exprasmlist, OS_INT, jmp_lt, longint(t^._low), hregister,
                              elselabel);
                              elselabel);
                          end;
                          end;
                     end;
                     end;
@@ -711,16 +686,16 @@ implementation
                   if opsize in [OS_S64,OS_64] then
                   if opsize in [OS_S64,OS_64] then
                     begin
                     begin
                        getlabel(l1);
                        getlabel(l1);
-                       cg.a_cmp_const_reg_label(exprasmlist, OS_INT, jmp_le, longint(hi(int64(t^._high))), hregister2, 
+                       cg.a_cmp_const_reg_label(exprasmlist, OS_INT, jmp_lt, longint(hi(int64(t^._high))), hregister2,
                              t^.statement);
                              t^.statement);
-                       cg.a_cmp_const_reg_label(exprasmlist, OS_INT, jmp_gt, longint(hi(int64(t^._high))), hregister2, 
+                       cg.a_cmp_const_reg_label(exprasmlist, OS_INT, jmp_gt, longint(hi(int64(t^._high))), hregister2,
                              l1);
                              l1);
                       cg.a_cmp_const_reg_label(exprasmlist, OS_INT, OC_BE, longint(lo(int64(t^._high))), hregister, t^.statement);
                       cg.a_cmp_const_reg_label(exprasmlist, OS_INT, OC_BE, longint(lo(int64(t^._high))), hregister, t^.statement);
                       cg.a_label(exprasmlist,l1);
                       cg.a_label(exprasmlist,l1);
                     end
                     end
                   else
                   else
                     begin
                     begin
-                       cg.a_cmp_const_reg_label(exprasmlist, OS_INT, jmp_lee,longint(t^._high) , hregister, t^.statement);
+                       cg.a_cmp_const_reg_label(exprasmlist, OS_INT, jmp_le, longint(t^._high), hregister, t^.statement);
                     end;
                     end;
 
 
                   last:=t^._high;
                   last:=t^._high;
@@ -742,14 +717,14 @@ implementation
         var
         var
            first : boolean;
            first : boolean;
            last : TConstExprInt;
            last : TConstExprInt;
-           scratch_reg : tregister;
+           scratch_reg: tregister;
 
 
         procedure genitem(t : pcaserecord);
         procedure genitem(t : pcaserecord);
 
 
             procedure gensub(value:longint);
             procedure gensub(value:longint);
             begin
             begin
-              { here, since the sub and cmp are separate we need 
-                to move the result before subtract to a help 
+              { here, since the sub and cmp are separate we need
+                to move the result before subtract to a help
                 register.
                 register.
               }
               }
               cg.a_load_reg_reg(exprasmlist, opsize, hregister, scratch_reg);
               cg.a_load_reg_reg(exprasmlist, opsize, hregister, scratch_reg);
@@ -762,7 +737,7 @@ implementation
              { need we to test the first value }
              { need we to test the first value }
              if first and (t^._low>get_min_value(left.resulttype.def)) then
              if first and (t^._low>get_min_value(left.resulttype.def)) then
                begin
                begin
-                  cg.a_cmp_const_reg_label(exprasmlist,OS_INT,jmp_le,longint(t^._low),hregister,elselabel);
+                  cg.a_cmp_const_reg_label(exprasmlist,OS_INT,jmp_lt,longint(t^._low),hregister,elselabel);
                end;
                end;
              if t^._low=t^._high then
              if t^._low=t^._high then
                begin
                begin
@@ -773,7 +748,7 @@ implementation
                   else
                   else
                     begin
                     begin
                         gensub(longint(t^._low-last));
                         gensub(longint(t^._low-last));
-                        cg.a_cmp_const_reg_label(exprasmlist, OS_INT, OC_EQ,0,hregister,t^.statement);
+                        cg.a_cmp_const_reg_label(exprasmlist, OS_INT, OC_EQ,longint(t^._low-last),hregister,t^.statement);
                     end;
                     end;
                   last:=t^._low;
                   last:=t^._low;
                end
                end
@@ -794,10 +769,10 @@ implementation
                       { present label then the lower limit can be checked    }
                       { present label then the lower limit can be checked    }
                       { immediately. else check the range in between:       }
                       { immediately. else check the range in between:       }
                       gensub(longint(t^._low-last));
                       gensub(longint(t^._low-last));
-                      cg.a_cmp_const_reg_label(exprasmlist, OS_INT,jmp_le,longint(t^._low-last),scratch_reg,elselabel);
+                      cg.a_cmp_const_reg_label(exprasmlist, OS_INT,jmp_lt,longint(t^._low-last),hregister,elselabel);
                     end;
                     end;
                   gensub(longint(t^._high-t^._low));
                   gensub(longint(t^._high-t^._low));
-                  cg.a_cmp_const_reg_label(exprasmlist, OS_INT,jmp_lee,longint(t^._high-t^._low),scratch_reg,t^.statement);
+                  cg.a_cmp_const_reg_label(exprasmlist, OS_INT,jmp_le,longint(t^._high-t^._low),hregister,t^.statement);
                   last:=t^._high;
                   last:=t^._high;
                end;
                end;
              first:=false;
              first:=false;
@@ -815,8 +790,8 @@ implementation
                 first:=true;
                 first:=true;
                 scratch_reg := cg.get_scratch_reg_int(exprasmlist);
                 scratch_reg := cg.get_scratch_reg_int(exprasmlist);
                 genitem(hp);
                 genitem(hp);
+                cg.free_scratch_reg(exprasmlist);
                 cg.a_jmp_always(exprasmlist,elselabel);
                 cg.a_jmp_always(exprasmlist,elselabel);
-                cg.free_scratch_reg(exprasmlist, scratch_reg);
              end;
              end;
         end;
         end;
 
 
@@ -836,14 +811,14 @@ implementation
          if with_sign then
          if with_sign then
            begin
            begin
               jmp_gt:=OC_GT;
               jmp_gt:=OC_GT;
-              jmp_le:=OC_LT;
-              jmp_lee:=OC_LTE;
+              jmp_lt:=OC_LT;
+              jmp_le:=OC_LTE;
            end
            end
          else
          else
             begin
             begin
               jmp_gt:=OC_A;
               jmp_gt:=OC_A;
-              jmp_le:=OC_B;
-              jmp_lee:=OC_BE;
+              jmp_lt:=OC_B;
+              jmp_le:=OC_BE;
            end;
            end;
          rg.cleartempgen;
          rg.cleartempgen;
          { save current truelabel and falselabel }
          { save current truelabel and falselabel }
@@ -963,7 +938,7 @@ implementation
            end;
            end;
          cg.a_label(exprasmlist,endlabel);
          cg.a_label(exprasmlist,endlabel);
       end;
       end;
-       
+
 
 
 
 
 
 
@@ -974,7 +949,10 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.11  2002-07-28 09:24:18  carl
+  Revision 1.12  2002-08-10 17:15:12  jonas
+    * optimizations and bugfix
+
+  Revision 1.11  2002/07/28 09:24:18  carl
   + generic case node
   + generic case node
 
 
   Revision 1.10  2002/07/23 14:31:00  daniel
   Revision 1.10  2002/07/23 14:31:00  daniel