Browse Source

+ Fixes from Jonas.

michael 25 years ago
parent
commit
587a967353
3 changed files with 53 additions and 42 deletions
  1. 19 29
      compiler/cg386add.pas
  2. 23 8
      compiler/cgai386.pas
  3. 11 5
      compiler/csopt386.pas

+ 19 - 29
compiler/cg386add.pas

@@ -337,7 +337,7 @@ implementation
         pushed : boolean;
         href   : treference;
         pushedregs : tpushed;
-        regstopush: longint;
+        regstopush: byte;
       begin
         cmpop:=false;
 
@@ -425,24 +425,8 @@ implementation
                      pushusedregisters(pushedregs,$ff);}
 
                      regstopush := $ff;
-                     case p^.right^.location.loc of
-                       LOC_REGISTER:
-                         regstopush := regstopush and
-                           not($80 shr byte(p^.right^.location.register));
-                       LOC_MEM,LOC_REFERENCE:
-                         regstopush := regstopush and
-                           not($80 shr byte(p^.right^.location.reference.base)) and
-                           not($80 shr byte(p^.right^.location.reference.index));
-                     end;
-                     case p^.left^.location.loc of
-                       LOC_REGISTER:
-                         regstopush := regstopush and
-                           not($80 shr byte(p^.left^.location.register));
-                       LOC_MEM,LOC_REFERENCE:
-                         regstopush := regstopush and
-                           not($80 shr byte(p^.left^.location.reference.base)) and
-                           not($80 shr byte(p^.left^.location.reference.index));
-                     end;
+                     remove_non_regvars_from_loc(p^.right^.location,regstopush);
+                     remove_non_regvars_from_loc(p^.left^.location,regstopush);
                      pushusedregisters(pushedregs,regstopush);
                      { this is still right before the instruction that uses }
                      { p^.left^.location, but that can be fixed by the      }
@@ -580,6 +564,7 @@ implementation
 {$endif SUPPORT_MMX}
          pushedreg : tpushed;
          hloc : tlocation;
+         regstopush: byte;
 
       procedure firstjmp64bitcmp;
 
@@ -1070,14 +1055,19 @@ implementation
                        Else
                         Begin
 {$EndIf NoShlMul}
-                         if not(R_EAX in unused) and not(reg_in_loc(R_EAX,p^.right^.location)) and
-                            not(reg_in_loc(R_EAX,p^.left^.location)) then
+                         regstopush := $ff;
+                         remove_non_regvars_from_loc(p^.right^.location,regstopush);
+                         remove_non_regvars_from_loc(p^.left^.location,regstopush);
+                         { now, regstopush does NOT contain EAX and/or EDX if they are }
+                         { used in either the left or the right location, excepts if   }
+                         {they are regvars. It DOES contain them if they are used in   }
+                         { another location (JM)                                       }
+                         if ((regstopush and ($80 shr byte(R_EAX))) <> 0) then
                           begin
                            emit_reg(A_PUSH,S_L,R_EAX);
                            popeax:=true;
                           end;
-                         if not(R_EDX in unused) and not(reg_in_loc(R_EDX,p^.right^.location)) and
-                            not(reg_in_loc(R_EDX,p^.left^.location)) then
+                         if ((regstopush and ($80 shr byte(R_EDX))) <> 0) then
                           begin
                            emit_reg(A_PUSH,S_L,R_EDX);
                            popedx:=true;
@@ -1095,11 +1085,8 @@ implementation
                          { load he right value }
                          emitloadord2reg(p^.right^.location,u32bitdef,R_EAX,true);
                          release_loc(p^.right^.location);
-                         { a hack, I know :( Necessary for when EAX is in }
-                         { p^.right^.location, since it can't be released }
-                         { yet (JM)                                       }
-                         if reg_in_loc(R_EAX,p^.right^.location) and
-                            (R_EAX in unused) then
+                         { allocate EAX if it isn't yet allocated (JM) }
+                         if (R_EAX in unused) then
                            exprasmlist^.concat(new(pairegalloc,alloc(R_EAX)));
 {$ifndef noAllocEdi}
                          { also allocate EDX, since it is also modified by }
@@ -2249,7 +2236,10 @@ implementation
 end.
 {
   $Log$
-  Revision 1.90  2000-01-22 16:02:38  jonas
+  Revision 1.91  2000-01-23 11:11:36  michael
+  + Fixes from Jonas.
+
+  Revision 1.90  2000/01/22 16:02:38  jonas
     * fixed more regalloc bugs (for set adding and unsigned
       multiplication)
 

+ 23 - 8
compiler/cgai386.pas

@@ -76,8 +76,9 @@ unit cgai386;
     procedure emit_pushq_loc(const t : tlocation);
     procedure release_qword_loc(const t : tlocation);
 
-    { is a register used in a location? }
-    function reg_in_loc(reg: tregister; const t: tlocation): boolean;
+    { remove non regvar registers in loc from regs (in the format }
+    { pushusedregisters uses)                                     } 
+    procedure remove_non_regvars_from_loc(const t: tlocation; var regs: byte);
     { releases the registers of a location }
     procedure release_loc(const t : tlocation);
 
@@ -611,16 +612,27 @@ procedure mov_reg_to_dest(p : ptree; s : topsize; reg : tregister);
          end;
       end;
 
-    function reg_in_loc(reg: tregister; const t: tlocation): boolean;
+    procedure remove_non_regvars_from_loc(const t: tlocation; var regs: byte);
     begin
-      reg_in_loc := false;
       case t.loc of
-        LOC_REGISTER: reg_in_loc := t.register = reg;
-        LOC_MEM, LOC_REFERENCE:
-          reg_in_loc := (t.reference.base = reg) or (t.reference.index = reg);
+        LOC_REGISTER:
+          { can't be a regvar, since it would be LOC_CREGISTER then } 
+          regs := regs and not($80 shr byte(t.register));
+        LOC_MEM,LOC_REFERENCE:
+          begin
+            if not(cs_regalloc in aktglobalswitches) or
+               (t.reference.base in usableregs) then
+              regs := regs and
+                not($80 shr byte(t.reference.base));
+            if not(cs_regalloc in aktglobalswitches) or
+               (t.reference.index in usableregs) then
+              regs := regs and
+                not($80 shr byte(t.reference.index));
+          end;
       end;
     end;
 
+
     procedure release_loc(const t : tlocation);
 
       begin
@@ -3672,7 +3684,10 @@ procedure mov_reg_to_dest(p : ptree; s : topsize; reg : tregister);
 end.
 {
   $Log$
-  Revision 1.71  2000-01-22 16:02:37  jonas
+  Revision 1.72  2000-01-23 11:11:36  michael
+  + Fixes from Jonas.
+
+  Revision 1.71  2000/01/22 16:02:37  jonas
     * fixed more regalloc bugs (for set adding and unsigned
       multiplication)
 

+ 11 - 5
compiler/csopt386.pas

@@ -736,10 +736,13 @@ begin
         end;
     end;
   sequenceEnd := sequenceEnd and
-     RegSizesOk(orgReg,newReg,paicpu(endP)) and
-     not(newRegModified and
-         (orgReg in PPaiProp(endP^.optInfo)^.usedRegs) and
-         not(RegLoadedWithNewValue(orgReg,true,paicpu(endP))));
+     (not(assigned(endp)) or
+      not(endp^.typ = ait_instruction) or
+      (noHardCodedRegs(paicpu(endP)) and
+       RegSizesOk(orgReg,newReg,paicpu(endP)) and
+       not(newRegModified and
+           (orgReg in PPaiProp(endP^.optInfo)^.usedRegs) and
+           not(RegLoadedWithNewValue(orgReg,true,paicpu(endP))))));
 
   if SequenceEnd then
     begin
@@ -1167,7 +1170,10 @@ End.
 
 {
  $Log$
- Revision 1.40  2000-01-22 16:10:06  jonas
+ Revision 1.41  2000-01-23 11:11:37  michael
+ + Fixes from Jonas.
+
+ Revision 1.40  2000/01/22 16:10:06  jonas
    + all code generator generated "mov reg1,reg2" instructions are now
      attempted to be removed using the replacereg code
      (-dnewoptimizations)