Jelajahi Sumber

+ stack pages need to be touched on aarch64-win64 as well

git-svn-id: trunk@49559 -
florian 4 tahun lalu
induk
melakukan
d7a9a73194
1 mengubah file dengan 55 tambahan dan 3 penghapusan
  1. 55 3
      compiler/aarch64/cgcpu.pas

+ 55 - 3
compiler/aarch64/cgcpu.pas

@@ -34,6 +34,9 @@ interface
        rgcpu;
        rgcpu;
 
 
     type
     type
+
+      { tcgaarch64 }
+
       tcgaarch64=class(tcg)
       tcgaarch64=class(tcg)
        protected
        protected
         { changes register size without adding register allocation info }
         { changes register size without adding register allocation info }
@@ -92,6 +95,7 @@ interface
         procedure g_flags2reg(list: TAsmList; size: tcgsize; const f:tresflags; reg: tregister);override;
         procedure g_flags2reg(list: TAsmList; size: tcgsize; const f:tresflags; reg: tregister);override;
         procedure g_overflowcheck(list: TAsmList; const loc: tlocation; def: tdef);override;
         procedure g_overflowcheck(list: TAsmList; const loc: tlocation; def: tdef);override;
         procedure g_overflowcheck_loc(list: TAsmList; const loc: tlocation; def: tdef; ovloc: tlocation);override;
         procedure g_overflowcheck_loc(list: TAsmList; const loc: tlocation; def: tdef; ovloc: tlocation);override;
+        procedure g_stackpointer_alloc(list: TAsmList; localsize: longint);override;
         procedure g_proc_entry(list: TAsmList; localsize: longint; nostackframe: boolean);override;
         procedure g_proc_entry(list: TAsmList; localsize: longint; nostackframe: boolean);override;
         procedure g_proc_exit(list: TAsmList; parasize: longint; nostackframe: boolean);override;
         procedure g_proc_exit(list: TAsmList; parasize: longint; nostackframe: boolean);override;
         procedure g_maybe_got_init(list: TAsmList); override;
         procedure g_maybe_got_init(list: TAsmList); override;
@@ -120,6 +124,7 @@ interface
         C_LT,C_GE,C_LE,C_NE,C_LS,C_CC,C_CS,C_HI
         C_LT,C_GE,C_LE,C_NE,C_LS,C_CC,C_CS,C_HI
       );
       );
 
 
+      winstackpagesize = 4096;
 
 
 implementation
 implementation
 
 
@@ -1809,6 +1814,55 @@ implementation
       end;
       end;
 
 
 
 
+    procedure tcgaarch64.g_stackpointer_alloc(list : TAsmList;localsize : longint);
+      var
+        href : treference;
+        i : integer;
+        again : tasmlabel;
+      begin
+        if localsize>0 then
+         begin
+           { windows guards only a few pages for stack growing,
+             so we have to access every page first              }
+           if (target_info.system=system_aarch64_win64) and
+              (localsize>=winstackpagesize) then
+             begin
+               if localsize div winstackpagesize<=4 then
+                 begin
+                   handle_reg_imm12_reg(list,A_SUB,OS_ADDR,NR_SP,localsize,NR_SP,NR_IP0,false,true);
+                   for i:=1 to localsize div winstackpagesize do
+                     begin
+                       reference_reset_base(href,NR_SP,localsize-i*winstackpagesize+4,ctempposinvalid,4,[]);
+                       list.concat(Taicpu.op_reg_ref(A_STR,NR_WZR,href));
+                     end;
+                   reference_reset_base(href,NR_SP,0,ctempposinvalid,4,[]);
+                   list.concat(Taicpu.op_reg_ref(A_STR,NR_WZR,href));
+                 end
+               else
+                 begin
+                    current_asmdata.getjumplabel(again);
+                    getcpuregister(list,NR_IP0);
+                    a_load_const_reg(list,OS_ADDR,localsize div winstackpagesize,NR_IP0);
+                    a_label(list,again);
+                    handle_reg_imm12_reg(list,A_SUB,OS_ADDR,NR_SP,winstackpagesize,NR_SP,NR_IP1,false,true);
+                    reference_reset_base(href,NR_SP,0,ctempposinvalid,4,[]);
+                    list.concat(Taicpu.op_reg_ref(A_STR,NR_WZR,href));
+                    list.concat(setoppostfix(Taicpu.op_reg_reg_const(A_SUB,NR_IP0,NR_IP0,1),PF_S));
+                    a_jmp_cond(list,OC_NE,again);
+                    handle_reg_imm12_reg(list,A_SUB,OS_ADDR,NR_SP,localsize mod winstackpagesize,NR_SP,NR_IP1,false,true);
+                    ungetcpuregister(list,NR_IP0);
+                 end
+             end
+           else
+             begin
+               handle_reg_imm12_reg(list,A_SUB,OS_ADDR,NR_SP,localsize,NR_SP,NR_IP0,false,true);
+               if target_info.system=system_aarch64_win64 then
+                 list.concat(cai_seh_directive.create_offset(ash_stackalloc,localsize));
+             end;
+         end;
+      end;
+
+
     procedure tcgaarch64.g_proc_entry(list: TAsmList; localsize: longint; nostackframe: boolean);
     procedure tcgaarch64.g_proc_entry(list: TAsmList; localsize: longint; nostackframe: boolean);
       var
       var
         hitem: tlinkedlistitem;
         hitem: tlinkedlistitem;
@@ -1870,9 +1924,7 @@ implementation
               begin
               begin
                 localsize:=align(localsize,16);
                 localsize:=align(localsize,16);
                 current_procinfo.final_localsize:=localsize;
                 current_procinfo.final_localsize:=localsize;
-                handle_reg_imm12_reg(list,A_SUB,OS_ADDR,NR_SP,localsize,NR_SP,NR_IP0,false,true);
-                if target_info.system=system_aarch64_win64 then
-                  list.concat(cai_seh_directive.create_offset(ash_stackalloc,localsize));
+                g_stackpointer_alloc(list,localsize);
               end;
               end;
             { By default, we use the frame pointer to access parameters passed via
             { By default, we use the frame pointer to access parameters passed via
               the stack and the stack pointer to address local variables and temps
               the stack and the stack pointer to address local variables and temps