Browse Source

* preparations for different default calling conventions
* various RA fixes

peter 22 years ago
parent
commit
b9d09a4e5c

+ 9 - 3
compiler/aasmtai.pas

@@ -2061,13 +2061,15 @@ implementation
         begin
           case p.typ of
             ait_regalloc:
-              setsupreg(Tai_regalloc(p).reg,table[getsupreg(Tai_regalloc(p).reg)]);
+              if (getregtype(Tai_regalloc(p).reg)=R_INTREGISTER) then
+                setsupreg(Tai_regalloc(p).reg,table[getsupreg(Tai_regalloc(p).reg)]);
             ait_instruction:
               begin
                 for i:=0 to Taicpu_abstract(p).ops-1 do
                   case Taicpu_abstract(p).oper[i].typ of
                     Top_reg:
-                      setsupreg(Taicpu_abstract(p).oper[i].reg,table[getsupreg(Taicpu_abstract(p).oper[i].reg)]);
+                       if (getregtype(Taicpu_abstract(p).oper[i].reg)=R_INTREGISTER) then
+                         setsupreg(Taicpu_abstract(p).oper[i].reg,table[getsupreg(Taicpu_abstract(p).oper[i].reg)]);
                     Top_ref:
                       begin
                         r:=Taicpu_abstract(p).oper[i].ref;
@@ -2104,7 +2106,11 @@ implementation
 end.
 {
   $Log$
-  Revision 1.38  2003-09-04 00:15:28  florian
+  Revision 1.39  2003-09-07 22:09:34  peter
+    * preparations for different default calling conventions
+    * various RA fixes
+
+  Revision 1.38  2003/09/04 00:15:28  florian
     * first bunch of adaptions of arm compiler for new register type
 
   Revision 1.37  2003/09/03 15:55:00  peter

+ 6 - 2
compiler/browcol.pas

@@ -1453,7 +1453,7 @@ end;
                else
                  MemInfo.Size:=getsize;
                { this is not completely correct... }
-               MemInfo.PushSize:=paramanager.push_size(varspez,vartype.def,pocall_none);
+               MemInfo.PushSize:=paramanager.push_size(varspez,vartype.def,pocall_default);
                Symbol^.SetMemInfo(MemInfo);
              end;
           constsym :
@@ -2111,7 +2111,11 @@ begin
 end.
 {
   $Log$
-  Revision 1.33  2003-04-26 00:29:17  peter
+  Revision 1.34  2003-09-07 22:09:34  peter
+    * preparations for different default calling conventions
+    * various RA fixes
+
+  Revision 1.33  2003/04/26 00:29:17  peter
     * adapted for removed funcretsym
 
   Revision 1.32  2002/12/29 14:57:50  peter

+ 15 - 17
compiler/cgbase.pas

@@ -86,19 +86,10 @@ unit cgbase;
           }
           flags : tprocinfoflags;
 
-          {# register used as frame pointer }
+          { register used as frame pointer }
           framepointer : tregister;
 
-          {# Holds the reference used to store the original stackpointer
-             after all registers are saved
-          }
-          save_stackptr_ref :treference;
-          {# Holds the reference used to store alll saved registers.
-
-             This is used on systems which do not have direct stack
-             operations (such as the PowerPC), it is unused on other
-             systems
-          }
+          { Holds the reference used to store alll saved registers. }
           save_regs_ref : treference;
 
           { label to leave the sub routine }
@@ -324,7 +315,7 @@ implementation
         { asmlists }
         aktproccode:=Taasmoutput.Create;
         aktlocaldata:=Taasmoutput.Create;
-        reference_reset(save_stackptr_ref);
+        reference_reset(save_regs_ref);
         { labels }
         objectlibrary.getlabel(aktexitlabel);
       end;
@@ -385,6 +376,8 @@ implementation
            current_procinfo.firsttemp_offset := tg.direction*symtablestack.datasize
          else
            current_procinfo.firsttemp_offset := 0;
+(*
+         THe registers are also allocated when loading the result
 
          { include return value registers }
          if not is_void(procdef.rettype.def) then
@@ -397,21 +390,22 @@ implementation
                LOC_CMMREGISTER :
                  begin
                    regidx:=findreg_by_number(paramloc.register);
-                   include(rg.used_in_proc_other,regidx);
+                   include(used_regs_fpu,regidx);
                  end;
                LOC_REGISTER,LOC_CREGISTER :
                  begin
                    if ((paramloc.size in [OS_S64,OS_64]) and
                       (sizeof(aword) < 8)) then
                      begin
-                       include(rg.used_in_proc_int,getsupreg(paramloc.registerhigh));
-                       include(rg.used_in_proc_int,getsupreg(paramloc.registerlow));
+                       include(used_regs_int,getsupreg(paramloc.registerhigh));
+                       include(used_regs_fpu,getsupreg(paramloc.registerlow));
                      end
                    else
-                     include(rg.used_in_proc_int,getsupreg(paramloc.register));
+                     include(used_regs_fpu,getsupreg(paramloc.register));
                  end;
              end;
            end;
+*)
       end;
 
 
@@ -582,7 +576,11 @@ implementation
 end.
 {
   $Log$
-  Revision 1.61  2003-09-03 15:55:00  peter
+  Revision 1.62  2003-09-07 22:09:34  peter
+    * preparations for different default calling conventions
+    * various RA fixes
+
+  Revision 1.61  2003/09/03 15:55:00  peter
     * NEWRA branch merged
 
   Revision 1.60.2.1  2003/08/29 17:28:59  peter

+ 23 - 19
compiler/cgobj.pas

@@ -1146,9 +1146,9 @@ unit cgobj;
         paramanager.freeintparaloc(list,3);
         paramanager.freeintparaloc(list,2);
         paramanager.freeintparaloc(list,1);
-        rg.allocexplicitregistersint(list,VOLATILE_INTREGISTERS);
+        rg.allocexplicitregistersint(list,paramanager.get_volatile_registers_int(pocall_default));
         a_call_name(list,'FPC_SHORTSTR_ASSIGN');
-        rg.deallocexplicitregistersint(list,VOLATILE_INTREGISTERS);
+        rg.deallocexplicitregistersint(list,paramanager.get_volatile_registers_int(pocall_default));
       end;
 
 
@@ -1175,9 +1175,9 @@ unit cgobj;
             { these functions get the pointer by value }
             a_param_ref(list,OS_ADDR,ref,paramanager.getintparaloc(list,1));
             paramanager.freeintparaloc(list,1);
-            rg.allocexplicitregistersint(list,VOLATILE_INTREGISTERS);
+            rg.allocexplicitregistersint(list,paramanager.get_volatile_registers_int(pocall_default));
             a_call_name(list,incrfunc);
-            rg.deallocexplicitregistersint(list,VOLATILE_INTREGISTERS);
+            rg.deallocexplicitregistersint(list,paramanager.get_volatile_registers_int(pocall_default));
           end
          else
           begin
@@ -1189,9 +1189,9 @@ unit cgobj;
               a_paramaddr_ref(list,ref,paramanager.getintparaloc(list,1));
             paramanager.freeintparaloc(list,1);
             paramanager.freeintparaloc(list,2);
-            rg.allocexplicitregistersint(list,VOLATILE_INTREGISTERS);
+            rg.allocexplicitregistersint(list,paramanager.get_volatile_registers_int(pocall_default));
             a_call_name(list,'FPC_ADDREF');
-            rg.deallocexplicitregistersint(list,VOLATILE_INTREGISTERS);
+            rg.deallocexplicitregistersint(list,paramanager.get_volatile_registers_int(pocall_default));
          end;
       end;
 
@@ -1229,9 +1229,9 @@ unit cgobj;
             else
               a_paramaddr_ref(list,ref,paramanager.getintparaloc(list,1));
             paramanager.freeintparaloc(list,1);
-            rg.allocexplicitregistersint(list,VOLATILE_INTREGISTERS);
+            rg.allocexplicitregistersint(list,paramanager.get_volatile_registers_int(pocall_default));
             a_call_name(list,decrfunc);
-            rg.deallocexplicitregistersint(list,VOLATILE_INTREGISTERS);
+            rg.deallocexplicitregistersint(list,paramanager.get_volatile_registers_int(pocall_default));
             if needrtti then
               paramanager.freeintparaloc(list,2);
           end
@@ -1245,9 +1245,9 @@ unit cgobj;
               a_paramaddr_ref(list,ref,paramanager.getintparaloc(list,1));
             paramanager.freeintparaloc(list,1);
             paramanager.freeintparaloc(list,2);
-            rg.allocexplicitregistersint(list,VOLATILE_INTREGISTERS);
+            rg.allocexplicitregistersint(list,paramanager.get_volatile_registers_int(pocall_default));
             a_call_name(list,'FPC_DECREF');
-            rg.deallocexplicitregistersint(list,VOLATILE_INTREGISTERS);
+            rg.deallocexplicitregistersint(list,paramanager.get_volatile_registers_int(pocall_default));
          end;
       end;
 
@@ -1270,9 +1270,9 @@ unit cgobj;
                 a_paramaddr_ref(list,ref,paramanager.getintparaloc(list,1));
               paramanager.freeintparaloc(list,1);
               paramanager.freeintparaloc(list,2);
-              rg.allocexplicitregistersint(list,VOLATILE_INTREGISTERS);
+              rg.allocexplicitregistersint(list,paramanager.get_volatile_registers_int(pocall_default));
               a_call_name(list,'FPC_INITIALIZE');
-              rg.deallocexplicitregistersint(list,VOLATILE_INTREGISTERS);
+              rg.deallocexplicitregistersint(list,paramanager.get_volatile_registers_int(pocall_default));
            end;
       end;
 
@@ -1295,9 +1295,9 @@ unit cgobj;
                 a_paramaddr_ref(list,ref,paramanager.getintparaloc(list,1));
               paramanager.freeintparaloc(list,1);
               paramanager.freeintparaloc(list,2);
-              rg.allocexplicitregistersint(list,VOLATILE_INTREGISTERS);
+              rg.allocexplicitregistersint(list,paramanager.get_volatile_registers_int(pocall_default));
               a_call_name(list,'FPC_FINALIZE');
-              rg.deallocexplicitregistersint(list,VOLATILE_INTREGISTERS);
+              rg.deallocexplicitregistersint(list,paramanager.get_volatile_registers_int(pocall_default));
            end;
       end;
 
@@ -1461,18 +1461,18 @@ unit cgobj;
            a_param_reg(list,OS_ADDR,reg,paramanager.getintparaloc(list,1));
            paramanager.freeintparaloc(list,2);
            paramanager.freeintparaloc(list,1);
-           rg.allocexplicitregistersint(list,VOLATILE_INTREGISTERS);
+           rg.allocexplicitregistersint(list,paramanager.get_volatile_registers_int(pocall_default));
            a_call_name(list,'FPC_CHECK_OBJECT_EXT');
-           rg.deallocexplicitregistersint(list,VOLATILE_INTREGISTERS);
+           rg.deallocexplicitregistersint(list,paramanager.get_volatile_registers_int(pocall_default));
          end
         else
          if (cs_check_range in aktlocalswitches) then
           begin
             a_param_reg(list,OS_ADDR,reg,paramanager.getintparaloc(list,1));
             paramanager.freeintparaloc(list,1);
-            rg.allocexplicitregistersint(list,VOLATILE_INTREGISTERS);
+            rg.allocexplicitregistersint(list,paramanager.get_volatile_registers_int(pocall_default));
             a_call_name(list,'FPC_CHECK_OBJECT');
-            rg.deallocexplicitregistersint(list,VOLATILE_INTREGISTERS);
+            rg.deallocexplicitregistersint(list,paramanager.get_volatile_registers_int(pocall_default));
           end;
       end;
 
@@ -1536,7 +1536,11 @@ finalization
 end.
 {
   $Log$
-  Revision 1.118  2003-09-03 15:55:00  peter
+  Revision 1.119  2003-09-07 22:09:34  peter
+    * preparations for different default calling conventions
+    * various RA fixes
+
+  Revision 1.118  2003/09/03 15:55:00  peter
     * NEWRA branch merged
 
   Revision 1.117  2003/09/03 11:18:36  florian

+ 6 - 2
compiler/globals.pas

@@ -1660,7 +1660,7 @@ implementation
         initfputype:=fpu_fpa;
 {$endif arm}
         initinterfacetype:=it_interfacecom;
-        initdefproccall:=pocall_none;
+        initdefproccall:=pocall_default;
         initdefines:=TStringList.Create;
 
       { memory sizes, will be overriden by parameter or default for target
@@ -1674,7 +1674,11 @@ implementation
 end.
 {
   $Log$
-  Revision 1.96  2003-09-06 16:47:24  florian
+  Revision 1.97  2003-09-07 22:09:34  peter
+    * preparations for different default calling conventions
+    * various RA fixes
+
+  Revision 1.96  2003/09/06 16:47:24  florian
     + support of NaN and Inf in the compiler as values of real constants
 
   Revision 1.95  2003/09/05 17:41:12  florian

+ 11 - 3
compiler/globtype.pas

@@ -132,7 +132,7 @@ interface
          pocall_cppdecl,       { C++ calling conventions }
          pocall_compilerproc,  { Procedure is used for internal compiler calls }
          pocall_far16,         { Far16 for OS/2 }
-         pocall_fpccall,       { FPC default calling }
+         pocall_oldfpccall,    { Old style FPC default calling }
          pocall_inline,        { Procedure is an assembler macro }
          pocall_internproc,    { Procedure has compiler magic}
          pocall_palmossyscall, { procedure is a PalmOS system call }
@@ -143,13 +143,14 @@ interface
        );
        tproccalloptions = set of tproccalloption;
 
+
      const
        proccalloptionStr : array[tproccalloption] of string[14]=('',
            'CDecl',
            'CPPDecl',
            'CompilerProc',
            'Far16',
-           'FPCCall',
+           'OldFPCCall',
            'Inline',
            'InternProc',
            'PalmOSSysCall',
@@ -159,6 +160,9 @@ interface
            'StdCall'
          );
 
+       { Default calling convention }
+       pocall_default = pocall_oldfpccall;
+
     type
        stringid = string[maxidlen];
 
@@ -206,7 +210,11 @@ implementation
 end.
 {
   $Log$
-  Revision 1.41  2003-09-04 21:37:29  olle
+  Revision 1.42  2003-09-07 22:09:35  peter
+    * preparations for different default calling conventions
+    * various RA fixes
+
+  Revision 1.41  2003/09/04 21:37:29  olle
     + added new lagnuage mode: MAC
 
   Revision 1.40  2003/09/03 15:55:00  peter

+ 41 - 1
compiler/i386/cpupara.pas

@@ -44,6 +44,8 @@ unit cpupara;
        ti386paramanager = class(tparamanager)
           function ret_in_param(def : tdef;calloption : tproccalloption) : boolean;override;
           function push_addr_param(def : tdef;calloption : tproccalloption) : boolean;override;
+          function get_volatile_registers_int(calloption : tproccalloption):tsuperregisterset;override;
+          function get_volatile_registers_fpu(calloption : tproccalloption):tsuperregisterset;override;
           function getintparaloc(list: taasmoutput; nr : longint) : tparalocation;override;
           procedure freeintparaloc(list: taasmoutput; nr : longint); override;
           function getparaloc(p : tdef) : tcgloc;
@@ -60,6 +62,10 @@ unit cpupara;
        cgbase;
 
 
+{****************************************************************************
+                                TI386PARAMANAGER
+****************************************************************************}
+
     function ti386paramanager.ret_in_param(def : tdef;calloption : tproccalloption) : boolean;
       begin
         case target_info.system of
@@ -112,6 +118,35 @@ unit cpupara;
       end;
 
 
+    function ti386paramanager.get_volatile_registers_int(calloption : tproccalloption):tsuperregisterset;
+      begin
+        case calloption of
+          pocall_internproc :
+            result:=[];
+          pocall_inline,
+          pocall_compilerproc,
+          pocall_register,
+          pocall_safecall,
+          pocall_stdcall,
+          pocall_cdecl,
+          pocall_cppdecl :
+            result:=[RS_EAX,RS_EDX,RS_ECX];
+          pocall_far16,
+          pocall_pascal,
+          pocall_oldfpccall :
+            result:=[RS_EAX,RS_EDX,RS_ECX,RS_ESI,RS_EDI,RS_EBX];
+          else
+            internalerror(200309071);
+        end;
+      end;
+
+
+    function ti386paramanager.get_volatile_registers_fpu(calloption : tproccalloption):tsuperregisterset;
+      begin
+        result:=[first_fpu_supreg..last_fpu_supreg];;
+      end;
+
+
     function ti386paramanager.getintparaloc(list: taasmoutput; nr : longint) : tparalocation;
       begin
          getintparaloc.loc:=LOC_REFERENCE;
@@ -202,12 +237,17 @@ unit cpupara;
          getselflocation.reference.offset:=hsym.adjusted_address;
       end;
 
+
 begin
    paramanager:=ti386paramanager.create;
 end.
 {
   $Log$
-  Revision 1.23  2003-09-03 15:55:01  peter
+  Revision 1.24  2003-09-07 22:09:35  peter
+    * preparations for different default calling conventions
+    * various RA fixes
+
+  Revision 1.23  2003/09/03 15:55:01  peter
     * NEWRA branch merged
 
   Revision 1.22.2.2  2003/08/28 18:35:08  peter

+ 6 - 3
compiler/i386/n386inl.pas

@@ -300,8 +300,7 @@ implementation
                 { need a cmp and jmp, but this should be done by the         }
                 { type cast code which does range checking if necessary (FK) }
                 begin
-                  hregister:=Tcallparanode(Tcallparanode(left).right).left.location.register;
-                  setsubreg(hregister,R_SUBWHOLE);
+                  hregister:=rg.makeregsize(Tcallparanode(Tcallparanode(left).right).left.location.register,OS_INT);
                 end
               else
                 begin
@@ -323,7 +322,11 @@ begin
 end.
 {
   $Log$
-  Revision 1.65  2003-09-03 15:55:01  peter
+  Revision 1.66  2003-09-07 22:09:35  peter
+    * preparations for different default calling conventions
+    * various RA fixes
+
+  Revision 1.65  2003/09/03 15:55:01  peter
     * NEWRA branch merged
 
   Revision 1.64.2.2  2003/08/31 15:46:26  peter

+ 9 - 5
compiler/i386/n386obj.pas

@@ -47,9 +47,9 @@ uses
 
 {
 possible calling conventions:
-              default stdcall cdecl pascal popstack register saveregisters
-default(0):      OK     OK    OK(1)  OK     OK(1)      OK          OK
-virtual(2):      OK     OK    OK(3)  OK     OK(3)      OK          OK(4)
+              default stdcall cdecl pascal register saveregisters
+default(0):      OK     OK    OK(1)  OK       OK          OK
+virtual(2):      OK     OK    OK(3)  OK       OK          OK(4)
 
 (0):
     set self parameter to correct value
@@ -177,7 +177,7 @@ begin
   adjustselfvalue(procdef,ioffset);
 
   { case 1 or 2 }
-  if (po_clearstack in procdef.procoptions) then
+  if (procdef.proccalloption in clearstack_pocalls) then
     begin
       if po_virtualmethod in procdef.procoptions then
         begin { case 2 }
@@ -228,7 +228,11 @@ initialization
 end.
 {
   $Log$
-  Revision 1.21  2003-09-03 15:55:01  peter
+  Revision 1.22  2003-09-07 22:09:35  peter
+    * preparations for different default calling conventions
+    * various RA fixes
+
+  Revision 1.21  2003/09/03 15:55:01  peter
     * NEWRA branch merged
 
   Revision 1.20.2.1  2003/08/29 17:29:00  peter

+ 8 - 9
compiler/i386/n386set.pas

@@ -214,8 +214,7 @@ implementation
                { use the register as base in a reference (JM)                }
                if ranges then
                  begin
-                   pleftreg:=left.location.register;
-                   setsubreg(pleftreg,R_SUBWHOLE);
+                   pleftreg:=rg.makeregsize(left.location.register,OS_INT);
                    cg.a_load_reg_reg(exprasmlist,left.location.size,OS_INT,left.location.register,pleftreg);
                    if opsize <> S_L then
                      emit_const_reg(A_AND,S_L,255,pleftreg);
@@ -225,8 +224,7 @@ implementation
                  { otherwise simply use the lower 8 bits (no "and" }
                  { necessary this way) (JM)                        }
                  begin
-                   pleftreg:=left.location.register;
-                   setsubreg(pleftreg,R_SUBL);
+                   pleftreg:=rg.makeregsize(left.location.register,OS_8);
                    opsize := S_B;
                  end;
              end
@@ -494,10 +492,7 @@ implementation
                else
                 begin
                   if (left.location.loc in [LOC_REGISTER,LOC_CREGISTER]) then
-                    begin
-                      pleftreg:=left.location.register;
-                      setsubreg(pleftreg,R_SUBWHOLE);
-                    end
+                    pleftreg:=rg.makeregsize(left.location.register,OS_INT)
                   else
                     pleftreg:=rg.getregisterint(exprasmlist,OS_INT);
                   cg.a_load_loc_reg(exprasmlist,OS_INT,left.location,pleftreg);
@@ -689,7 +684,11 @@ begin
 end.
 {
   $Log$
-  Revision 1.64  2003-09-05 11:21:39  marco
+  Revision 1.65  2003-09-07 22:09:35  peter
+    * preparations for different default calling conventions
+    * various RA fixes
+
+  Revision 1.64  2003/09/05 11:21:39  marco
    * applied Peter's patch. Now cycles.
 
   Revision 1.63  2003/09/03 15:55:01  peter

+ 22 - 8
compiler/i386/rgcpu.pas

@@ -31,13 +31,15 @@ unit rgcpu;
     uses
       cpubase,
       cpuinfo,
-      aasmbase,aasmtai,aasmcpu,
+      aasmbase,aasmtai,
       cclasses,globtype,cgbase,cginfo,rgobj;
 
     type
        trgcpu = class(trgobj)
           fpuvaroffset : byte;
 
+          constructor create;override;
+
           { to keep the same allocation order as with the old routines }
           procedure add_constraints(reg:Tregister);override;
 
@@ -72,7 +74,6 @@ unit rgcpu;
 
          { corrects the fpu stack register by ofs }
          function correct_fpuregister(r : tregister;ofs : byte) : tregister;
-
        end;
 
 
@@ -80,13 +81,19 @@ unit rgcpu;
 
     uses
        systems,
-       globals,verbose,
-       tgobj;
+       globals,verbose;
 
 {************************************************************************}
 {                               trgcpu                                   }
 {************************************************************************}
 
+    constructor Trgcpu.create;
+      begin
+        inherited create;
+        cpu_registers:=6;
+      end;
+
+
     procedure Trgcpu.add_constraints(reg:Tregister);
     var
       supreg : tsuperregister;
@@ -230,22 +237,29 @@ unit rgcpu;
 
 
     function trgcpu.makeregsize(reg: tregister; size: tcgsize): tregister;
+      var
+        subreg : tsubregister;
       begin
         if getregtype(reg)<>R_INTREGISTER then
           internalerror(200306032);
+        subreg:=cgsize2subreg(size);
         result:=reg;
-        setsubreg(result,cgsize2subreg(size));
+        setsubreg(result,subreg);
+        add_constraints(result);
       end;
 
 
-
 initialization
-  rg := trgcpu.create(6);   {We use 6 int registers on i386.}
+  crgobj:=trgcpu;
 end.
 
 {
   $Log$
-  Revision 1.32  2003-09-03 15:55:01  peter
+  Revision 1.33  2003-09-07 22:09:35  peter
+    * preparations for different default calling conventions
+    * various RA fixes
+
+  Revision 1.32  2003/09/03 15:55:01  peter
     * NEWRA branch merged
 
   Revision 1.31.2.3  2003/08/31 13:50:16  daniel

+ 13 - 3
compiler/nbas.pas

@@ -27,7 +27,7 @@ unit nbas;
 interface
 
     uses
-       cpubase,
+       cpubase,cginfo,
        aasmbase,aasmtai,aasmcpu,
        node,
        tgobj,
@@ -53,6 +53,9 @@ interface
           p_asm : taasmoutput;
           currenttai : tai;
           getposition : boolean;
+          { Used registers in assembler block }
+          used_regs_int : tsuperregisterset;
+          used_regs_fpu : totherregisterset;
           constructor create(p : taasmoutput);virtual;
           constructor create_get_position;
           destructor destroy;override;
@@ -180,7 +183,7 @@ implementation
       verbose,globals,globtype,systems,
       symconst,symdef,symsym,symutil,defutil,defcmp,
       pass_1,
-      nld,ncal,nflw,rgobj,cginfo,cgbase
+      nld,ncal,nflw,rgobj,cgbase
       ;
 
 
@@ -483,6 +486,8 @@ implementation
         p_asm:=p;
         getposition:=false;
         currenttai:=nil;
+        used_regs_int:=[];
+        used_regs_fpu:=[];
       end;
 
 
@@ -531,6 +536,7 @@ implementation
       begin
         inherited ppuwrite(ppufile);
         ppufile.putbyte(byte(getposition));
+{$warning FIXME Add saving of register sets}
         if not getposition then
           begin
             hp:=tai(p_asm.first);
@@ -848,7 +854,11 @@ begin
 end.
 {
   $Log$
-  Revision 1.60  2003-09-03 15:55:00  peter
+  Revision 1.61  2003-09-07 22:09:35  peter
+    * preparations for different default calling conventions
+    * various RA fixes
+
+  Revision 1.60  2003/09/03 15:55:00  peter
     * NEWRA branch merged
 
   Revision 1.59.2.1  2003/08/27 20:23:55  peter

+ 6 - 2
compiler/ncal.pas

@@ -2288,7 +2288,7 @@ type
                      begin
                        { consider it has not inlined if called
                          again inside the args }
-                       procdefinition.proccalloption:=pocall_fpccall;
+                       procdefinition.proccalloption:=pocall_default;
                        firstpass(inlinecode);
                      end;
                 end
@@ -2514,7 +2514,11 @@ begin
 end.
 {
   $Log$
-  Revision 1.178  2003-09-06 22:27:08  florian
+  Revision 1.179  2003-09-07 22:09:35  peter
+    * preparations for different default calling conventions
+    * various RA fixes
+
+  Revision 1.178  2003/09/06 22:27:08  florian
     * fixed web bug 2669
     * cosmetic fix in printnode
     * tobjectdef.gettypename implemented

+ 11 - 1
compiler/ncgbas.pas

@@ -138,6 +138,9 @@ interface
              exit;
            end;
 
+         { Allocate registers used in the assembler block }
+         rg.allocexplicitregistersint(exprasmlist,used_regs_int);
+
          if inlining_procedure then
            begin
              objectlibrary.CreateUsedAsmSymbolList;
@@ -220,6 +223,9 @@ interface
              else
                exprasmList.concatlist(p_asm);
            end;
+
+         { Release register used in the assembler block }
+         rg.deallocexplicitregistersint(exprasmlist,used_regs_int);
        end;
 
 
@@ -309,7 +315,11 @@ begin
 end.
 {
   $Log$
-  Revision 1.38  2003-09-03 15:55:00  peter
+  Revision 1.39  2003-09-07 22:09:35  peter
+    * preparations for different default calling conventions
+    * various RA fixes
+
+  Revision 1.38  2003/09/03 15:55:00  peter
     * NEWRA branch merged
 
   Revision 1.37.2.1  2003/08/27 20:23:55  peter

+ 24 - 20
compiler/ncgcal.pas

@@ -661,6 +661,7 @@ implementation
               else
                 iolabel:=nil;
 
+(*
               regs_to_alloc:=Tprocdef(procdefinition).usedintregisters;
 
 {$ifdef i386}
@@ -675,24 +676,17 @@ implementation
               rg.used_in_proc_int:=rg.used_in_proc_int + tprocdef(procdefinition).usedintregisters;
               rg.used_in_proc_other:=rg.used_in_proc_other + tprocdef(procdefinition).usedotherregisters;
 {$endif i386}
+*)
            end
          else
            begin
-              regs_to_alloc:=VOLATILE_INTREGISTERS;
-{$ifdef i386}
-              regs_to_push_other := all_otherregisters;
-{$else i386}
-              regs_to_push_other := VOLATILE_FPUREGISTERS;
-{$endif i386}
-{$ifdef i386}
-              rg.used_in_proc_int:=VOLATILE_INTREGISTERS;
-              rg.used_in_proc_other:=all_otherregisters;
-{$endif i386}
-
               { no IO check for methods and procedure variables }
               iolabel:=nil;
            end;
 
+        regs_to_alloc:=paramanager.get_volatile_registers_int(procdefinition.proccalloption);
+        regs_to_push_other:=paramanager.get_volatile_registers_fpu(procdefinition.proccalloption);
+
         { Include Function result registers }
         if (not is_void(resulttype.def)) then
           begin
@@ -758,7 +752,7 @@ implementation
          if assigned(left) then
            begin
               tcallparanode(left).secondcallparan(
-                (po_leftright in procdefinition.procoptions),procdefinition.proccalloption,
+                (procdefinition.proccalloption in pushleftright_pocalls),procdefinition.proccalloption,
                  para_alignment,0);
 
              pushparas;
@@ -875,7 +869,7 @@ implementation
            end;
 
          { Need to remove the parameters from the stack? }
-         if (po_clearstack in procdefinition.procoptions) then
+         if (procdefinition.proccalloption in clearstack_pocalls) then
           begin
             { the old pop_size was already included in pushedparasize }
             pop_size:=pushedparasize;
@@ -933,9 +927,9 @@ implementation
               //reference_reset_symbol(href,iolabel,0);
               //cg.a_paramaddr_ref(exprasmlist,href,paramanager.getintparaloc(exprasmlist,1));
               //paramanager.freeintparaloc(exprasmlist,1);
-              rg.allocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS);
+              rg.allocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default));
               cg.a_call_name(exprasmlist,'FPC_IOCHECK');
-              rg.deallocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS);
+              rg.deallocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default));
            end;
 
          { restore registers }
@@ -1133,8 +1127,12 @@ implementation
 
          { save all used registers and possible registers
            used for the return value }
+(*
          regs_to_push_int := tprocdef(procdefinition).usedintregisters;
          regs_to_push_other := tprocdef(procdefinition).usedotherregisters;
+*)
+         regs_to_push_int:=paramanager.get_volatile_registers_int(procdefinition.proccalloption);
+         regs_to_push_other:=paramanager.get_volatile_registers_fpu(procdefinition.proccalloption);
          if (not is_void(resulttype.def)) then
            begin
              case procdefinition.funcret_paraloc[callerside].loc of
@@ -1155,11 +1153,13 @@ implementation
 
          rg.saveusedotherregisters(exprasmlist,pushedother,regs_to_push_other);
 
+(*
 {$ifdef i386}
          { give used registers through }
          rg.used_in_proc_int:=rg.used_in_proc_int + tprocdef(procdefinition).usedintregisters;
          rg.used_in_proc_other:=rg.used_in_proc_other + tprocdef(procdefinition).usedotherregisters;
 {$endif i386}
+*)
 
          { Initialize for pushing the parameters }
          oldpushedparasize:=pushedparasize;
@@ -1174,7 +1174,7 @@ implementation
               { we push from right to left, so start with parameters at the end of
                 the parameter block }
               tcallparanode(left).secondcallparan(
-                  (po_leftright in procdefinition.procoptions),procdefinition.proccalloption,
+                  (procdefinition.proccalloption in pushleftright_pocalls),procdefinition.proccalloption,
                   0,procdefinition.parast.address_fixup+procdefinition.parast.datasize);
            end;
          aktcallnode:=oldaktcallnode;
@@ -1249,9 +1249,9 @@ implementation
               //reference_reset_symbol(href,iolabel,0);
               //cg.a_paramaddr_ref(exprasmlist,href,paramanager.getintparaloc(exprasmlist,1));
               //paramanager.freeintparaloc(exprasmlist,1);
-              rg.allocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS);
+              rg.allocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default));
               cg.a_call_name(exprasmlist,'FPC_IOCHECK');
-              rg.deallocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS);
+              rg.deallocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default));
            end;
 
          { restore registers }
@@ -1331,7 +1331,11 @@ begin
 end.
 {
   $Log$
-  Revision 1.110  2003-09-04 15:39:58  peter
+  Revision 1.111  2003-09-07 22:09:35  peter
+    * preparations for different default calling conventions
+    * various RA fixes
+
+  Revision 1.110  2003/09/04 15:39:58  peter
     * released useparatemp
 
   Revision 1.109  2003/09/03 15:55:00  peter
@@ -1403,7 +1407,7 @@ end.
 
   Revision 1.95  2003/06/17 16:34:44  jonas
     * lots of newra fixes (need getfuncretparaloc implementation for i386)!
-    * renamed all_intregisters to volatile_intregisters and made it
+    * renamed all_intregisters to paramanager.get_volatile_registers_int(pocall_default) and made it
       processor dependent
 
   Revision 1.94  2003/06/15 16:52:02  jonas

+ 37 - 33
compiler/ncgflw.pas

@@ -816,16 +816,16 @@ implementation
               paramanager.freeintparaloc(exprasmlist,3);
               paramanager.freeintparaloc(exprasmlist,2);
               paramanager.freeintparaloc(exprasmlist,1);
-              rg.allocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS);
+              rg.allocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default));
               cg.a_call_name(exprasmlist,'FPC_RAISEEXCEPTION');
-              rg.deallocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS);
+              rg.deallocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default));
            end
          else
            begin
-              rg.allocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS);
+              rg.allocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default));
               cg.a_call_name(exprasmlist,'FPC_POPADDRSTACK');
               cg.a_call_name(exprasmlist,'FPC_RERAISE');
-              rg.deallocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS);
+              rg.deallocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default));
            end;
        end;
 
@@ -863,14 +863,14 @@ implementation
     procedure cleanupobjectstack;
 
       begin
-         rg.allocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS);
+         rg.allocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default));
          cg.a_call_name(exprasmlist,'FPC_POPOBJECTSTACK');
-         rg.deallocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS);
+         rg.deallocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default));
          cg.a_param_reg(exprasmlist,OS_ADDR,NR_FUNCTION_RESULT_REG,paramanager.getintparaloc(exprasmlist,1));
          paramanager.freeintparaloc(exprasmlist,1);
-         rg.allocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS);
+         rg.allocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default));
          cg.a_call_name(exprasmlist,'FPC_DESTROYEXCEPTION');
-         rg.deallocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS);
+         rg.deallocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default));
       end;
 
 
@@ -975,9 +975,9 @@ implementation
               }
               cg.a_param_const(exprasmlist,OS_ADDR,aword(-1),paramanager.getintparaloc(exprasmlist,1));
               paramanager.freeintparaloc(exprasmlist,1);
-              rg.allocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS);
+              rg.allocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default));
               cg.a_call_name(exprasmlist,'FPC_CATCHES');
-              rg.deallocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS);
+              rg.deallocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default));
 
               { the destruction of the exception object must be also }
               { guarded by an exception frame                        }
@@ -995,15 +995,15 @@ implementation
 
               try_free_exception(exprasmlist,tempbuf,tempaddr,href,0,doobjectdestroy,false);
 
-              rg.allocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS);
+              rg.allocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default));
               cg.a_call_name(exprasmlist,'FPC_POPSECONDOBJECTSTACK');
-              rg.deallocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS);
+              rg.deallocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default));
 
               cg.a_param_reg(exprasmlist, OS_ADDR, NR_FUNCTION_RESULT_REG, paramanager.getintparaloc(exprasmlist,1));
               paramanager.freeintparaloc(exprasmlist,1);
-              rg.allocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS);
+              rg.allocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default));
               cg.a_call_name(exprasmlist,'FPC_DESTROYEXCEPTION');
-              rg.deallocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS);
+              rg.deallocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default));
               { we don't need to restore esi here because reraise never }
               { returns                                                 }
               cg.a_call_name(exprasmlist,'FPC_RERAISE');
@@ -1024,9 +1024,9 @@ implementation
               cg.a_label(exprasmlist,exitexceptlabel);
               { we must also destroy the address frame which guards }
               { exception object                                    }
-              rg.allocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS);
+              rg.allocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default));
               cg.a_call_name(exprasmlist,'FPC_POPADDRSTACK');
-              rg.deallocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS);
+              rg.deallocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default));
               cg.g_exception_reason_load(exprasmlist,href);
               cleanupobjectstack;
               cg.a_jmp_always(exprasmlist,oldaktexitlabel);
@@ -1037,9 +1037,9 @@ implementation
               cg.a_label(exprasmlist,breakexceptlabel);
               { we must also destroy the address frame which guards }
               { exception object                                    }
-              rg.allocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS);
+              rg.allocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default));
               cg.a_call_name(exprasmlist,'FPC_POPADDRSTACK');
-              rg.deallocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS);
+              rg.deallocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default));
               cg.g_exception_reason_load(exprasmlist,href);
               cleanupobjectstack;
               cg.a_jmp_always(exprasmlist,oldaktbreaklabel);
@@ -1050,9 +1050,9 @@ implementation
               cg.a_label(exprasmlist,continueexceptlabel);
               { we must also destroy the address frame which guards }
               { exception object                                    }
-              rg.allocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS);
+              rg.allocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default));
               cg.a_call_name(exprasmlist,'FPC_POPADDRSTACK');
-              rg.deallocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS);
+              rg.deallocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default));
               cg.g_exception_reason_load(exprasmlist,href);
               cleanupobjectstack;
               cg.a_jmp_always(exprasmlist,oldaktcontinuelabel);
@@ -1062,9 +1062,9 @@ implementation
            begin
               { do some magic for exit in the try block }
               cg.a_label(exprasmlist,exittrylabel);
-              rg.allocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS);
+              rg.allocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default));
               cg.a_call_name(exprasmlist,'FPC_POPADDRSTACK');
-              rg.deallocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS);
+              rg.deallocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default));
               cg.g_exception_reason_load(exprasmlist,href);
               cg.a_jmp_always(exprasmlist,oldaktexitlabel);
            end;
@@ -1072,9 +1072,9 @@ implementation
          if fc_break in tryflowcontrol then
            begin
               cg.a_label(exprasmlist,breaktrylabel);
-              rg.allocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS);
+              rg.allocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default));
               cg.a_call_name(exprasmlist,'FPC_POPADDRSTACK');
-              rg.deallocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS);
+              rg.deallocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default));
               cg.g_exception_reason_load(exprasmlist,href);
               cg.a_jmp_always(exprasmlist,oldaktbreaklabel);
            end;
@@ -1082,9 +1082,9 @@ implementation
          if fc_continue in tryflowcontrol then
            begin
               cg.a_label(exprasmlist,continuetrylabel);
-              rg.allocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS);
+              rg.allocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default));
               cg.a_call_name(exprasmlist,'FPC_POPADDRSTACK');
-              rg.deallocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS);
+              rg.deallocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default));
               cg.g_exception_reason_load(exprasmlist,href);
               cg.a_jmp_always(exprasmlist,oldaktcontinuelabel);
            end;
@@ -1136,9 +1136,9 @@ implementation
          reference_reset_symbol(href2,objectlibrary.newasmsymboldata(excepttype.vmt_mangledname),0);
          cg.a_paramaddr_ref(exprasmlist,href2,paramanager.getintparaloc(exprasmlist,1));
          paramanager.freeintparaloc(exprasmlist,1);
-         rg.allocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS);
+         rg.allocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default));
          cg.a_call_name(exprasmlist,'FPC_CATCHES');
-         rg.deallocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS);
+         rg.deallocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default));
 
          { is it this catch? No. go to next onlabel }
          cg.a_cmp_const_reg_label(exprasmlist,OS_ADDR,OC_EQ,0,NR_FUNCTION_RESULT_REG,nextonlabel);
@@ -1179,14 +1179,14 @@ implementation
 
          try_free_exception(exprasmlist,tempbuf,tempaddr,href,0,doobjectdestroy,false);
 
-         rg.allocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS);
+         rg.allocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default));
          cg.a_call_name(exprasmlist,'FPC_POPSECONDOBJECTSTACK');
-         rg.deallocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS);
+         rg.deallocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default));
          cg.a_param_reg(exprasmlist, OS_ADDR, NR_FUNCTION_RESULT_REG, paramanager.getintparaloc(exprasmlist,1));
          paramanager.freeintparaloc(exprasmlist,1);
-         rg.allocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS);
+         rg.allocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default));
          cg.a_call_name(exprasmlist,'FPC_DESTROYEXCEPTION');
-         rg.deallocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS);
+         rg.deallocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default));
          { we don't need to restore esi here because reraise never }
          { returns                                                 }
          cg.a_call_name(exprasmlist,'FPC_RERAISE');
@@ -1409,7 +1409,11 @@ begin
 end.
 {
   $Log$
-  Revision 1.78  2003-09-03 15:55:00  peter
+  Revision 1.79  2003-09-07 22:09:35  peter
+    * preparations for different default calling conventions
+    * various RA fixes
+
+  Revision 1.78  2003/09/03 15:55:00  peter
     * NEWRA branch merged
 
   Revision 1.77  2003/09/03 11:18:36  florian

+ 7 - 3
compiler/ncginl.pas

@@ -208,9 +208,9 @@ implementation
        paramanager.freeintparaloc(exprasmlist,3);
        paramanager.freeintparaloc(exprasmlist,2);
        paramanager.freeintparaloc(exprasmlist,1);
-       rg.allocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS);
+       rg.allocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default));
        cg.a_call_name(exprasmlist,'FPC_ASSERT');
-       rg.deallocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS);
+       rg.deallocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default));
        cg.a_label(exprasmlist,truelabel);
        truelabel:=otlabel;
        falselabel:=oflabel;
@@ -653,7 +653,11 @@ end.
 
 {
   $Log$
-  Revision 1.40  2003-09-03 15:55:00  peter
+  Revision 1.41  2003-09-07 22:09:35  peter
+    * preparations for different default calling conventions
+    * various RA fixes
+
+  Revision 1.40  2003/09/03 15:55:00  peter
     * NEWRA branch merged
 
   Revision 1.39.2.1  2003/08/29 17:28:59  peter

+ 20 - 16
compiler/ncgmem.pas

@@ -232,9 +232,9 @@ implementation
           begin
             cg.a_param_reg(exprasmlist, OS_ADDR,location.reference.base,paramanager.getintparaloc(exprasmlist,1));
             paramanager.freeintparaloc(exprasmlist,1);
-            rg.allocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS);
+            rg.allocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default));
             cg.a_call_name(exprasmlist,'FPC_CHECKPOINTER');
-            rg.deallocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS);
+            rg.deallocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default));
           end;
       end;
 
@@ -282,9 +282,9 @@ implementation
               begin
                 cg.a_param_reg(exprasmlist, OS_ADDR,location.reference.base,paramanager.getintparaloc(exprasmlist,1));
                 paramanager.freeintparaloc(exprasmlist,1);
-                rg.allocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS);
+                rg.allocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default));
                 cg.a_call_name(exprasmlist,'FPC_CHECKPOINTER');
-                rg.deallocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS);
+                rg.deallocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default));
               end;
            end
          else if is_interfacecom(left.resulttype.def) then
@@ -298,9 +298,9 @@ implementation
               begin
                 cg.a_param_reg(exprasmlist, OS_ADDR,location.reference.base,paramanager.getintparaloc(exprasmlist,1));
                 paramanager.freeintparaloc(exprasmlist,1);
-                rg.allocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS);
+                rg.allocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default));
                 cg.a_call_name(exprasmlist,'FPC_CHECKPOINTER');
-                rg.allocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS);
+                rg.allocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default));
               end;
 
            end
@@ -482,11 +482,11 @@ implementation
             begin
                cg.a_param_loc(exprasmlist,right.location,paramanager.getintparaloc(exprasmlist,2));
                cg.a_param_loc(exprasmlist,left.location,paramanager.getintparaloc(exprasmlist,1));
-               rg.allocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS);
+               rg.allocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default));
                cg.a_call_name(exprasmlist,'FPC_DYNARRAY_RANGECHECK');
                paramanager.freeintparaloc(exprasmlist,2);
                paramanager.freeintparaloc(exprasmlist,1);
-               rg.deallocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS);
+               rg.deallocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default));
             end
          else
            cg.g_rangecheck(exprasmlist,right.location,right.resulttype.def,left.resulttype.def);
@@ -540,10 +540,10 @@ implementation
               if (cs_check_range in aktlocalswitches) then
                 begin
                    cg.a_param_reg(exprasmlist,OS_ADDR,location.reference.base,paramanager.getintparaloc(exprasmlist,1));
-                   rg.allocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS);
+                   rg.allocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default));
                    cg.a_call_name(exprasmlist,'FPC_'+upper(tstringdef(left.resulttype.def).stringtypname)+'_CHECKZERO');
                    paramanager.freeintparaloc(exprasmlist,1);
-                   rg.deallocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS);
+                   rg.deallocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default));
                 end;
 
               { in ansistrings/widestrings S[1] is p<w>char(S)[0] !! }
@@ -620,11 +620,11 @@ implementation
                               href:=location.reference;
                               dec(href.offset,7);
                               cg.a_param_ref(exprasmlist,OS_INT,href,paramanager.getintparaloc(exprasmlist,1));
-                              rg.allocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS);
+                              rg.allocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default));
                               cg.a_call_name(exprasmlist,'FPC_'+upper(tstringdef(left.resulttype.def).stringtypname)+'_RANGECHECK');
                               paramanager.freeintparaloc(exprasmlist,2);
                               paramanager.freeintparaloc(exprasmlist,1);
-                              rg.deallocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS);
+                              rg.deallocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default));
                            end;
 
                          st_shortstring:
@@ -750,11 +750,11 @@ implementation
                               href:=location.reference;
                               dec(href.offset,7);
                               cg.a_param_ref(exprasmlist,OS_INT,href,paramanager.getintparaloc(exprasmlist,1));
-                              rg.allocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS);
+                              rg.allocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default));
                               cg.a_call_name(exprasmlist,'FPC_'+upper(tstringdef(left.resulttype.def).stringtypname)+'_RANGECHECK');
                               paramanager.freeintparaloc(exprasmlist,2);
                               paramanager.freeintparaloc(exprasmlist,1);
-                              rg.deallocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS);
+                              rg.deallocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default));
                            end;
                          st_shortstring:
                            begin
@@ -787,7 +787,11 @@ begin
 end.
 {
   $Log$
-  Revision 1.70  2003-09-03 15:55:00  peter
+  Revision 1.71  2003-09-07 22:09:35  peter
+    * preparations for different default calling conventions
+    * various RA fixes
+
+  Revision 1.70  2003/09/03 15:55:00  peter
     * NEWRA branch merged
 
   Revision 1.69.2.1  2003/08/29 17:28:59  peter
@@ -817,7 +821,7 @@ end.
 
   Revision 1.63  2003/06/17 16:34:44  jonas
     * lots of newra fixes (need getfuncretparaloc implementation for i386)!
-    * renamed all_intregisters to volatile_intregisters and made it
+    * renamed all_intregisters to paramanager.get_volatile_registers_int(pocall_default) and made it
       processor dependent
 
   Revision 1.62  2003/06/13 21:19:30  peter

+ 6 - 2
compiler/ncgopt.pas

@@ -185,7 +185,7 @@ begin
     end
   else
     cg.a_load_const_ref(exprasmlist,OS_8,tordconstnode(right).value,href2);
-  setsubreg(lengthreg,R_SUBL);
+  lengthreg:=rg.makeregsize(lengthreg,OS_8);
   { increase the string length }
   cg.a_op_const_reg(exprasmlist,OP_ADD,OS_8,1,lengthreg);
   cg.a_load_reg_ref(exprasmlist,OS_8,OS_8,lengthreg,left.location.reference);
@@ -201,7 +201,11 @@ end.
 
 {
   $Log$
-  Revision 1.7  2003-09-03 15:55:00  peter
+  Revision 1.8  2003-09-07 22:09:35  peter
+    * preparations for different default calling conventions
+    * various RA fixes
+
+  Revision 1.7  2003/09/03 15:55:00  peter
     * NEWRA branch merged
 
   Revision 1.6.2.1  2003/08/29 17:28:59  peter

+ 90 - 60
compiler/ncgutil.pas

@@ -60,8 +60,10 @@ interface
 
     procedure gen_proc_symbol(list:Taasmoutput);
     procedure gen_stackalloc_code(list:Taasmoutput);
+    procedure gen_save_used_regs(list : TAAsmoutput);
+    procedure gen_restore_used_regs(list : TAAsmoutput;usesacc,usesacchi,usesfpu:boolean);
     procedure gen_entry_code(list:TAAsmoutput;inlined:boolean);
-    procedure gen_exit_code(list : TAAsmoutput;inlined,usesacc,usesacchi,usesfpu:boolean);
+    procedure gen_exit_code(list:TAAsmoutput;inlined,usesacc,usesacchi:boolean);
 
 (*
     procedure geninlineentrycode(list : TAAsmoutput;stackframe:longint);
@@ -263,15 +265,15 @@ implementation
        paramanager.freeintparaloc(list,3);
        paramanager.freeintparaloc(list,2);
        paramanager.freeintparaloc(list,1);
-       rg.allocexplicitregistersint(list,VOLATILE_INTREGISTERS);
+       rg.allocexplicitregistersint(list,paramanager.get_volatile_registers_int(pocall_default));
        cg.a_call_name(list,'FPC_PUSHEXCEPTADDR');
-       rg.deallocexplicitregistersint(list,VOLATILE_INTREGISTERS);
+       rg.deallocexplicitregistersint(list,paramanager.get_volatile_registers_int(pocall_default));
 
        cg.a_param_reg(list,OS_ADDR,NR_FUNCTION_RESULT_REG,paramanager.getintparaloc(list,1));
        paramanager.freeintparaloc(list,1);
-       rg.allocexplicitregistersint(list,VOLATILE_INTREGISTERS);
+       rg.allocexplicitregistersint(list,paramanager.get_volatile_registers_int(pocall_default));
        cg.a_call_name(list,'FPC_SETJMP');
-       rg.deallocexplicitregistersint(list,VOLATILE_INTREGISTERS);
+       rg.deallocexplicitregistersint(list,paramanager.get_volatile_registers_int(pocall_default));
 
        cg.g_exception_reason_save(list, href);
        cg.a_cmp_const_reg_label(list,OS_S32,OC_NE,0,NR_FUNCTION_RESULT_REG,exceptlabel);
@@ -282,9 +284,9 @@ implementation
      a : aword ; endexceptlabel : tasmlabel; onlyfree : boolean);
 
      begin
-         rg.allocexplicitregistersint(list,VOLATILE_INTREGISTERS);
+         rg.allocexplicitregistersint(list,paramanager.get_volatile_registers_int(pocall_default));
          cg.a_call_name(list,'FPC_POPADDRSTACK');
-         rg.deallocexplicitregistersint(list,VOLATILE_INTREGISTERS);
+         rg.deallocexplicitregistersint(list,paramanager.get_volatile_registers_int(pocall_default));
 
          if not onlyfree then
           begin
@@ -315,8 +317,7 @@ implementation
               { load a smaller size to OS_64 }
               if l.loc=LOC_REGISTER then
                begin
-                 hregister:=l.registerlow;
-                 setsubreg(hregister,R_SUBWHOLE);
+                 hregister:=rg.makeregsize(l.registerlow,OS_32);
                  cg.a_load_reg_reg(list,l.size,OS_32,l.registerlow,hregister);
                end
               else
@@ -1039,9 +1040,9 @@ implementation
                  reference_reset_base(href,current_procinfo.framepointer,hp^.pos);
                  cg.a_paramaddr_ref(list,href,paramanager.getintparaloc(list,1));
                  paramanager.freeintparaloc(list,1);
-                 rg.allocexplicitregistersint(list,VOLATILE_INTREGISTERS);
+                 rg.allocexplicitregistersint(list,paramanager.get_volatile_registers_int(pocall_default));
                  cg.a_call_name(list,'FPC_ANSISTR_DECR_REF');
-                 rg.deallocexplicitregistersint(list,VOLATILE_INTREGISTERS);
+                 rg.deallocexplicitregistersint(list,paramanager.get_volatile_registers_int(pocall_default));
                end;
              tt_widestring,
              tt_freewidestring :
@@ -1049,18 +1050,18 @@ implementation
                  reference_reset_base(href,current_procinfo.framepointer,hp^.pos);
                  cg.a_paramaddr_ref(list,href,paramanager.getintparaloc(list,1));
                  paramanager.freeintparaloc(list,1);
-                 rg.allocexplicitregistersint(list,VOLATILE_INTREGISTERS);
+                 rg.allocexplicitregistersint(list,paramanager.get_volatile_registers_int(pocall_default));
                  cg.a_call_name(list,'FPC_WIDESTR_DECR_REF');
-                 rg.deallocexplicitregistersint(list,VOLATILE_INTREGISTERS);
+                 rg.deallocexplicitregistersint(list,paramanager.get_volatile_registers_int(pocall_default));
                end;
              tt_interfacecom :
                begin
                  reference_reset_base(href,current_procinfo.framepointer,hp^.pos);
                  cg.a_paramaddr_ref(list,href,paramanager.getintparaloc(list,1));
                  paramanager.freeintparaloc(list,1);
-                 rg.allocexplicitregistersint(list,VOLATILE_INTREGISTERS);
+                 rg.allocexplicitregistersint(list,paramanager.get_volatile_registers_int(pocall_default));
                  cg.a_call_name(list,'FPC_INTF_DECR_REF');
-                 rg.deallocexplicitregistersint(list,VOLATILE_INTREGISTERS);
+                 rg.deallocexplicitregistersint(list,paramanager.get_volatile_registers_int(pocall_default));
                end;
            end;
            hp:=hp^.next;
@@ -1068,6 +1069,10 @@ implementation
       end;
 
 
+(*
+    Return value is in the localst/parast and will be initialized by the
+    foreach loop (PFV)
+
     procedure initretvalue(list:taasmoutput);
       var
         href    : treference;
@@ -1091,6 +1096,7 @@ implementation
                end;
           end;
       end;
+*)
 
 
     procedure gen_load_return_value(list:TAAsmoutput; var uses_acc,uses_acchi,uses_fpu : boolean);
@@ -1230,8 +1236,10 @@ implementation
               cg.g_profilecode(list);
           end;
 
+(*
         { initialize return value }
         initretvalue(list);
+*)
 
         { initialize local data like ansistrings }
         case current_procinfo.procdef.proctypeoption of
@@ -1278,15 +1286,15 @@ implementation
                  cg.a_paramaddr_ref(list,href,paramanager.getintparaloc(list,1));
                  paramanager.freeintparaloc(list,2);
                  paramanager.freeintparaloc(list,1);
-                 rg.allocexplicitregistersint(list,VOLATILE_INTREGISTERS);
+                 rg.allocexplicitregistersint(list,paramanager.get_volatile_registers_int(pocall_cdecl));
                  cg.a_call_name(list,'_monstartup');
-                 rg.deallocexplicitregistersint(list,VOLATILE_INTREGISTERS);
+                 rg.deallocexplicitregistersint(list,paramanager.get_volatile_registers_int(pocall_cdecl));
                end;
 
               { initialize units }
-              rg.allocexplicitregistersint(list,VOLATILE_INTREGISTERS);
+              rg.allocexplicitregistersint(list,paramanager.get_volatile_registers_int(pocall_default));
               cg.a_call_name(list,'FPC_INITIALIZEUNITS');
-              rg.deallocexplicitregistersint(list,VOLATILE_INTREGISTERS);
+              rg.deallocexplicitregistersint(list,paramanager.get_volatile_registers_int(pocall_default));
             end;
 
 {$ifdef GDB}
@@ -1417,6 +1425,62 @@ implementation
       end;
 
 
+    procedure gen_save_used_regs(list : TAAsmoutput);
+      begin
+        { Pure assembler routines need to save the registers themselves }
+        if (po_assembler in current_procinfo.procdef.procoptions) then
+          exit;
+
+        { for the save all registers we can simply use a pusha,popa which
+          push edi,esi,ebp,esp(ignored),ebx,edx,ecx,eax }
+        if (po_saveregisters in current_procinfo.procdef.procoptions) then
+          cg.g_save_all_registers(list)
+        else
+          if current_procinfo.procdef.proccalloption in savestdregs_pocalls then
+            cg.g_save_standard_registers(list,rg.used_in_proc_int);
+
+(*
+        { Save stackpointer value }
+        if not inlined and
+           (current_procinfo.framepointer<>NR_STACK_POINTER_REG) and
+           ((po_savestdregs in current_procinfo.procdef.procoptions) or
+            (po_saveregisters in current_procinfo.procdef.procoptions)) then
+         begin
+           tg.GetTemp(list,POINTER_SIZE,tt_noreuse,current_procinfo.save_stackptr_ref);
+           cg.a_load_reg_ref(list,OS_ADDR,OS_ADDR,NR_STACK_POINTER_REG,current_procinfo.save_stackptr_ref);
+         end;
+*)
+      end;
+
+
+    procedure gen_restore_used_regs(list : TAAsmoutput;usesacc,usesacchi,usesfpu:boolean);
+      begin
+        { Pure assembler routines need to save the registers themselves }
+        if (po_assembler in current_procinfo.procdef.procoptions) then
+          exit;
+
+(*
+        { Restore stackpointer if it was saved }
+        if not inlined and
+           (current_procinfo.framepointer<>NR_STACK_POINTER_REG) and
+           ((po_savestdregs in current_procinfo.procdef.procoptions) or
+            (po_saveregisters in current_procinfo.procdef.procoptions)) then
+         begin
+           cg.a_load_ref_reg(list,OS_ADDR,OS_ADDR,current_procinfo.save_stackptr_ref,NR_STACK_POINTER_REG);
+           tg.UngetTemp(list,current_procinfo.save_stackptr_ref);
+         end;
+*)
+
+        { for the save all registers we can simply use a pusha,popa which
+          push edi,esi,ebp,esp(ignored),ebx,edx,ecx,eax }
+        if (po_saveregisters in current_procinfo.procdef.procoptions) then
+          cg.g_restore_all_registers(list,usesacc,usesacchi)
+        else
+          if current_procinfo.procdef.proccalloption in savestdregs_pocalls then
+            cg.g_restore_standard_registers(list,rg.used_in_proc_int);
+      end;
+
+
     procedure gen_entry_code(list:TAAsmoutput;inlined:boolean);
       var
         href : treference;
@@ -1470,29 +1534,10 @@ implementation
                   end;
               end;
           end;
-
-        { for the save all registers we can simply use a pusha,popa which
-          push edi,esi,ebp,esp(ignored),ebx,edx,ecx,eax }
-        if (po_saveregisters in current_procinfo.procdef.procoptions) then
-          cg.g_save_all_registers(list)
-        else
-         { should we save edi,esi,ebx like C ? }
-         if (po_savestdregs in current_procinfo.procdef.procoptions) then
-           cg.g_save_standard_registers(list,current_procinfo.procdef.usedintregisters);
-
-        { Save stackpointer value }
-        if not inlined and
-           (current_procinfo.framepointer<>NR_STACK_POINTER_REG) and
-           ((po_savestdregs in current_procinfo.procdef.procoptions) or
-            (po_saveregisters in current_procinfo.procdef.procoptions)) then
-         begin
-           tg.GetTemp(list,POINTER_SIZE,tt_noreuse,current_procinfo.save_stackptr_ref);
-           cg.a_load_reg_ref(list,OS_ADDR,OS_ADDR,NR_STACK_POINTER_REG,current_procinfo.save_stackptr_ref);
-         end;
       end;
 
 
-    procedure gen_exit_code(list : TAAsmoutput;inlined,usesacc,usesacchi,usesfpu:boolean);
+    procedure gen_exit_code(list:TAAsmoutput;inlined,usesacc,usesacchi:boolean);
       var
 {$ifdef GDB}
         stabsendlabel : tasmlabel;
@@ -1511,25 +1556,6 @@ implementation
           end;
 {$endif GDB}
 
-        { Restore stackpointer if it was saved }
-        if not inlined and
-           (current_procinfo.framepointer<>NR_STACK_POINTER_REG) and
-           ((po_savestdregs in current_procinfo.procdef.procoptions) or
-            (po_saveregisters in current_procinfo.procdef.procoptions)) then
-         begin
-           cg.a_load_ref_reg(list,OS_ADDR,OS_ADDR,current_procinfo.save_stackptr_ref,NR_STACK_POINTER_REG);
-           tg.UngetTemp(list,current_procinfo.save_stackptr_ref);
-         end;
-
-        { for the save all registers we can simply use a pusha,popa which
-          push edi,esi,ebp,esp(ignored),ebx,edx,ecx,eax }
-        if (po_saveregisters in current_procinfo.procdef.procoptions) then
-          cg.g_restore_all_registers(list,usesacc,usesacchi)
-        else
-         { should we restore edi ? }
-         if (po_savestdregs in current_procinfo.procdef.procoptions) then
-           cg.g_restore_standard_registers(list,current_procinfo.procdef.usedintregisters);
-
 {$ifndef powerpc}
         { remove stackframe }
         if not inlined then
@@ -1552,7 +1578,7 @@ implementation
             cg.g_interrupt_stackframe_exit(list,usesacc,usesacchi)
            else
             begin
-              if (po_clearstack in current_procinfo.procdef.procoptions) then
+              if current_procinfo.procdef.proccalloption in clearstack_pocalls then
                 begin
                   retsize:=0;
                   if paramanager.ret_in_param(current_procinfo.procdef.rettype.def,current_procinfo.procdef.proccalloption) then
@@ -1779,7 +1805,11 @@ implementation
 end.
 {
   $Log$
-  Revision 1.139  2003-09-03 15:55:01  peter
+  Revision 1.140  2003-09-07 22:09:35  peter
+    * preparations for different default calling conventions
+    * various RA fixes
+
+  Revision 1.139  2003/09/03 15:55:01  peter
     * NEWRA branch merged
 
   Revision 1.138  2003/09/03 11:18:37  florian

+ 6 - 2
compiler/nld.pas

@@ -488,7 +488,7 @@ implementation
                 { we need a register for call by reference parameters }
                 if (tvarsym(symtableentry).varspez in [vs_var,vs_out]) or
                    ((tvarsym(symtableentry).varspez=vs_const) and
-                    paramanager.push_addr_param(tvarsym(symtableentry).vartype.def,pocall_none)) or
+                    paramanager.push_addr_param(tvarsym(symtableentry).vartype.def,pocall_default)) or
                     { call by value open arrays are also indirect addressed }
                     is_open_array(tvarsym(symtableentry).vartype.def) then
                   registers32:=1;
@@ -1287,7 +1287,11 @@ begin
 end.
 {
   $Log$
-  Revision 1.103  2003-07-08 15:20:56  peter
+  Revision 1.104  2003-09-07 22:09:35  peter
+    * preparations for different default calling conventions
+    * various RA fixes
+
+  Revision 1.103  2003/07/08 15:20:56  peter
     * don't allow add/assignments for formaldef
     * formaldef size changed to 0
 

+ 8 - 4
compiler/nmat.pas

@@ -238,11 +238,10 @@ implementation
 
 
     function tmoddivnode.first_moddivint: tnode;
+{$ifdef cpuneedsdiv32helper}
       var
         procname: string[31];
       begin
-{$ifdef cpuneedsdiv32helper}
-      begin
         result := nil;
 
         { otherwise create a call to a helper }
@@ -264,9 +263,10 @@ implementation
         firstpass(result);
       end;
 {$else cpuneedsdiv32helper}
+      begin
         result:=nil;
-{$endif cpuneedsdiv32helper}
       end;
+{$endif cpuneedsdiv32helper}
 
 
     function tmoddivnode.first_moddiv64bitint: tnode;
@@ -831,7 +831,11 @@ begin
 end.
 {
   $Log$
-  Revision 1.50  2003-09-03 11:18:37  florian
+  Revision 1.51  2003-09-07 22:09:35  peter
+    * preparations for different default calling conventions
+    * various RA fixes
+
+  Revision 1.50  2003/09/03 11:18:37  florian
     * fixed arm concatcopy
     + arm support in the common compiler sources added
     * moved some generic cg code around

+ 21 - 3
compiler/paramgr.pas

@@ -29,7 +29,7 @@ unit paramgr;
   interface
 
     uses
-       cpubase,
+       cpubase,cginfo,
        aasmtai,
        globtype,
        symconst,symtype,symdef;
@@ -70,6 +70,8 @@ unit paramgr;
             @param(list Current assembler list)
             @param(nr Parameter number of routine, starting from 1)
           }
+          function get_volatile_registers_int(calloption : tproccalloption):tsuperregisterset;virtual;
+          function get_volatile_registers_fpu(calloption : tproccalloption):tsuperregisterset;virtual;
           function getintparaloc(list: taasmoutput; nr : longint) : tparalocation;virtual;abstract;
 
           {# frees a parameter location allocated with getintparaloc
@@ -123,7 +125,7 @@ implementation
        cpuinfo,globals,systems,
        symbase,symsym,
        rgobj,
-       defutil,cgbase,cginfo,verbose;
+       defutil,cgbase,verbose;
 
     { true if uses a parameter as return value }
     function tparamanager.ret_in_param(def : tdef;calloption : tproccalloption) : boolean;
@@ -244,6 +246,18 @@ implementation
       end;
 
 
+    function tparamanager.get_volatile_registers_int(calloption : tproccalloption):tsuperregisterset;
+      begin
+        result:=[];
+      end;
+
+
+    function tparamanager.get_volatile_registers_fpu(calloption : tproccalloption):tsuperregisterset;
+      begin
+        result:=[];
+      end;
+
+
     procedure tparamanager.allocparaloc(list: taasmoutput; const loc: tparalocation);
       begin
         case loc.loc of
@@ -348,7 +362,11 @@ end.
 
 {
    $Log$
-   Revision 1.52  2003-09-04 15:39:58  peter
+   Revision 1.53  2003-09-07 22:09:35  peter
+     * preparations for different default calling conventions
+     * various RA fixes
+
+   Revision 1.52  2003/09/04 15:39:58  peter
      * released useparatemp
 
    Revision 1.51  2003/09/03 15:55:01  peter

+ 22 - 45
compiler/pdecsub.pas

@@ -273,7 +273,7 @@ implementation
               { Give a warning that cdecl routines does not include high()
                 support }
               if (pd.proccalloption in [pocall_cdecl,pocall_cppdecl]) and
-                 paramanager.push_high_param(currpara.paratype.def,pocall_fpccall) then
+                 paramanager.push_high_param(currpara.paratype.def,pocall_default) then
                begin
                  if is_open_string(currpara.paratype.def) then
                     Message(parser_w_cdecl_no_openstring);
@@ -965,7 +965,7 @@ begin
           begin
             Message1(parser_w_not_supported_for_inline,'array of const');
             Message(parser_w_inlining_disabled);
-            pd.proccalloption:=pocall_fpccall;
+            pd.proccalloption:=pocall_default;
           end;
       end;
      hp:=tparaitem(hp.next);
@@ -1185,7 +1185,7 @@ type
    end;
 const
   {Should contain the number of procedure directives we support.}
-  num_proc_directives=35;
+  num_proc_directives=34;
   proc_direcdata:array[1..num_proc_directives] of proc_dir_rec=
    (
     (
@@ -1277,7 +1277,7 @@ const
       pooption : [];
       mutexclpocall : [];
       mutexclpotype : [];
-      mutexclpo     : [po_external,po_leftright]
+      mutexclpo     : [po_external]
     ),(
       idtok:_FORWARD;
       pd_flags : [pd_implemen,pd_notobject,pd_notobjintf];
@@ -1288,14 +1288,14 @@ const
       mutexclpotype : [];
       mutexclpo     : [po_external]
     ),(
-      idtok:_FPCCALL;
+      idtok:_OLDFPCCALL;
       pd_flags : [pd_interface,pd_implemen,pd_body,pd_procvar];
       handler  : nil;
-      pocall   : pocall_fpccall;
+      pocall   : pocall_oldfpccall;
       pooption : [];
       mutexclpocall : [];
       mutexclpotype : [];
-      mutexclpo     : [po_leftright]
+      mutexclpo     : []
     ),(
       idtok:_INLINE;
       pd_flags : [pd_interface,pd_implemen,pd_body,pd_notobjintf];
@@ -1322,17 +1322,17 @@ const
       pooption : [];
       mutexclpocall : [];
       mutexclpotype : [potype_constructor,potype_destructor,potype_operator];
-      mutexclpo     : [po_exports,po_external,po_interrupt,po_assembler,po_iocheck,po_leftright]
+      mutexclpo     : [po_exports,po_external,po_interrupt,po_assembler,po_iocheck]
     ),(
       idtok:_INTERRUPT;
       pd_flags : [pd_implemen,pd_body,pd_notobject,pd_notobjintf];
       handler  : {$ifdef FPCPROCVAR}@{$endif}pd_interrupt;
       pocall   : pocall_none;
       pooption : [po_interrupt];
-      mutexclpocall : [pocall_internproc,pocall_cdecl,pocall_cppdecl,
-                       pocall_inline,pocall_pascal,pocall_far16,pocall_fpccall];
+      mutexclpocall : [pocall_internproc,pocall_cdecl,pocall_cppdecl,pocall_stdcall,
+                       pocall_inline,pocall_pascal,pocall_far16,pocall_oldfpccall];
       mutexclpotype : [potype_constructor,potype_destructor,potype_operator];
-      mutexclpo     : [po_external,po_leftright,po_clearstack]
+      mutexclpo     : [po_external]
     ),(
       idtok:_IOCHECK;
       pd_flags : [pd_implemen,pd_body,pd_notobjintf];
@@ -1387,15 +1387,6 @@ const
       mutexclpocall : [];
       mutexclpotype : [potype_constructor,potype_destructor];
       mutexclpo     : [po_external]
-    ),(
-      idtok:_POPSTACK;
-      pd_flags : [pd_interface,pd_implemen,pd_body,pd_procvar];
-      handler  : nil;
-      pocall   : pocall_none;
-      pooption : [po_clearstack];
-      mutexclpocall : [pocall_inline,pocall_internproc,pocall_stdcall];
-      mutexclpotype : [potype_constructor,potype_destructor];
-      mutexclpo     : [po_assembler,po_external]
     ),(
       idtok:_PUBLIC;
       pd_flags : [pd_implemen,pd_body,pd_notobject,pd_notobjintf];
@@ -1482,7 +1473,7 @@ const
       pd_flags : [pd_interface,pd_implemen,pd_body,pd_procvar];
       handler  : nil;
       pocall   : pocall_cppdecl;
-      pooption : [po_savestdregs];
+      pooption : [];
       mutexclpocall : [];
       mutexclpotype : [potype_constructor,potype_destructor];
       mutexclpo     : [po_assembler,po_external,po_virtualmethod]
@@ -1493,9 +1484,9 @@ const
       pocall   : pocall_none;
       pooption : [po_varargs];
       mutexclpocall : [pocall_internproc,pocall_stdcall,pocall_register,
-                       pocall_inline,pocall_far16,pocall_fpccall];
+                       pocall_inline,pocall_far16,pocall_oldfpccall];
       mutexclpotype : [];
-      mutexclpo     : [po_assembler,po_interrupt,po_leftright]
+      mutexclpo     : [po_assembler,po_interrupt]
     ),(
       idtok:_COMPILERPROC;
       pd_flags : [pd_interface,pd_implemen,pd_body,pd_notobjintf];
@@ -1656,9 +1647,6 @@ const
         case pd.proccalloption of
           pocall_cdecl :
             begin
-              { use popstack and save std registers }
-              include(pd.procoptions,po_clearstack);
-              include(pd.procoptions,po_savestdregs);
               { set mangledname }
               if (pd.deftype=procdef) then
                begin
@@ -1677,9 +1665,6 @@ const
             end;
           pocall_cppdecl :
             begin
-              { use popstack and save std registers }
-              include(pd.procoptions,po_clearstack);
-              include(pd.procoptions,po_savestdregs);
               { set mangledname }
               if (pd.deftype=procdef) then
                begin
@@ -1693,27 +1678,18 @@ const
             end;
           pocall_stdcall :
             begin
-              include(pd.procoptions,po_savestdregs);
               if (pd.deftype=procdef) then
                begin
                  { Adjust alignment to match cdecl or stdcall }
                  pd.parast.dataalignment:=std_param_align;
                end;
             end;
-          pocall_safecall :
-            begin
-              include(pd.procoptions,po_savestdregs);
-            end;
           pocall_compilerproc :
             begin
               if (pd.deftype<>procdef) then
                internalerror(200110232);
               tprocdef(pd).setmangledname(lower(tprocdef(pd).procsym.name));
             end;
-          pocall_pascal :
-            begin
-              include(pd.procoptions,po_leftright);
-            end;
           pocall_register :
             begin
               Message1(parser_w_proc_directive_ignored,'REGISTER');
@@ -1725,9 +1701,6 @@ const
             end;
           pocall_palmossyscall :
             begin
-              { use popstack and save std registers }
-              include(pd.procoptions,po_clearstack);
-              include(pd.procoptions,po_savestdregs);
               if (pd.deftype=procdef) then
                begin
                  { Adjust positions of args for cdecl or stdcall }
@@ -1739,7 +1712,7 @@ const
               if not(cs_support_inline in aktmoduleswitches) then
                begin
                  Message(parser_e_proc_inline_not_supported);
-                 pd.proccalloption:=pocall_fpccall;
+                 pd.proccalloption:=pocall_default;
                end;
             end;
         end;
@@ -1795,7 +1768,7 @@ const
 
            { Calculate symtable addresses }
            st:=pd.parast;
-           if po_leftright in pd.procoptions then
+           if pd.proccalloption in pushleftright_pocalls then
             begin
               { pushed from left to right, so the in reverse order
                 on the stack }
@@ -2022,7 +1995,7 @@ const
                    { Check procedure options, Delphi requires that class is
                      repeated in the implementation for class methods }
                    if (m_fpc in aktmodeswitches) then
-                     po_comp:=[po_varargs,po_methodpointer,po_interrupt,po_clearstack]
+                     po_comp:=[po_varargs,po_methodpointer,po_interrupt]
                    else
                      po_comp:=[po_classmethod,po_methodpointer];
 
@@ -2168,7 +2141,11 @@ const
 end.
 {
   $Log$
-  Revision 1.130  2003-09-03 11:18:37  florian
+  Revision 1.131  2003-09-07 22:09:35  peter
+    * preparations for different default calling conventions
+    * various RA fixes
+
+  Revision 1.130  2003/09/03 11:18:37  florian
     * fixed arm concatcopy
     + arm support in the common compiler sources added
     * moved some generic cg code around

+ 15 - 6
compiler/pmodules.pas

@@ -40,7 +40,7 @@ implementation
        globals,verbose,fmodule,finput,fppu,
        symconst,symbase,symtype,symdef,symsym,symtable,
        aasmbase,aasmtai,aasmcpu,
-       cgbase,cpuinfo,
+       cgbase,cpuinfo,rgobj,
        ncgutil,
        link,assemble,import,export,gendef,ppu,comprsrc,
        cresstr,cpubase,
@@ -725,6 +725,8 @@ implementation
         current_procinfo:=cprocinfo.create(nil);
         current_module.procinfo:=current_procinfo;
         current_procinfo.procdef:=pd;
+        { start register allocator }
+        rg:=crgobj.create;
         { return procdef }
         create_main_proc:=pd;
       end;
@@ -737,6 +739,8 @@ implementation
            assigned(current_procinfo.parent) or
            not(current_procinfo.procdef=pd) then
          internalerror(200304276);
+        { remove register allocator }
+        rg.free;
         { remove procinfo }
         current_module.procinfo:=nil;
         current_procinfo.free;
@@ -786,11 +790,15 @@ implementation
         usesfpu:=false;
         usesacchi:=false;
         gen_load_return_value(list,usesacc,usesacchi,usesfpu);
+        { Add save and restore of used registers }
+        gen_save_used_regs(templist);
+        list.insertlistafter(headertai,templist);
+        gen_restore_used_regs(list,usesacc,usesacchi,usesfpu);
         { Add stack allocation code after header }
         gen_stackalloc_code(templist);
         list.insertlistafter(headertai,templist);
         { Add exit code at the end }
-        gen_exit_code(list,false,usesacc,usesacchi,usesfpu);
+        gen_exit_code(list,false,usesacc,usesacchi);
         release_main_proc(pd);
         templist.free;
       end;
@@ -1322,9 +1330,6 @@ implementation
             { Win32 startup code needs a single name }
 //            if (target_info.system in [system_i386_win32,system_i386_wdosx]) then
             pd.aliasnames.insert('PASCALMAIN');
-            { this code is called from C so we need to save some
-              registers }
-            include(pd.procoptions,po_savestdregs);
           end
          else
           begin
@@ -1465,7 +1470,11 @@ implementation
 end.
 {
   $Log$
-  Revision 1.121  2003-09-05 17:41:12  florian
+  Revision 1.122  2003-09-07 22:09:35  peter
+    * preparations for different default calling conventions
+    * various RA fixes
+
+  Revision 1.121  2003/09/05 17:41:12  florian
     * merged Wiktor's Watcom patches in 1.1
 
   Revision 1.120  2003/08/23 22:29:24  peter

+ 11 - 7
compiler/pstatmnt.pas

@@ -800,7 +800,7 @@ implementation
                  Begin
                     Message1(parser_w_not_supported_for_inline,'direct asm');
                     Message(parser_w_inlining_disabled);
-                    current_procinfo.procdef.proccalloption:=pocall_fpccall;
+                    current_procinfo.procdef.proccalloption:=pocall_default;
                  End;
                asmstat:=tasmnode(radirect.assemble);
              end;
@@ -814,7 +814,7 @@ implementation
          { END is read, got a list of changed registers? }
          if try_to_consume(_LECKKLAMMER) then
            begin
-             rg.used_in_proc_other:=ALL_OTHERREGISTERS;
+             asmstat.used_regs_fpu:=ALL_OTHERREGISTERS;
              if token<>_RECKKLAMMER then
               begin
                 repeat
@@ -823,7 +823,7 @@ implementation
                   if reg<>NR_NO then
                     begin
                       if getregtype(reg)=R_INTREGISTER then
-                        include(rg.used_in_proc_int,getsupreg(reg));
+                        include(asmstat.used_regs_int,getsupreg(reg));
                     end
                   else
                     Message(asmr_e_invalid_register);
@@ -836,8 +836,8 @@ implementation
            end
          else
            begin
-              rg.used_in_proc_int:=VOLATILE_INTREGISTERS;
-              rg.used_in_proc_other:=ALL_OTHERREGISTERS;
+              asmstat.used_regs_int:=paramanager.get_volatile_registers_int(current_procinfo.procdef.proccalloption);
+              asmstat.used_regs_fpu:=ALL_OTHERREGISTERS;
            end;
 
          { mark the start and the end of the assembler block
@@ -1181,7 +1181,11 @@ implementation
 end.
 {
   $Log$
-  Revision 1.107  2003-09-03 15:55:01  peter
+  Revision 1.108  2003-09-07 22:09:35  peter
+    * preparations for different default calling conventions
+    * various RA fixes
+
+  Revision 1.107  2003/09/03 15:55:01  peter
     * NEWRA branch merged
 
   Revision 1.106.2.3  2003/08/31 15:46:26  peter
@@ -1198,7 +1202,7 @@ end.
 
   Revision 1.105  2003/06/17 16:34:44  jonas
     * lots of newra fixes (need getfuncretparaloc implementation for i386)!
-    * renamed all_intregisters to volatile_intregisters and made it
+    * renamed all_intregisters to paramanager.get_volatile_registers_int(pocall_default) and made it
       processor dependent
 
   Revision 1.104  2003/06/13 21:19:31  peter

+ 34 - 31
compiler/psub.pas

@@ -574,6 +574,7 @@ implementation
 
     procedure tcgprocinfo.generate_code;
       var
+        oldrg : trgobj;
         oldprocinfo : tprocinfo;
         oldaktmaxfpuregisters : longint;
         oldfilepos : tfileposinfo;
@@ -591,6 +592,7 @@ implementation
           exit;
 
         oldprocinfo:=current_procinfo;
+        oldrg:=rg;
         oldfilepos:=aktfilepos;
         oldaktmaxfpuregisters:=aktmaxfpuregisters;
 
@@ -604,8 +606,11 @@ implementation
         { add parast/localst to symtablestack }
         add_to_symtablestack;
 
-        { reset the temporary memory }
-        rg.cleartempgen;
+        { set the start offset to the start of the temp area in the stack }
+        tg.setfirsttemp(firsttemp_offset);
+
+        { Create register allocator }
+        rg:=crgobj.create;
 
 {$warning FIXME!!}
         { FIXME!! If a procedure contains assembler blocks (or is pure assembler), }
@@ -615,21 +620,14 @@ implementation
         { assembler procedures... For non-i386, the changed registers are even     }
         { always all volatile registers (JM)                                       }
 {$ifdef i386}
-        if not(po_assembler in current_procinfo.procdef.procoptions) then
+        if (po_assembler in current_procinfo.procdef.procoptions) then
           begin
-            rg.used_in_proc_int:=[{RS_STACK_POINTER_REG}];
-            rg.used_in_proc_other:=[];
-          end
-        else
-{$endif i386}
-          begin
-            rg.used_in_proc_int:={$ifdef i386}[]{$else}VOLATILE_INTREGISTERS{$endif};
-            rg.used_in_proc_other:=VOLATILE_FPUREGISTERS;
+            rg.used_in_proc_int:=paramanager.get_volatile_registers_int(pocall_oldfpccall);
+            rg.used_in_proc_other:=paramanager.get_volatile_registers_int(pocall_oldfpccall);
           end;
+{$endif i386}
 
-        { set the start offset to the start of the temp area in the stack }
-        tg.setfirsttemp(firsttemp_offset);
-
+        { generate code for the body }
         generatecode(code);
 
         { first generate entry and initialize code with the correct
@@ -682,21 +680,21 @@ implementation
 
         { The procedure body is finished, we can now
           allocate the registers }
-{$ifdef ra_debug2}
-        rg.writegraph;
-{$endif}
         if not(cs_no_regalloc in aktglobalswitches) then
           begin
             {Do register allocation.}
             spillingcounter:=0;
             repeat
+{$ifdef EXTDEBUG}
+//              if aktfilepos.line=1207 then
+//                rg.writegraph(spillingcounter);
+{$endif EXTDEBUG}
               rg.prepare_colouring;
               rg.colour_registers;
               rg.epilogue_colouring;
               if rg.spillednodes='' then
                 break;
-              if not rg.spill_registers(aktproccode,rg.spillednodes) then
-                break;
+              rg.spill_registers(aktproccode,rg.spillednodes);
               inc(spillingcounter);
               if spillingcounter>maxspillingcounter then
                 internalerror(200309041);
@@ -713,17 +711,23 @@ implementation
           end;
 
         translate_regvars(aktproccode,rg.colour);
+        { Add save and restore of used registers }
+        gen_save_used_regs(templist);
+        aktproccode.insertlistafter(headertai,templist);
+        gen_restore_used_regs(aktproccode,usesacc,usesacchi,usesfpu);
         { Add stack allocation code after header }
         gen_stackalloc_code(templist);
         aktproccode.insertlistafter(headertai,templist);
         { Add exit code at the end }
-        gen_exit_code(templist,false,usesacc,usesacchi,usesfpu);
+        gen_exit_code(templist,false,usesacc,usesacchi);
         aktproccode.concatlist(templist);
 
+(*
         { now all the registers used are known }
         { Remove all imaginary registers from the used list.}
-        procdef.usedintregisters:=rg.used_in_proc_int*VOLATILE_INTREGISTERS-rg.savedintbyproc;
+        procdef.usedintregisters:=rg.used_in_proc_int*paramanager.get_volatile_registers_int(pocall_default)-rg.preserved_by_proc_int;
         procdef.usedotherregisters:=rg.used_in_proc_other;
+*)
 
         { save local data (casetable) also in the same file }
         if assigned(aktlocaldata) and
@@ -745,8 +749,6 @@ implementation
           codesegment.concat(Tai_cut.Create);
         codesegment.concatlist(aktproccode);
 
-        { all registers can be used again }
-        rg.resetusableregisters;
         { only now we can remove the temps }
         tg.resettempgen;
 
@@ -754,7 +756,9 @@ implementation
         remove_from_symtablestack;
 
         { restore }
+        rg.free;
         templist.free;
+        rg:=oldrg;
         aktmaxfpuregisters:=oldaktmaxfpuregisters;
         aktfilepos:=oldfilepos;
         current_procinfo:=oldprocinfo;
@@ -873,11 +877,6 @@ implementation
          { constant symbols are inserted in this symboltable }
          constsymtable:=symtablestack;
 
-         { reset the temporary memory }
-         rg.cleartempgen;
-         rg.used_in_proc_int:=[];
-         rg.used_in_proc_other:=[];
-
          { save entry info }
          entrypos:=aktfilepos;
          entryswitches:=aktlocalswitches;
@@ -1216,7 +1215,7 @@ implementation
              Begin
                 Message1(parser_w_not_supported_for_inline,tokenstring(t));
                 Message(parser_w_inlining_disabled);
-                current_procinfo.procdef.proccalloption:=pocall_fpccall;
+                current_procinfo.procdef.proccalloption:=pocall_default;
              End;
         end;
 
@@ -1315,7 +1314,11 @@ begin
 end.
 {
   $Log$
-  Revision 1.141  2003-09-04 14:46:12  peter
+  Revision 1.142  2003-09-07 22:09:35  peter
+    * preparations for different default calling conventions
+    * various RA fixes
+
+  Revision 1.141  2003/09/04 14:46:12  peter
     * abort with IE when spilling requires > 20 loops
 
   Revision 1.140  2003/09/03 15:55:01  peter
@@ -1371,7 +1374,7 @@ end.
 
   Revision 1.129  2003/06/17 16:34:44  jonas
     * lots of newra fixes (need getfuncretparaloc implementation for i386)!
-    * renamed all_intregisters to volatile_intregisters and made it
+    * renamed all_intregisters to paramanager.get_volatile_registers_int(pocall_default) and made it
       processor dependent
 
   Revision 1.128  2003/06/14 14:53:50  jonas

+ 6 - 2
compiler/regvars.pas

@@ -554,7 +554,7 @@ implementation
                     end
                   else
                     begin
-                      setsubreg(reg,cgsize2subreg(OS_INT));
+                      reg:=rg.makeregsize(reg,OS_INT);
                       regidx:=findreg_by_number(reg);
                       if (rg.regvar_loaded_other[regidx]) then
                        asml.concat(tai_regalloc.dealloc(reg));
@@ -610,7 +610,11 @@ end.
 
 {
   $Log$
-  Revision 1.63  2003-09-03 15:55:01  peter
+  Revision 1.64  2003-09-07 22:09:35  peter
+    * preparations for different default calling conventions
+    * various RA fixes
+
+  Revision 1.63  2003/09/03 15:55:01  peter
     * NEWRA branch merged
 
   Revision 1.62.2.2  2003/08/29 17:28:59  peter

+ 76 - 79
compiler/rgobj.pas

@@ -178,9 +178,8 @@ unit rgobj;
           { Contains the registers which are really used by the proc itself.
             It doesn't take care of registers used by called procedures
           }
-          savedintbyproc,
-          used_in_proc_int,
-          usedaddrinproc : Tsuperregisterset;
+          preserved_by_proc_int,
+          used_in_proc_int : Tsuperregisterset;
           used_in_proc_other : totherregisterset;
 
           reg_pushes_other : regvarother_longintarray;
@@ -194,7 +193,8 @@ unit rgobj;
           { tries to hold the amount of times which the current tree is processed  }
           t_times: longint;
 
-          constructor create(Acpu_registers:byte);
+          constructor create;virtual;
+          destructor destroy;virtual;
 
           {# Allocate a general purpose register
 
@@ -287,14 +287,6 @@ unit rgobj;
           }
           procedure ungetreference(list: taasmoutput; const ref : treference); virtual;
 
-          {# Reset the register allocator information (usable registers etc).
-             Please note that it is mortal sins to call cleartempgen during
-             graph colouring (that is between prepare_colouring and
-             epilogue_colouring).
-          }
-
-          procedure cleartempgen;virtual;
-
           {# Convert a register to a specified register size, and return that register size }
           function makeregsize(reg: tregister; size: tcgsize): tregister; virtual;
 
@@ -338,9 +330,9 @@ unit rgobj;
 
           procedure saveUnusedState(var state: pointer);virtual;
           procedure restoreUnusedState(var state: pointer);virtual;
-{$ifdef ra_debug2}
-          procedure writegraph;
-{$endif ra_debug2}
+{$ifdef EXTDEBUG}
+          procedure writegraph(loopidx:longint);
+{$endif EXTDEBUG}
           procedure add_move_instruction(instr:Taicpu);
           procedure prepare_colouring;
           procedure epilogue_colouring;
@@ -395,6 +387,8 @@ unit rgobj;
          procedure clear_interferences(u:Tsuperregister);
        end;
 
+       trgobjclass = class of trgobj;
+
      const
        {# This value is used in tsaved. If the array value is equal
           to this, then this means that this register is not used.
@@ -403,7 +397,8 @@ unit rgobj;
 
      var
        {# This is the class instance used to access the register allocator class }
-       rg: trgobj;
+       crgobj : trgobjclass;
+       rg : trgobj;
 
      { trerefence handling }
 
@@ -462,11 +457,11 @@ unit rgobj;
   implementation
 
     uses
-       systems,{$ifdef ra_debug2}fmodule,{$endif}
+       systems,{$ifdef EXTDEBUG}fmodule,{$endif}
        globals,verbose,
        cgobj,tgobj,regvars;
 
-    constructor Trgobj.create(Acpu_registers:byte);
+    constructor Trgobj.create;
 
      begin
        used_in_proc_int := [];
@@ -475,12 +470,17 @@ unit rgobj;
        resetusableregisters;
        lastintreg:=0;
        maxintreg:=first_int_imreg;
-       {What madman decided to change the code like this: (??)
-       cpu_registers:=last_int_supreg-first_int_supreg+1;
-       The amount of registers available for register allocation is
-       allmost allways smaller than the amount of registers that exists!
-       Therefore: }
-       cpu_registers:=Acpu_registers;
+       cpu_registers:=0;
+       unusedregsint:=[0..254]; { 255 (RS_INVALID) can't be used }
+       unusedregsfpu:=usableregsfpu;
+       unusedregsmm:=usableregsmm;
+       countunusedregsfpu:=countusableregsfpu;
+       countunusedregsmm:=countusableregsmm;
+{$ifdef powerpc}
+       preserved_by_proc_int:=[RS_R13..RS_R31];
+{$else powerpc}
+       preserved_by_proc_int:=[];
+{$endif powerpc}
        fillchar(igraph,sizeof(igraph),0);
        fillchar(degree,sizeof(degree),0);
        {Precoloured nodes should have an infinite degree, which we can approach
@@ -488,9 +488,26 @@ unit rgobj;
        fillchar(movelist,sizeof(movelist),0);
        worklist_moves:=Tlinkedlist.create;
        abtlist:='';
+       fillchar(colour,sizeof(colour),RS_INVALID);
      end;
 
 
+    destructor Trgobj.destroy;
+
+    var i:Tsuperregister;
+
+    begin
+      for i:=low(Tsuperregister) to high(Tsuperregister) do
+        begin
+          if igraph.adjlist[i]<>nil then
+            dispose(igraph.adjlist[i]);
+          if movelist[i]<>nil then
+            dispose(movelist[i]);
+        end;
+      worklist_moves.free;
+    end;
+
+
     function trgobj.getregistergenother(list: taasmoutput; const lowreg, highreg: tsuperregister;
         var unusedregs: tsuperregisterset; var countunusedregs: byte): tregister;
       var
@@ -541,6 +558,7 @@ unit rgobj;
             if i>maxintreg then
               maxintreg:=i;
             add_edges_used(i);
+            add_constraints(r);
             exit;
           end;
       until i=lastintreg;
@@ -581,6 +599,7 @@ unit rgobj;
         include(unusedregs,supreg);
         list.concat(tai_regalloc.dealloc(r));
         add_edges_used(supreg);
+        add_constraints(r);
       end;
 
 
@@ -590,10 +609,11 @@ unit rgobj;
 
     begin
       subreg:=cgsize2subreg(size);
+      { Leave 2 imaginary registers free for spilling (PFV) }
       result:=getregistergenint(list,
                                 subreg,
                                 first_int_imreg,
-                                last_int_imreg,
+                                last_int_imreg-2,
                                 used_in_proc_int,
                                 unusedregsint);
       add_constraints(getregisterint);
@@ -625,6 +645,7 @@ unit rgobj;
           include(used_in_proc_int,supreg);
           list.concat(tai_regalloc.alloc(r));
           add_edges_used(supreg);
+          add_constraints(r);
          end
        else
 {$ifndef ALLOWDUPREG}
@@ -772,42 +793,6 @@ unit rgobj;
       end;
 
 
-    procedure Trgobj.cleartempgen;
-
-    var i:Tsuperregister;
-
-    begin
-      countunusedregsfpu:=countusableregsfpu;
-      countunusedregsmm:=countusableregsmm;
-      lastintreg:=0;
-      maxintreg:=first_int_imreg;
-      unusedregsint:=[0..255];
-      unusedregsfpu:=usableregsfpu;
-      unusedregsmm:=usableregsmm;
-{$ifdef powerpc}
-      savedintbyproc:=[RS_R13..RS_R31];
-{$else powerpc}
-      savedintbyproc:=[];
-{$endif powerpc}
-      for i:=low(Tsuperregister) to high(Tsuperregister) do
-        begin
-          if igraph.adjlist[i]<>nil then
-            dispose(igraph.adjlist[i]);
-          if movelist[i]<>nil then
-            dispose(movelist[i]);
-        end;
-      fillchar(movelist,sizeof(movelist),0);
-      fillchar(igraph,sizeof(igraph),0);
-      fillchar(degree,sizeof(degree),0);
-      {Precoloured nodes should have an infinite degree, which we can approach
-       by 255.}
-      for i:=first_int_supreg to last_int_supreg do
-        degree[i]:=255;
-      worklist_moves.clear;
-      abtlist:='';
-    end;
-
-
     procedure trgobj.ungetreference(list : taasmoutput; const ref : treference);
 
       begin
@@ -1164,6 +1149,7 @@ unit rgobj;
         end;
     end;
 
+
     procedure Trgobj.add_edges_used(u:Tsuperregister);
 
     var i:Tsuperregister;
@@ -1174,8 +1160,8 @@ unit rgobj;
           add_edge(u,i);
     end;
 
-{$ifdef ra_debug2}
-    procedure Trgobj.writegraph;
+{$ifdef EXTDEBUG}
+    procedure Trgobj.writegraph(loopidx:longint);
 
     {This procedure writes out the current interference graph in the
     register allocator.}
@@ -1185,7 +1171,7 @@ unit rgobj;
         i,j:Tsuperregister;
 
     begin
-      assign(f,'igraph.'+Lower(current_module.modulename^));
+      assign(f,'igraph'+tostr(loopidx));
       rewrite(f);
       writeln(f,'Interference graph');
       writeln(f);
@@ -1210,7 +1196,7 @@ unit rgobj;
         end;
       close(f);
     end;
-{$endif ra_debug2}
+{$endif EXTDEBUG}
 
     procedure Trgobj.add_to_movelist(u:Tsuperregister;data:Tlinkedlistitem);
 
@@ -1750,11 +1736,10 @@ unit rgobj;
           freeze
         else if length(spillworklist)<>0 then
           select_spill;
-      until (length(simplifyworklist) or
-             byte(not(worklist_moves.empty)) or
-             length(freezeworklist) or
-             length(spillworklist)
-            )=0;
+      until (length(simplifyworklist)=0) and
+            worklist_moves.empty and
+            (length(freezeworklist)=0) and
+            (length(spillworklist)=0);
       assign_colours;
     end;
 
@@ -1911,7 +1896,11 @@ unit rgobj;
           i:=first_int_imreg
         else
           inc(i);
-        if (i in unusedregsint) and (pos(char(i),abtlist)=0) then
+        if (i in unusedregsint) and
+           (pos(char(i),abtlist)=0) and
+           (pos(char(i),spillednodes)=0) and
+            ((rg.colour[i] in unusedregsint) or
+            (rg.colour[i]=RS_INVALID)) then
           begin
             exclude(unusedregsint,i);
             include(used_in_proc_int,i);
@@ -1920,12 +1909,12 @@ unit rgobj;
               list.insert(Tai_regalloc.alloc(r))
             else
               list.insertafter(Tai_regalloc.alloc(r),position);
-            result:=r;
             lastintreg:=i;
             if i>maxintreg then
               maxintreg:=i;
             add_edges_used(i);
-            add_constraints(result);
+            add_constraints(r);
+            result:=r;
             exit;
           end;
       until i=lastintreg;
@@ -1958,6 +1947,7 @@ unit rgobj;
 
     var i:Tsuperregister;
         r:Tregister;
+        subreg:tsubregister;
         found:boolean;
 
     begin
@@ -1986,19 +1976,20 @@ unit rgobj;
         begin
           exclude(unusedregsint,i);
           include(used_in_proc_int,i);
-          r:=newreg(R_INTREGISTER,i,cgsize2subreg(size));
+          subreg:=cgsize2subreg(size);
+          r:=newreg(R_INTREGISTER,i,subreg);
           list.concat(Tai_regalloc.alloc(r));
           getabtregisterint:=r;
           lastintreg:=i;
           if i>maxintreg then
             maxintreg:=i;
           add_edges_used(i);
+          add_constraints(r);
           if pos(char(i),abtlist)=0 then
             abtlist:=abtlist+char(i);
         end
       else
         internalerror(10);
-      add_constraints(getabtregisterint);
     end;
 
     procedure Trgobj.ungetregisterintinline(list:Taasmoutput;position:Tai;r:Tregister);
@@ -2013,6 +2004,7 @@ unit rgobj;
       else
         list.insertafter(Tai_regalloc.dealloc(r),position);
       add_edges_used(supreg);
+      add_constraints(r);
     end;
 
     function Trgobj.spill_registers(list:Taasmoutput;const regs_to_spill:string):boolean;
@@ -2203,14 +2195,19 @@ unit rgobj;
 
 
 initialization
-   ;
-finalization
-  rg.free;
+  { This check is required because rgcpu is initialized before rgobj
+    when compiling with FPC 1.0.x (PFV) }
+  if not assigned(crgobj) then
+    crgobj:=trgobj;
 end.
 
 {
   $Log$
-  Revision 1.70  2003-09-03 21:06:45  peter
+  Revision 1.71  2003-09-07 22:09:35  peter
+    * preparations for different default calling conventions
+    * various RA fixes
+
+  Revision 1.70  2003/09/03 21:06:45  peter
     * fixes for FPU register allocation
 
   Revision 1.69  2003/09/03 15:55:01  peter

+ 23 - 4
compiler/symconst.pas

@@ -25,6 +25,9 @@ unit symconst;
 
 interface
 
+uses
+  globtype;
+
 const
   def_alignment = 4;
 
@@ -193,12 +196,9 @@ type
     po_msgint,            { method for int message handling }
     po_exports,           { Procedure has export directive (needed for OS/2) }
     po_external,          { Procedure is external (in other object or lib)}
-    po_savestdregs,       { save std regs cdecl and stdcall need that ! }
     po_saveregisters,     { save all registers }
     po_overload,          { procedure is declared with overload directive }
     po_varargs,           { printf like arguments }
-    po_leftright,         { push arguments from left to right }
-    po_clearstack,        { caller clears the stack }
     po_internconst,       { procedure has constant evaluator intern }
     po_addressonly,       { flag that only the address of a method is returned and not a full methodpointer }
     po_public             { procedure is exported }
@@ -333,7 +333,22 @@ const
     objectdef];
 {$endif GDB}
 
+
 const
+   savestdregs_pocalls = [
+     pocall_cdecl,pocall_cppdecl,pocall_palmossyscall,
+     pocall_stdcall,pocall_safecall,pocall_compilerproc,
+     pocall_register
+   ];
+
+   clearstack_pocalls = [
+     pocall_cdecl,pocall_cppdecl,pocall_palmossyscall
+   ];
+
+   pushleftright_pocalls = [
+     pocall_pascal
+   ];
+
      SymTypeName : array[tsymtyp] of string[12] = (
        'abstractsym','variable','type','proc','unit',
        'const','enum','typed const','errorsym','system sym',
@@ -357,7 +372,11 @@ implementation
 end.
 {
   $Log$
-  Revision 1.60  2003-08-11 21:18:20  peter
+  Revision 1.61  2003-09-07 22:09:35  peter
+    * preparations for different default calling conventions
+    * various RA fixes
+
+  Revision 1.60  2003/08/11 21:18:20  peter
     * start of sparc support for newra
 
   Revision 1.59  2003/08/10 17:25:23  peter

+ 10 - 6
compiler/symdef.pas

@@ -3419,7 +3419,7 @@ implementation
           end;
          lastref:=defref;
        { first, we assume that all registers are used }
-         usedintregisters:=VOLATILE_INTREGISTERS;
+         usedintregisters:=paramanager.get_volatile_registers_int(pocall_default);
          usedotherregisters:=ALL_OTHERREGISTERS;
          forwarddef:=true;
          interfacedef:=false;
@@ -3561,7 +3561,7 @@ implementation
          { set all registers to used for simplified compilation PM }
          if simplify_ppu then
            begin
-             usedintregisters:=VOLATILE_INTREGISTERS;
+             usedintregisters:=paramanager.get_volatile_registers_int(pocall_default);
              usedotherregisters:=ALL_OTHERREGISTERS;
            end;
 
@@ -4302,7 +4302,7 @@ implementation
 
              { write parameter info. The parameters must be written in reverse order
                if this method uses right to left parameter pushing! }
-             if (po_leftright in procoptions) then
+             if proccalloption in pushleftright_pocalls then
               pdc:=TParaItem(Para.first)
              else
               pdc:=TParaItem(Para.last);
@@ -4322,7 +4322,7 @@ implementation
                  { write name of type of current parameter }
                  tstoreddef(pdc.paratype.def).write_rtti_name;
 
-                 if (po_leftright in procoptions) then
+                 if proccalloption in pushleftright_pocalls then
                   pdc:=TParaItem(pdc.next)
                  else
                   pdc:=TParaItem(pdc.previous);
@@ -5848,7 +5848,11 @@ implementation
 end.
 {
   $Log$
-  Revision 1.161  2003-09-06 22:27:09  florian
+  Revision 1.162  2003-09-07 22:09:35  peter
+    * preparations for different default calling conventions
+    * various RA fixes
+
+  Revision 1.161  2003/09/06 22:27:09  florian
     * fixed web bug 2669
     * cosmetic fix in printnode
     * tobjectdef.gettypename implemented
@@ -5893,7 +5897,7 @@ end.
 
   Revision 1.152  2003/06/17 16:34:44  jonas
     * lots of newra fixes (need getfuncretparaloc implementation for i386)!
-    * renamed all_intregisters to volatile_intregisters and made it
+    * renamed all_intregisters to paramanager.get_volatile_registers_int(pocall_default) and made it
       processor dependent
 
   Revision 1.151  2003/06/08 11:41:21  peter

+ 7 - 5
compiler/tokens.pas

@@ -169,7 +169,6 @@ type
     _EXPORTS,
     _FINALLY,
     _FORWARD,
-    _FPCCALL,
     _IOCHECK,
     _LIBRARY,
     _MESSAGE,
@@ -189,7 +188,6 @@ type
     _OVERLOAD,
     _OVERRIDE,
     _PLATFORM,
-    _POPSTACK,
     _PROPERTY,
     _REGISTER,
     _RESIDENT,
@@ -208,6 +206,7 @@ type
     _DESTRUCTOR,
     _IMPLEMENTS,
     _INTERNPROC,
+    _OLDFPCCALL,
     _OPENSTRING,
     _CONSTRUCTOR,
     _INTERNCONST,
@@ -392,7 +391,6 @@ const
       (str:'EXPORTS'       ;special:false;keyword:m_all;op:NOTOKEN),
       (str:'FINALLY'       ;special:false;keyword:m_class;op:NOTOKEN),
       (str:'FORWARD'       ;special:false;keyword:m_none;op:NOTOKEN),
-      (str:'FPCCALL'       ;special:false;keyword:m_none;op:NOTOKEN),
       (str:'IOCHECK'       ;special:false;keyword:m_none;op:NOTOKEN),
       (str:'LIBRARY'       ;special:false;keyword:m_all;op:NOTOKEN),
       (str:'MESSAGE'       ;special:false;keyword:m_none;op:NOTOKEN),
@@ -412,7 +410,6 @@ const
       (str:'OVERLOAD'      ;special:false;keyword:m_none;op:NOTOKEN),
       (str:'OVERRIDE'      ;special:false;keyword:m_none;op:NOTOKEN),
       (str:'PLATFORM'      ;special:false;keyword:m_none;op:NOTOKEN),
-      (str:'POPSTACK'      ;special:false;keyword:m_none;op:NOTOKEN),
       (str:'PROPERTY'      ;special:false;keyword:m_class;op:NOTOKEN),
       (str:'REGISTER'      ;special:false;keyword:m_none;op:NOTOKEN),
       (str:'RESIDENT'      ;special:false;keyword:m_none;op:NOTOKEN),
@@ -431,6 +428,7 @@ const
       (str:'DESTRUCTOR'    ;special:false;keyword:m_all;op:NOTOKEN),
       (str:'IMPLEMENTS'    ;special:false;keyword:m_none;op:NOTOKEN),
       (str:'INTERNPROC'    ;special:false;keyword:m_none;op:NOTOKEN),
+      (str:'OLDFPCCALL'    ;special:false;keyword:m_none;op:NOTOKEN),
       (str:'OPENSTRING'    ;special:false;keyword:m_none;op:NOTOKEN),
       (str:'CONSTRUCTOR'   ;special:false;keyword:m_all;op:NOTOKEN),
       (str:'INTERNCONST'   ;special:false;keyword:m_none;op:NOTOKEN),
@@ -504,7 +502,11 @@ end;
 end.
 {
   $Log$
-  Revision 1.23  2003-09-04 21:58:16  olle
+  Revision 1.24  2003-09-07 22:09:35  peter
+    * preparations for different default calling conventions
+    * various RA fixes
+
+  Revision 1.23  2003/09/04 21:58:16  olle
     + bugfix, put token UNIMPLEMENTED in right order
 
   Revision 1.22  2003/08/10 17:25:23  peter

+ 13 - 9
compiler/x86/aasmcpu.pas

@@ -1920,7 +1920,7 @@ implementation
                     if oper[0].ref^.index=NR_NO then
                       pos:=Tai(previous)
                     else
-                      pos:=get_insert_pos(Tai(previous),getsupreg(oper[0].ref^.index),0,0,unusedregsint);
+                      pos:=get_insert_pos(Tai(previous),getsupreg(oper[0].ref^.index),RS_INVALID,RS_INVALID,unusedregsint);
                     rgget(list,pos,subreg,helpreg);
                     spill_registers:=true;
                     helpins:=Taicpu.op_ref_reg(A_MOV,reg2opsize(oper[0].ref^.base),spilltemplist[supreg],helpreg);
@@ -1946,7 +1946,7 @@ implementation
                     if oper[0].ref^.base=NR_NO then
                       pos:=Tai(previous)
                     else
-                      pos:=get_insert_pos(Tai(previous),getsupreg(oper[0].ref^.base),0,0,unusedregsint);
+                      pos:=get_insert_pos(Tai(previous),getsupreg(oper[0].ref^.base),RS_INVALID,RS_INVALID,unusedregsint);
                     rgget(list,pos,subreg,helpreg);
                     spill_registers:=true;
                     helpins:=Taicpu.op_ref_reg(A_MOV,reg2opsize(oper[0].ref^.index),spilltemplist[supreg],helpreg);
@@ -1981,9 +1981,9 @@ implementation
                       subreg:=getsubreg(oper[i].ref^.base);
                       if i=1 then
                         pos:=get_insert_pos(Tai(previous),getsupreg(oper[i].ref^.index),getsupreg(oper[0].reg),
-                                            0,unusedregsint)
+                                            RS_INVALID,unusedregsint)
                       else
-                        pos:=get_insert_pos(Tai(previous),getsupreg(oper[i].ref^.index),0,0,unusedregsint);
+                        pos:=get_insert_pos(Tai(previous),getsupreg(oper[i].ref^.index),RS_INVALID,RS_INVALID,unusedregsint);
                       rgget(list,pos,subreg,helpreg);
                       spill_registers:=true;
                       helpins:=Taicpu.op_ref_reg(A_MOV,reg2opsize(oper[i].ref^.base),spilltemplist[supreg],helpreg);
@@ -2008,9 +2008,9 @@ implementation
                       subreg:=getsubreg(oper[i].ref^.index);
                       if i=1 then
                         pos:=get_insert_pos(Tai(previous),getsupreg(oper[i].ref^.base),getsupreg(oper[0].reg),
-                                            0,unusedregsint)
+                                            RS_INVALID,unusedregsint)
                       else
-                        pos:=get_insert_pos(Tai(previous),getsupreg(oper[i].ref^.base),0,0,unusedregsint);
+                        pos:=get_insert_pos(Tai(previous),getsupreg(oper[i].ref^.base),RS_INVALID,RS_INVALID,unusedregsint);
                       rgget(list,pos,subreg,helpreg);
                       spill_registers:=true;
                       helpins:=Taicpu.op_ref_reg(A_MOV,reg2opsize(oper[i].ref^.index),spilltemplist[supreg],helpreg);
@@ -2082,7 +2082,7 @@ implementation
                          mov r22d,[r21d]      ; Use a help register
                          add [ebp-12],r22d    ; Replace register by helpregister }
                         pos:=get_insert_pos(Tai(previous),getsupreg(oper[0].ref^.base),
-                                            getsupreg(oper[0].ref^.index),0,unusedregsint);
+                                            getsupreg(oper[0].ref^.index),RS_INVALID,unusedregsint);
                         rgget(list,pos,subreg,helpreg);
                         spill_registers:=true;
                         op:=A_MOV;
@@ -2123,7 +2123,7 @@ implementation
                             op:=opcode;
                             opcode:=A_MOV;
                             opsize:=reg2opsize(oper[1].reg);
-                            pos:=get_insert_pos(Tai(previous),getsupreg(oper[0].reg),0,0,unusedregsint);
+                            pos:=get_insert_pos(Tai(previous),getsupreg(oper[0].reg),RS_INVALID,RS_INVALID,unusedregsint);
                             rgget(list,pos,subreg,helpreg);
                             helpins:=Taicpu.op_reg_reg(op,hopsize,oper[0].reg,helpreg);
                             if pos=nil then
@@ -2228,7 +2228,11 @@ implementation
 end.
 {
   $Log$
-  Revision 1.17  2003-09-03 15:55:02  peter
+  Revision 1.18  2003-09-07 22:09:35  peter
+    * preparations for different default calling conventions
+    * various RA fixes
+
+  Revision 1.17  2003/09/03 15:55:02  peter
     * NEWRA branch merged
 
   Revision 1.16.2.4  2003/08/31 15:46:26  peter

+ 68 - 23
compiler/x86/cgx86.pas

@@ -346,9 +346,9 @@ unit cgx86;
           OS_16,OS_S16:
             begin
               if target_info.alignment.paraalign = 2 then
-                setsubreg(r,R_SUBW)
+                r:=rg.makeregsize(r,OS_16)
               else
-                setsubreg(r,R_SUBD);
+                r:=rg.makeregsize(r,OS_32);
               list.concat(taicpu.op_reg(A_PUSH,S_L,r));
             end;
           OS_32,OS_S32:
@@ -1372,8 +1372,7 @@ unit cgx86;
                else
                  begin
                     objectlibrary.getlabel(again);
-                    r:=NR_EDI;
-                    rg.getexplicitregisterint(list,r);
+                    r:=rg.getexplicitregisterint(list,NR_EDI);
                     list.concat(Taicpu.op_const_reg(A_MOV,S_L,localsize div winstackpagesize,r));
                     a_label(list,again);
                     list.concat(Taicpu.op_const_reg(A_SUB,S_L,winstackpagesize-4,NR_ESP));
@@ -1395,7 +1394,7 @@ unit cgx86;
 
     begin
       list.concat(tai_regalloc.alloc(NR_EBP));
-      include(rg.savedintbyproc,RS_EBP);
+      include(rg.preserved_by_proc_int,RS_EBP);
       list.concat(Taicpu.op_reg(A_PUSH,S_L,NR_EBP));
       list.concat(Taicpu.op_reg_reg(A_MOV,S_L,NR_ESP,NR_EBP));
       if localsize>0 then
@@ -1415,7 +1414,7 @@ unit cgx86;
       begin
         { Routines with the poclearstack flag set use only a ret }
         { also routines with parasize=0     }
-        if (po_clearstack in current_procinfo.procdef.procoptions) then
+        if current_procinfo.procdef.proccalloption in clearstack_pocalls then
          begin
            { complex return values are removed from stack in C code PM }
            if paramanager.ret_in_param(current_procinfo.procdef.rettype.def,
@@ -1438,26 +1437,68 @@ unit cgx86;
 
 
     procedure tcgx86.g_save_standard_registers(list:Taasmoutput;usedinproc:Tsuperregisterset);
-
-    begin
-      if (RS_EBX in usedinproc) then
-        list.concat(Taicpu.op_reg(A_PUSH,S_L,NR_EBX));
-      list.concat(Taicpu.op_reg(A_PUSH,S_L,NR_ESI));
-      list.concat(Taicpu.op_reg(A_PUSH,S_L,NR_EDI));
-      include(rg.savedintbyproc,RS_EBX);
-      include(rg.savedintbyproc,RS_ESI);
-      include(rg.savedintbyproc,RS_EDI);
-    end;
+      var
+        href : treference;
+        size : longint;
+      begin
+        { Get temp }
+        size:=0;
+        if (RS_EBX in usedinproc) then
+          inc(size,POINTER_SIZE);
+        if (RS_ESI in usedinproc) then
+          inc(size,POINTER_SIZE);
+        if (RS_EDI in usedinproc) then
+          inc(size,POINTER_SIZE);
+        if size>0 then
+          begin
+            tg.GetTemp(list,size,tt_noreuse,current_procinfo.save_regs_ref);
+            { Copy registers to temp }
+            href:=current_procinfo.save_regs_ref;
+            if (RS_EBX in usedinproc) then
+              begin
+                cg.a_load_reg_ref(list,OS_ADDR,OS_ADDR,NR_EBX,href);
+                inc(href.offset,POINTER_SIZE);
+              end;
+            if (RS_ESI in usedinproc) then
+              begin
+                cg.a_load_reg_ref(list,OS_ADDR,OS_ADDR,NR_ESI,href);
+                inc(href.offset,POINTER_SIZE);
+              end;
+            if (RS_EDI in usedinproc) then
+              begin
+                cg.a_load_reg_ref(list,OS_ADDR,OS_ADDR,NR_EDI,href);
+                inc(href.offset,POINTER_SIZE);
+              end;
+          end;
+        include(rg.preserved_by_proc_int,RS_EBX);
+        include(rg.preserved_by_proc_int,RS_ESI);
+        include(rg.preserved_by_proc_int,RS_EDI);
+      end;
 
 
     procedure tcgx86.g_restore_standard_registers(list:Taasmoutput;usedinproc:Tsuperregisterset);
-
-    begin
-        list.concat(Taicpu.Op_reg(A_POP,S_L,NR_EDI));
-        list.concat(Taicpu.Op_reg(A_POP,S_L,NR_ESI));
+      var
+        href : treference;
+      begin
+        { Copy registers from temp }
+        href:=current_procinfo.save_regs_ref;
         if (RS_EBX in usedinproc) then
-         list.concat(Taicpu.Op_reg(A_POP,S_L,NR_EBX));
-    end;
+          begin
+            cg.a_load_ref_reg(list,OS_ADDR,OS_ADDR,href,NR_EBX);
+            inc(href.offset,POINTER_SIZE);
+          end;
+        if (RS_ESI in usedinproc) then
+          begin
+            cg.a_load_ref_reg(list,OS_ADDR,OS_ADDR,href,NR_ESI);
+            inc(href.offset,POINTER_SIZE);
+          end;
+        if (RS_EDI in usedinproc) then
+          begin
+            cg.a_load_ref_reg(list,OS_ADDR,OS_ADDR,href,NR_EDI);
+            inc(href.offset,POINTER_SIZE);
+          end;
+        tg.UnGetTemp(list,current_procinfo.save_regs_ref);
+      end;
 
 
     procedure tcgx86.g_save_all_registers(list : taasmoutput);
@@ -1516,7 +1557,11 @@ unit cgx86;
 end.
 {
   $Log$
-  Revision 1.60  2003-09-05 17:41:13  florian
+  Revision 1.61  2003-09-07 22:09:35  peter
+    * preparations for different default calling conventions
+    * various RA fixes
+
+  Revision 1.60  2003/09/05 17:41:13  florian
     * merged Wiktor's Watcom patches in 1.1
 
   Revision 1.59  2003/09/03 15:55:02  peter

+ 5 - 5
compiler/x86/cpubase.pas

@@ -185,10 +185,6 @@ uses
 {$endif x86_64}
       );
 
-      { registers which may be destroyed by calls }
-      VOLATILE_INTREGISTERS = [first_int_supreg..last_int_supreg]-[RS_EBP,RS_ESP];
-      VOLATILE_FPUREGISTERS = [first_fpu_supreg..last_fpu_supreg];
-
    type
       totherregisterset = set of tregisterindex;
 
@@ -563,7 +559,11 @@ implementation
 end.
 {
   $Log$
-  Revision 1.16  2003-09-04 21:07:03  florian
+  Revision 1.17  2003-09-07 22:09:35  peter
+    * preparations for different default calling conventions
+    * various RA fixes
+
+  Revision 1.16  2003/09/04 21:07:03  florian
     * ARM compiler compiles again
 
   Revision 1.15  2003/09/03 15:55:02  peter