Browse Source

* fixed wrong regalloc info around FPC_MUL/DIV/MOD_INT64/QWORD calls
* fixed partial result overwriting with the above calls too

Jonas Maebe 24 years ago
parent
commit
14576640c5
2 changed files with 76 additions and 31 deletions
  1. 38 13
      compiler/i386/n386add.pas
  2. 38 18
      compiler/i386/n386mat.pas

+ 38 - 13
compiler/i386/n386add.pas

@@ -686,6 +686,8 @@ interface
       label do_normal;
 
       var
+         unusedregisters : tregisterset;
+         usablecount : byte;
          hregister,hregister2 : tregister;
          noswap,popeax,popedx,
          pushed,mboverflow,cmpop : boolean;
@@ -1657,15 +1659,18 @@ interface
 
                    if nodetype=muln then
                      begin
-                        { save lcoation, because we change it now }
-                        set_location(hloc,location);
-                        release_qword_loc(location);
-                        release_qword_loc(right.location);
-                        location.registerlow:=getexplicitregister32(R_EAX);
-                        location.registerhigh:=getexplicitregister32(R_EDX);
-                        pushusedregisters(pushedreg,$ff
-                          and not($80 shr byte(location.registerlow))
-                          and not($80 shr byte(location.registerhigh)));
+                        regstopush := $ff;
+                        remove_non_regvars_from_loc(location,regstopush);
+                        remove_non_regvars_from_loc(right.location,regstopush);
+                        
+                        { ugly hack because in *this* case, the pushed register }
+                        { must not be allocated later on (JM)                   }
+                        unusedregisters:=unused;
+                        usablecount:=usablereg32;
+                        pushusedregisters(pushedreg,regstopush);
+                        unused:=unusedregisters;
+                        usablereg32:=usablecount;
+                        
                         if cs_check_overflow in aktlocalswitches then
                           push_int(1)
                         else
@@ -1673,19 +1678,35 @@ interface
                         { the left operand is in hloc, because the
                           location of left is location but location
                           is already destroyed
+                          
+                          not anymore... I had to change this because the
+                          regalloc info was completely wrong otherwise (JM)
                         }
-                        emit_pushq_loc(hloc);
-                        clear_location(hloc);
+                        emit_pushq_loc(location);
+                        release_qword_loc(location);
+                        clear_location(location);
                         emit_pushq_loc(right.location);
+                        release_qword_loc(right.location);
                         saveregvars($ff);
                         if torddef(resulttype.def).typ=u64bit then
                           emitcall('FPC_MUL_QWORD')
                         else
                           emitcall('FPC_MUL_INT64');
+                        { make sure we don't overwrite any results (JM) }
+                        if R_EDX in unused then
+                          begin
+                             location.registerhigh:=getexplicitregister32(R_EDX);
+                             location.registerlow:=getexplicitregister32(R_EAX);
+                          end
+                        else
+                          begin
+                             location.registerlow:=getexplicitregister32(R_EAX);
+                             location.registerhigh:=getexplicitregister32(R_EDX);
+                          end;
+                        location.loc := LOC_REGISTER;
                         emit_reg_reg(A_MOV,S_L,R_EAX,location.registerlow);
                         emit_reg_reg(A_MOV,S_L,R_EDX,location.registerhigh);
                         popusedregisters(pushedreg);
-                        location.loc:=LOC_REGISTER;
                      end
                    else
                      begin
@@ -2293,7 +2314,11 @@ begin
 end.
 {
   $Log$
-  Revision 1.17  2001-08-26 13:36:55  florian
+  Revision 1.18  2001-08-29 12:03:23  jonas
+    * fixed wrong regalloc info around FPC_MUL/DIV/MOD_INT64/QWORD calls
+    * fixed partial result overwriting with the above calls too
+
+  Revision 1.17  2001/08/26 13:36:55  florian
     * some cg reorganisation
     * some PPC updates
 

+ 38 - 18
compiler/i386/n386mat.pas

@@ -64,6 +64,8 @@ implementation
 
     procedure ti386moddivnode.pass_2;
       var
+         unusedregisters : tregisterset;
+         usablecount, regstopush : byte;
          hreg1 : tregister;
          hreg2 : tregister;
          shrdiv, andmod, pushed,popeax,popedx : boolean;
@@ -86,23 +88,23 @@ implementation
 
          if is_64bitint(resulttype.def) then
            begin
-              { save lcoation, because we change it now }
-              set_location(hloc,location);
+              regstopush := $ff;
+              remove_non_regvars_from_loc(location,regstopush);
+              remove_non_regvars_from_loc(right.location,regstopush);
+              
+              { ugly hack because in *this* case, the pushed register }
+              { must not be allocated later on (JM)                   }
+              unusedregisters:=unused;
+              usablecount:=usablereg32;
+              pushusedregisters(pushedreg,regstopush);
+              unused:=unusedregisters;
+              usablereg32:=usablecount;
+              
+              emit_pushq_loc(location);
               release_qword_loc(location);
-              release_qword_loc(right.location);
-              location.registerlow:=getexplicitregister32(R_EAX);
-              location.registerhigh:=getexplicitregister32(R_EDX);
-              pushusedregisters(pushedreg,$ff
-                and not($80 shr byte(location.registerlow))
-                and not($80 shr byte(location.registerhigh)));
-              { the left operand is in hloc, because the
-                location of left is location but location
-                is already destroyed
-              }
-              emit_pushq_loc(hloc);
-              clear_location(hloc);
+              clear_location(location);
               emit_pushq_loc(right.location);
-
+              release_qword_loc(right.location);
               if torddef(resulttype.def).typ=u64bit then
                 typename:='QWORD'
               else
@@ -114,10 +116,22 @@ implementation
               saveregvars($ff);
               emitcall('FPC_'+opname+typename);
 
+              { make sure we don't overwrite any results (JM) }
+              if R_EDX in unused then
+                begin
+                   location.registerhigh:=getexplicitregister32(R_EDX);
+                   location.registerlow:=getexplicitregister32(R_EAX);
+                end
+              else
+                begin
+                   location.registerlow:=getexplicitregister32(R_EAX);
+                   location.registerhigh:=getexplicitregister32(R_EDX);
+                end;
+              location.loc:=LOC_REGISTER;
               emit_reg_reg(A_MOV,S_L,R_EAX,location.registerlow);
               emit_reg_reg(A_MOV,S_L,R_EDX,location.registerhigh);
+
               popusedregisters(pushedreg);
-              location.loc:=LOC_REGISTER;
            end
          else
            begin
@@ -476,7 +490,9 @@ implementation
                          begin
                            popecx:=true;
                            emit_reg(A_PUSH,S_L,R_ECX);
-                         end;
+                         end
+                        else
+                          getexplicitregister32(R_ECX);
                         emit_reg_reg(A_MOV,S_L,hregister2,R_ECX);
                      end;
 
@@ -1042,7 +1058,11 @@ begin
 end.
 {
   $Log$
-  Revision 1.14  2001-08-26 13:37:00  florian
+  Revision 1.15  2001-08-29 12:03:23  jonas
+    * fixed wrong regalloc info around FPC_MUL/DIV/MOD_INT64/QWORD calls
+    * fixed partial result overwriting with the above calls too
+
+  Revision 1.14  2001/08/26 13:37:00  florian
     * some cg reorganisation
     * some PPC updates