소스 검색

* x86: Don't save/restore integer registers that are volatile per calling convention of current procedure. It implies that nothing will be saved for procedures with OLDFPCCALL, FAR16 and PASCAL and calling conventions. OLDFPCCALL restores behavior that was in effect before r25224.

git-svn-id: trunk@32542 -
sergei 9 년 전
부모
커밋
1b965e6766
2개의 변경된 파일10개의 추가작업 그리고 4개의 파일을 삭제
  1. 6 2
      compiler/x86/cgx86.pas
  2. 4 2
      compiler/x86_64/cgcpu.pas

+ 6 - 2
compiler/x86/cgx86.pas

@@ -2847,10 +2847,12 @@ unit cgx86;
       procedure push_regs;
       procedure push_regs;
         var
         var
           r: longint;
           r: longint;
+          usedregs: tcpuregisterset;
         begin
         begin
           regsize:=0;
           regsize:=0;
+          usedregs:=rg[R_INTREGISTER].used_in_proc-paramanager.get_volatile_registers_int(current_procinfo.procdef.proccalloption);
           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 usedregs then
               begin
               begin
                 inc(regsize,sizeof(aint));
                 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)));
@@ -3106,10 +3108,12 @@ unit cgx86;
         r: longint;
         r: longint;
         hreg: tregister;
         hreg: tregister;
         href: treference;
         href: treference;
+        usedregs: tcpuregisterset;
       begin
       begin
         href:=current_procinfo.save_regs_ref;
         href:=current_procinfo.save_regs_ref;
+        usedregs:=rg[R_INTREGISTER].used_in_proc-paramanager.get_volatile_registers_int(current_procinfo.procdef.proccalloption);
         for r:=high(saved_standard_registers) downto low(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 usedregs then
             begin
             begin
               hreg:=newreg(R_INTREGISTER,saved_standard_registers[r],R_SUBWHOLE);
               hreg:=newreg(R_INTREGISTER,saved_standard_registers[r],R_SUBWHOLE);
               { Allocate register so the optimizer does not remove the load }
               { Allocate register so the optimizer does not remove the load }

+ 4 - 2
compiler/x86_64/cgcpu.pas

@@ -189,9 +189,11 @@ unit cgcpu;
       procedure push_regs;
       procedure push_regs;
         var
         var
           r: longint;
           r: longint;
+          usedregs: tcpuregisterset;
         begin
         begin
+          usedregs:=rg[R_INTREGISTER].used_in_proc-paramanager.get_volatile_registers_int(current_procinfo.procdef.proccalloption);
           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 usedregs then
               begin
               begin
                 inc(stackmisalignment,sizeof(pint));
                 inc(stackmisalignment,sizeof(pint));
                 push_one_reg(newreg(R_INTREGISTER,saved_standard_registers[r],R_SUBWHOLE));
                 push_one_reg(newreg(R_INTREGISTER,saved_standard_registers[r],R_SUBWHOLE));
@@ -263,7 +265,7 @@ unit cgcpu;
               begin
               begin
                 if target_info.stackalign>sizeof(pint) then
                 if target_info.stackalign>sizeof(pint) then
                   localsize := align(localsize+stackmisalignment,target_info.stackalign)-stackmisalignment;
                   localsize := align(localsize+stackmisalignment,target_info.stackalign)-stackmisalignment;
-                cg.g_stackpointer_alloc(list,localsize);
+                g_stackpointer_alloc(list,localsize);
                 if current_procinfo.framepointer=NR_STACK_POINTER_REG then
                 if current_procinfo.framepointer=NR_STACK_POINTER_REG then
                   current_asmdata.asmcfi.cfa_def_cfa_offset(list,localsize+sizeof(pint));
                   current_asmdata.asmcfi.cfa_def_cfa_offset(list,localsize+sizeof(pint));
                 current_procinfo.final_localsize:=localsize;
                 current_procinfo.final_localsize:=localsize;