Sfoglia il codice sorgente

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

Jonas Maebe 25 anni fa
parent
commit
c1df09f993
3 ha cambiato i file con 64 aggiunte e 67 eliminazioni
  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) }
                              { also problem with constant string!                      }
                              pstringdef(p^.left^.resulttype)^.len := 255;
-                             
+
 {$endif newoptimizations2}
                           end;
 
@@ -638,22 +638,23 @@ implementation
             subn,
          symdifn,
             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;
                      gettempofsizereference(32,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);
-{$EndIf regallocfix}
-                     emitpushreferenceaddr(p^.left^.location.reference);
-{$IfDef regallocfix}
+                     emitpushreferenceaddr(p^.right^.location.reference);
+                     { The same here }
                      del_location(p^.left^.location);
-{$EndIf regallocfix}
+                     emitpushreferenceaddr(p^.left^.location.reference);
                      case p^.treetype of
                       subn : emitcall('FPC_SET_SUB_SETS');
                    symdifn : emitcall('FPC_SET_SYMDIF_SETS');
@@ -2376,7 +2377,11 @@ implementation
 end.
 {
   $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"
       optimizations (were only active with -dnewoptimizations) because of
       several internal issues

+ 30 - 36
compiler/cg386cnv.pas

@@ -189,39 +189,34 @@ implementation
     procedure loadansi2short(source,dest : ptree);
       var
          pushed : tpushed;
+         regs_to_push: byte;
       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
            LOC_REFERENCE,LOC_MEM:
              begin
+                { Now release the location and registers (see cgai386.pas: }
+                { loadansistring for more info on the order) (JM)          }
                 ungetiftemp(source^.location.reference);
-{$IfNDef regallocfix}
                 del_reference(source^.location.reference);
-                pushusedregisters(pushed,$ff);
                 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;
            LOC_REGISTER,LOC_CREGISTER:
              begin
-{$IfNDef regallocfix}
-                ungetregister32(source^.location.register);
-                pushusedregisters(pushed,$ff);
                 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;
          push_shortstring_length(dest);
          emitpushreferenceaddr(dest^.location.reference);
+         { Only now release the destination (JM) }
+         del_reference(dest^.location.reference);
          emitcall('FPC_ANSISTR_TO_SHORTSTR');
          popusedregisters(pushed);
          maybe_loadesi;
@@ -1251,6 +1246,7 @@ implementation
     procedure second_pchar_to_string(var pto,pfrom : ptree;convtyp : tconverttype);
       var
         pushed : tpushed;
+        regs_to_push: byte;
       begin
          case pstringdef(pto^.resulttype)^.string_typ of
            st_shortstring:
@@ -1266,8 +1262,10 @@ implementation
                      end;
                    LOC_REFERENCE,LOC_MEM:
                      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);
+                        emit_push_mem(pfrom^.location.reference);
                      end;
                 end;
                 emitpushreferenceaddr(pto^.location.reference);
@@ -1280,32 +1278,24 @@ implementation
                 pto^.location.loc:=LOC_REFERENCE;
                 gettempansistringreference(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
                   LOC_REFERENCE,LOC_MEM:
                     begin
-{$IfNDef regallocfix}
+                      { Now release the registers (see cgai386.pas:     }
+                      { loadansistring for more info on the order) (JM) }
                       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);
-                      del_reference(pfrom^.location.reference);
-{$EndIf regallocfix}
                     end;
                   LOC_REGISTER,LOC_CREGISTER:
                     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);
                       ungetregister32(pfrom^.location.register);
-{$EndIf regallocfix}
                    end;
                 end;
                 emitpushreferenceaddr(pto^.location.reference);
@@ -1537,7 +1527,11 @@ implementation
 end.
 {
   $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
       to delete the sref itself (so the reg deallocations are put in the
       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
          pushed : tpushed;
+         regs_to_push: byte;
          ungettemp : boolean;
       begin
          { 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 }
          { 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);
          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
             LOC_REGISTER,LOC_CREGISTER:
               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)));
                  ungetregister32(p^.right^.location.register);
-{$EndIf regallocfix}
               end;
             LOC_REFERENCE,LOC_MEM:
               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);
-                 pushusedregisters(pushed,$ff);
+                 { This one doesn't need extra registers (JM) }
                  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;
               end;
          end;
@@ -3968,7 +3962,11 @@ procedure mov_reg_to_dest(p : ptree; s : topsize; reg : tregister);
 end.
 {
   $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
 
   Revision 1.104  2000/05/18 17:05:15  peter