Prechádzať zdrojové kódy

* fixed wrong register deallocations in several ansistring related
procedures. The IDE's now function fine when compiled with -OG3p3r

Jonas Maebe 25 rokov pred
rodič
commit
c1df09f993
3 zmenil súbory, kde vykonal 64 pridanie a 67 odobranie
  1. 18 13
      compiler/cg386add.pas
  2. 30 36
      compiler/cg386cnv.pas
  3. 16 18
      compiler/cgai386.pas

+ 18 - 13
compiler/cg386add.pas

@@ -304,7 +304,7 @@ implementation
                              { *** redefining a type is not allowed!! (thanks, Pierre) }
                              { *** redefining a type is not allowed!! (thanks, Pierre) }
                              { also problem with constant string!                      }
                              { also problem with constant string!                      }
                              pstringdef(p^.left^.resulttype)^.len := 255;
                              pstringdef(p^.left^.resulttype)^.len := 255;
-                             
+
 {$endif newoptimizations2}
 {$endif newoptimizations2}
                           end;
                           end;
 
 
@@ -638,22 +638,23 @@ implementation
             subn,
             subn,
          symdifn,
          symdifn,
             muln : begin
             muln : begin
-{$IfNDef regallocfix}
-                     del_location(p^.left^.location);
-                     del_location(p^.right^.location);
-                     pushusedregisters(pushedregs,$ff);
-{$EndIf regallocfix}
+                     { Find out which registers have to pushed (JM) }
+                     regstopush := $ff;
+                     remove_non_regvars_from_loc(p^.left^.location,regstopush);
+                     remove_non_regvars_from_loc(p^.right^.location,regstopush);
+                     { Push them (JM) }
+                     pushusedregisters(pushedregs,regstopush);
                      href.symbol:=nil;
                      href.symbol:=nil;
                      gettempofsizereference(32,href);
                      gettempofsizereference(32,href);
                      emitpushreferenceaddr(href);
                      emitpushreferenceaddr(href);
-                     emitpushreferenceaddr(p^.right^.location.reference);
-{$IfDef regallocfix}
+                     { Release the registers right before they're used,  }
+                     { see explanation in cgai386.pas:loadansistring for }
+                     { info why this is done right before the push (JM)  }
                      del_location(p^.right^.location);
                      del_location(p^.right^.location);
-{$EndIf regallocfix}
-                     emitpushreferenceaddr(p^.left^.location.reference);
-{$IfDef regallocfix}
+                     emitpushreferenceaddr(p^.right^.location.reference);
+                     { The same here }
                      del_location(p^.left^.location);
                      del_location(p^.left^.location);
-{$EndIf regallocfix}
+                     emitpushreferenceaddr(p^.left^.location.reference);
                      case p^.treetype of
                      case p^.treetype of
                       subn : emitcall('FPC_SET_SUB_SETS');
                       subn : emitcall('FPC_SET_SUB_SETS');
                    symdifn : emitcall('FPC_SET_SYMDIF_SETS');
                    symdifn : emitcall('FPC_SET_SYMDIF_SETS');
@@ -2376,7 +2377,11 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.101  2000-04-25 14:43:36  jonas
+  Revision 1.102  2000-05-26 20:16:00  jonas
+    * fixed wrong register deallocations in several ansistring related
+      procedures. The IDE's now function fine when compiled with -OG3p3r
+
+  Revision 1.101  2000/04/25 14:43:36  jonas
     - disabled "string_var := string_var + ... " and "string_var + char_var"
     - disabled "string_var := string_var + ... " and "string_var + char_var"
       optimizations (were only active with -dnewoptimizations) because of
       optimizations (were only active with -dnewoptimizations) because of
       several internal issues
       several internal issues

+ 30 - 36
compiler/cg386cnv.pas

@@ -189,39 +189,34 @@ implementation
     procedure loadansi2short(source,dest : ptree);
     procedure loadansi2short(source,dest : ptree);
       var
       var
          pushed : tpushed;
          pushed : tpushed;
+         regs_to_push: byte;
       begin
       begin
-         del_reference(dest^.location.reference);
+         { Find out which registers have to be pushed (JM) }
+         regs_to_push := $ff;
+         remove_non_regvars_from_loc(source^.location,regs_to_push);
+         remove_non_regvars_from_loc(dest^.location,regs_to_push);
+         { Push them (JM) }
+         pushusedregisters(pushed,regs_to_push);
          case source^.location.loc of
          case source^.location.loc of
            LOC_REFERENCE,LOC_MEM:
            LOC_REFERENCE,LOC_MEM:
              begin
              begin
+                { Now release the location and registers (see cgai386.pas: }
+                { loadansistring for more info on the order) (JM)          }
                 ungetiftemp(source^.location.reference);
                 ungetiftemp(source^.location.reference);
-{$IfNDef regallocfix}
                 del_reference(source^.location.reference);
                 del_reference(source^.location.reference);
-                pushusedregisters(pushed,$ff);
                 emit_push_mem(source^.location.reference);
                 emit_push_mem(source^.location.reference);
-{$Else regallocfix}
-                 pushusedregisters(pushed,$ff
-                   xor ($80 shr byte(source^.location.reference.base))
-                   xor ($80 shr byte(source^.location.reference.index)));
-                 emit_push_mem(source^.location.reference);
-                 del_reference(source^.location.reference);
-{$EndIf regallocfix}
              end;
              end;
            LOC_REGISTER,LOC_CREGISTER:
            LOC_REGISTER,LOC_CREGISTER:
              begin
              begin
-{$IfNDef regallocfix}
-                ungetregister32(source^.location.register);
-                pushusedregisters(pushed,$ff);
                 emit_reg(A_PUSH,S_L,source^.location.register);
                 emit_reg(A_PUSH,S_L,source^.location.register);
-{$Else regallocfix}
-                 pushusedregisters(pushed, $ff xor ($80 shr byte(source^.location.register)));
-                 emit_reg(A_PUSH,S_L,source^.location.register);
-                 ungetregister32(source^.location.register);
-{$EndIf regallocfix}
+                { Now release the register (JM) }
+                ungetregister32(source^.location.register);
              end;
              end;
          end;
          end;
          push_shortstring_length(dest);
          push_shortstring_length(dest);
          emitpushreferenceaddr(dest^.location.reference);
          emitpushreferenceaddr(dest^.location.reference);
+         { Only now release the destination (JM) }
+         del_reference(dest^.location.reference);
          emitcall('FPC_ANSISTR_TO_SHORTSTR');
          emitcall('FPC_ANSISTR_TO_SHORTSTR');
          popusedregisters(pushed);
          popusedregisters(pushed);
          maybe_loadesi;
          maybe_loadesi;
@@ -1251,6 +1246,7 @@ implementation
     procedure second_pchar_to_string(var pto,pfrom : ptree;convtyp : tconverttype);
     procedure second_pchar_to_string(var pto,pfrom : ptree;convtyp : tconverttype);
       var
       var
         pushed : tpushed;
         pushed : tpushed;
+        regs_to_push: byte;
       begin
       begin
          case pstringdef(pto^.resulttype)^.string_typ of
          case pstringdef(pto^.resulttype)^.string_typ of
            st_shortstring:
            st_shortstring:
@@ -1266,8 +1262,10 @@ implementation
                      end;
                      end;
                    LOC_REFERENCE,LOC_MEM:
                    LOC_REFERENCE,LOC_MEM:
                      begin
                      begin
-                        emit_push_mem(pfrom^.location.reference);
+                       { Now release the registers (see cgai386.pas:     }
+                       { loadansistring for more info on the order) (JM) }
                         del_reference(pfrom^.location.reference);
                         del_reference(pfrom^.location.reference);
+                        emit_push_mem(pfrom^.location.reference);
                      end;
                      end;
                 end;
                 end;
                 emitpushreferenceaddr(pto^.location.reference);
                 emitpushreferenceaddr(pto^.location.reference);
@@ -1280,32 +1278,24 @@ implementation
                 pto^.location.loc:=LOC_REFERENCE;
                 pto^.location.loc:=LOC_REFERENCE;
                 gettempansistringreference(pto^.location.reference);
                 gettempansistringreference(pto^.location.reference);
                 decrstringref(cansistringdef,pto^.location.reference);
                 decrstringref(cansistringdef,pto^.location.reference);
+                { Find out which regs have to be pushed (JM) }
+                regs_to_push := $ff;
+                remove_non_regvars_from_loc(pfrom^.location,regs_to_push);
+                pushusedregisters(pushed,regs_to_push);
                 case pfrom^.location.loc of
                 case pfrom^.location.loc of
                   LOC_REFERENCE,LOC_MEM:
                   LOC_REFERENCE,LOC_MEM:
                     begin
                     begin
-{$IfNDef regallocfix}
+                      { Now release the registers (see cgai386.pas:     }
+                      { loadansistring for more info on the order) (JM) }
                       del_reference(pfrom^.location.reference);
                       del_reference(pfrom^.location.reference);
-                      pushusedregisters(pushed,$ff);
-                      emit_push_mem(pfrom^.location.reference);
-{$Else regallocfix}
-                      pushusedregisters(pushed,$ff
-                        xor ($80 shr byte(pfrom^.location.reference.base))
-                        xor ($80 shr byte(pfrom^.location.reference.index)));
                       emit_push_mem(pfrom^.location.reference);
                       emit_push_mem(pfrom^.location.reference);
-                      del_reference(pfrom^.location.reference);
-{$EndIf regallocfix}
                     end;
                     end;
                   LOC_REGISTER,LOC_CREGISTER:
                   LOC_REGISTER,LOC_CREGISTER:
                     begin
                     begin
-{$IfNDef regallocfix}
-                      ungetregister32(pfrom^.location.register);
-                      pushusedregisters(pushed,$ff);
-                      emit_reg(A_PUSH,S_L,pfrom^.location.register);
-{$Else regallocfix}
-                      pushusedregisters(pushed, $ff xor ($80 shr byte(pfrom^.location.register)));
+                       { Now release the registers (see cgai386.pas:     }
+                       { loadansistring for more info on the order) (JM) }
                       emit_reg(A_PUSH,S_L,pfrom^.location.register);
                       emit_reg(A_PUSH,S_L,pfrom^.location.register);
                       ungetregister32(pfrom^.location.register);
                       ungetregister32(pfrom^.location.register);
-{$EndIf regallocfix}
                    end;
                    end;
                 end;
                 end;
                 emitpushreferenceaddr(pto^.location.reference);
                 emitpushreferenceaddr(pto^.location.reference);
@@ -1537,7 +1527,11 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.105  2000-04-10 12:23:19  jonas
+  Revision 1.106  2000-05-26 20:16:00  jonas
+    * fixed wrong register deallocations in several ansistring related
+      procedures. The IDE's now function fine when compiled with -OG3p3r
+
+  Revision 1.105  2000/04/10 12:23:19  jonas
     * modified copyshortstring so it takes an extra paramter which allows it
     * modified copyshortstring so it takes an extra paramter which allows it
       to delete the sref itself (so the reg deallocations are put in the
       to delete the sref itself (so the reg deallocations are put in the
       right place for the optimizer)
       right place for the optimizer)

+ 16 - 18
compiler/cgai386.pas

@@ -994,6 +994,7 @@ procedure mov_reg_to_dest(p : ptree; s : topsize; reg : tregister);
     }
     }
       var
       var
          pushed : tpushed;
          pushed : tpushed;
+         regs_to_push: byte;
          ungettemp : boolean;
          ungettemp : boolean;
       begin
       begin
          { before pushing any parameter, we have to save all used      }
          { before pushing any parameter, we have to save all used      }
@@ -1003,35 +1004,28 @@ procedure mov_reg_to_dest(p : ptree; s : topsize; reg : tregister);
 
 
          { nevertheless, this has to be changed, because otherwise the }
          { nevertheless, this has to be changed, because otherwise the }
          { register is released before it's contents are pushed ->     }
          { register is released before it's contents are pushed ->     }
-         { problems with the optimizer (JM)                         }
+         { problems with the optimizer (JM)                            }
          del_reference(p^.left^.location.reference);
          del_reference(p^.left^.location.reference);
          ungettemp:=false;
          ungettemp:=false;
+         { Find out which registers have to be pushed (JM) }
+         regs_to_push := $ff;
+         remove_non_regvars_from_loc(p^.right^.location,regs_to_push);
+         { And push them (JM) }
+         pushusedregisters(pushed,regs_to_push);
          case p^.right^.location.loc of
          case p^.right^.location.loc of
             LOC_REGISTER,LOC_CREGISTER:
             LOC_REGISTER,LOC_CREGISTER:
               begin
               begin
-{$IfNDef regallocfix}
-                 ungetregister32(p^.right^.location.register);
-                 pushusedregisters(pushed,$ff);
-                 exprasmlist^.concat(new(paicpu,op_reg(A_PUSH,S_L,p^.right^.location.register)));
-{$Else regallocfix}
-                 pushusedregisters(pushed, $ff xor ($80 shr byte(p^.right^.location.register)));
                  exprasmlist^.concat(new(paicpu,op_reg(A_PUSH,S_L,p^.right^.location.register)));
                  exprasmlist^.concat(new(paicpu,op_reg(A_PUSH,S_L,p^.right^.location.register)));
                  ungetregister32(p^.right^.location.register);
                  ungetregister32(p^.right^.location.register);
-{$EndIf regallocfix}
               end;
               end;
             LOC_REFERENCE,LOC_MEM:
             LOC_REFERENCE,LOC_MEM:
               begin
               begin
-{$IfNDef regallocfix}
+                 { First release the registers because emit_push_mem may  }
+                 { load the reference in edi before pushing and then the  }
+                 { dealloc is too late (and optimizations are missed (JM) }
                  del_reference(p^.right^.location.reference);
                  del_reference(p^.right^.location.reference);
-                 pushusedregisters(pushed,$ff);
+                 { This one doesn't need extra registers (JM) }
                  emit_push_mem(p^.right^.location.reference);
                  emit_push_mem(p^.right^.location.reference);
-{$Else regallocfix}
-                 pushusedregisters(pushed,$ff
-                   xor ($80 shr byte(p^.right^.location.reference.base))
-                   xor ($80 shr byte(p^.right^.location.reference.index)));
-                 emit_push_mem(p^.right^.location.reference);
-                 del_reference(p^.right^.location.reference);
-{$EndIf regallocfix}
                  ungettemp:=true;
                  ungettemp:=true;
               end;
               end;
          end;
          end;
@@ -3968,7 +3962,11 @@ procedure mov_reg_to_dest(p : ptree; s : topsize; reg : tregister);
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.105  2000-05-23 14:20:49  pierre
+  Revision 1.106  2000-05-26 20:16:00  jonas
+    * fixed wrong register deallocations in several ansistring related
+      procedures. The IDE's now function fine when compiled with -OG3p3r
+
+  Revision 1.105  2000/05/23 14:20:49  pierre
    * Use stacksize param instead of gettempsize
    * Use stacksize param instead of gettempsize
 
 
   Revision 1.104  2000/05/18 17:05:15  peter
   Revision 1.104  2000/05/18 17:05:15  peter