Browse Source

* Restore registers in correct order (for push/pop it *does* matter), fixes crashes caused by r25224.

git-svn-id: trunk@25228 -
sergei 12 years ago
parent
commit
e1550e1aed
1 changed files with 8 additions and 4 deletions
  1. 8 4
      compiler/x86/cgx86.pas

+ 8 - 4
compiler/x86/cgx86.pas

@@ -2457,6 +2457,7 @@ unit cgx86;
       var
       var
         stackmisalignment: longint;
         stackmisalignment: longint;
         para: tparavarsym;
         para: tparavarsym;
+        regsize: longint;
 {$ifdef i8086}
 {$ifdef i8086}
         dgroup: treference;
         dgroup: treference;
 {$endif i8086}
 {$endif i8086}
@@ -2465,9 +2466,11 @@ unit cgx86;
         var
         var
           r: longint;
           r: longint;
         begin
         begin
+          regsize:=0;
           for r := low(saved_standard_registers) to high(saved_standard_registers) do
           for r := low(saved_standard_registers) to high(saved_standard_registers) do
             if saved_standard_registers[r] in rg[R_INTREGISTER].used_in_proc then
             if saved_standard_registers[r] in rg[R_INTREGISTER].used_in_proc then
               begin
               begin
+                inc(regsize,sizeof(aint));
                 list.concat(Taicpu.Op_reg(A_PUSH,tcgsize2opsize[OS_ADDR],newreg(R_INTREGISTER,saved_standard_registers[r],R_SUBWHOLE)));
                 list.concat(Taicpu.Op_reg(A_PUSH,tcgsize2opsize[OS_ADDR],newreg(R_INTREGISTER,saved_standard_registers[r],R_SUBWHOLE)));
               end;
               end;
         end;
         end;
@@ -2558,10 +2561,11 @@ unit cgx86;
             if (not paramanager.use_fixed_stack) and
             if (not paramanager.use_fixed_stack) and
                (current_procinfo.framepointer<>NR_STACK_POINTER_REG) then
                (current_procinfo.framepointer<>NR_STACK_POINTER_REG) then
               begin
               begin
+                regsize:=0;
+                push_regs;
                 reference_reset_base(current_procinfo.save_regs_ref,
                 reference_reset_base(current_procinfo.save_regs_ref,
                   current_procinfo.framepointer,
                   current_procinfo.framepointer,
-                  -(localsize+sizeof(aint)),sizeof(aint));
-                push_regs;
+                  -(localsize+regsize),sizeof(aint));
               end;
               end;
 {$endif i386}
 {$endif i386}
           end;
           end;
@@ -2593,7 +2597,7 @@ unit cgx86;
         href: treference;
         href: treference;
       begin
       begin
         href:=current_procinfo.save_regs_ref;
         href:=current_procinfo.save_regs_ref;
-        for r:=low(saved_standard_registers) to high(saved_standard_registers) do
+        for r:=high(saved_standard_registers) downto low(saved_standard_registers) do
           if saved_standard_registers[r] in rg[R_INTREGISTER].used_in_proc then
           if saved_standard_registers[r] in rg[R_INTREGISTER].used_in_proc then
             begin
             begin
               hreg:=newreg(R_INTREGISTER,saved_standard_registers[r],R_SUBWHOLE);
               hreg:=newreg(R_INTREGISTER,saved_standard_registers[r],R_SUBWHOLE);
@@ -2604,7 +2608,7 @@ unit cgx86;
               else
               else
                 begin
                 begin
                   a_load_ref_reg(list,OS_ADDR,OS_ADDR,href,hreg);
                   a_load_ref_reg(list,OS_ADDR,OS_ADDR,href,hreg);
-                  dec(href.offset,sizeof(aint));
+                  inc(href.offset,sizeof(aint));
                 end;
                 end;
             end;
             end;
       end;
       end;