Browse Source

* fixed stackchecking for register calling

peter 21 years ago
parent
commit
ac1332a388
2 changed files with 44 additions and 34 deletions
  1. 4 29
      compiler/cgobj.pas
  2. 40 5
      compiler/ncgutil.pas

+ 4 - 29
compiler/cgobj.pas

@@ -366,15 +366,6 @@ unit cgobj;
           procedure g_initialize(list : taasmoutput;t : tdef;const ref : treference;loadref : boolean);
           procedure g_finalize(list : taasmoutput;t : tdef;const ref : treference;loadref : boolean);
 
-          {# Emits the call to the stack checking routine of
-             the runtime library. The default behavior
-             does not need to be modified, as it is generic
-             for all platforms.
-
-             @param(stackframesize Number of bytes which will be allocated on the stack)
-          }
-          procedure g_stackcheck(list : taasmoutput;stackframesize : longint);virtual;
-
           {# Generates range checking code. It is to note
              that this routine does not need to be overriden,
              as it takes care of everything.
@@ -1807,25 +1798,6 @@ implementation
       end;
 
 
-    procedure tcg.g_stackcheck(list : taasmoutput;stackframesize : longint);
-      var
-        paraloc1 : tparalocation;
-      begin
-         paraloc1:=paramanager.getintparaloc(pocall_default,1);
-         paramanager.allocparaloc(list,paraloc1);
-         a_param_const(list,OS_32,stackframesize,paraloc1);
-         paramanager.freeparaloc(list,paraloc1);
-         { No register saving needed, saveregisters is used }
-{$ifndef x86}
-         allocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
-{$endif x86}
-         a_call_name(list,'FPC_STACKCHECK');
-{$ifndef x86}
-         deallocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
-{$endif x86}
-      end;
-
-
     procedure tcg.g_flags2ref(list: taasmoutput; size: TCgSize; const f: tresflags; const ref:TReference);
 
       var
@@ -2137,7 +2109,10 @@ finalization
 end.
 {
   $Log$
-  Revision 1.149  2004-01-20 12:59:36  florian
+  Revision 1.150  2004-01-21 21:01:34  peter
+    * fixed stackchecking for register calling
+
+  Revision 1.149  2004/01/20 12:59:36  florian
     * common addnode code for x86-64 and i386
 
   Revision 1.148  2004/01/12 22:11:38  peter

+ 40 - 5
compiler/ncgutil.pas

@@ -1502,7 +1502,19 @@ implementation
         hitemp,
         lotemp,
         stackframe : longint;
+        check      : boolean;
+        paraloc1   : tparalocation;
+        href       : treference;
       begin
+        check:=(cs_check_stack in aktlocalswitches) and (current_procinfo.procdef.proctypeoption<>potype_proginit);
+        if check then
+          begin
+            { Allocate tempspace to store register parameter than
+              is destroyed when calling stackchecking code }
+            paraloc1:=paramanager.getintparaloc(pocall_default,1);
+            if paraloc1.loc=LOC_REGISTER then
+              tg.GetTemp(list,POINTER_SIZE,tt_normal,href);
+          end;
         { Calculate size of stackframe }
         stackframe:=current_procinfo.calc_stackframe_size;
 
@@ -1540,10 +1552,30 @@ implementation
 
             cg.g_stackframe_entry(list,stackframe);
 
-            {Never call stack checking before the standard system unit
-             has been initialized.}
-             if (cs_check_stack in aktlocalswitches) and (current_procinfo.procdef.proctypeoption<>potype_proginit) then
-               cg.g_stackcheck(list,stackframe);
+            { Add stack checking code? }
+            if check then
+              begin
+                { The tempspace to store original register is already
+                  allocated above before the stackframe size is calculated. }
+                if paraloc1.loc=LOC_REGISTER then
+                  cg.a_load_reg_ref(list,OS_INT,OS_INT,paraloc1.register,href);
+                paramanager.allocparaloc(list,paraloc1);
+                cg.a_param_const(list,OS_32,stackframe,paraloc1);
+                paramanager.freeparaloc(list,paraloc1);
+                { No register saving needed, saveregisters is used }
+{$ifndef x86}
+                cg.allocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
+{$endif x86}
+                cg.a_call_name(list,'FPC_STACKCHECK');
+{$ifndef x86}
+                cg.deallocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
+{$endif x86}
+                if paraloc1.loc=LOC_REGISTER then
+                  begin
+                    cg.a_load_ref_reg(list,OS_INT,OS_INT,href,paraloc1.register);
+                    tg.UnGetTemp(list,href);
+                  end;
+              end;
           end;
       end;
 
@@ -2066,7 +2098,10 @@ implementation
 end.
 {
   $Log$
-  Revision 1.183  2004-01-17 15:55:10  jonas
+  Revision 1.184  2004-01-21 21:01:34  peter
+    * fixed stackchecking for register calling
+
+  Revision 1.183  2004/01/17 15:55:10  jonas
     * fixed allocation of parameters passed by reference for powerpc in
       callee