Răsfoiți Sursa

* varargs calculation fixed, it's now the same as the other
targets

peter 21 ani în urmă
părinte
comite
b6ed8c482b
1 a modificat fișierele cu 42 adăugiri și 61 ștergeri
  1. 42 61
      compiler/i386/cpupara.pas

+ 42 - 61
compiler/i386/cpupara.pas

@@ -53,8 +53,10 @@ unit cpupara;
           function create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargspara):longint;override;
        private
           procedure create_funcret_paraloc_info(p : tabstractprocdef; side: tcallercallee);
-          function create_stdcall_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;
-          function create_register_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;
+          procedure create_stdcall_paraloc_info(p : tabstractprocdef; side: tcallercallee;firstpara:tparaitem;
+                                                var parasize:longint);
+          procedure create_register_paraloc_info(p : tabstractprocdef; side: tcallercallee;firstpara:tparaitem;
+                                                 var parareg,parasize:longint);
        end;
 
   implementation
@@ -261,53 +263,15 @@ unit cpupara;
       end;
 
 
-    function ti386paramanager.create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargspara):longint;
+    procedure ti386paramanager.create_stdcall_paraloc_info(p : tabstractprocdef; side: tcallercallee;firstpara:tparaitem;
+                                                           var parasize:longint);
       var
         hp : tparaitem;
         paraloc : tparalocation;
         l,
         varalign,
-        paraalign,
-        parasize : longint;
+        paraalign : longint;
       begin
-        parasize:=0;
-        paraalign:=get_para_align(p.proccalloption);
-        { Retrieve last know info from normal parameters }
-        hp:=tparaitem(p.para.last);
-        if assigned(hp) then
-          parasize:=hp.paraloc[callerside].reference.offset;
-        { Assign varargs }
-        hp:=tparaitem(varargspara.first);
-        while assigned(hp) do
-          begin
-            paraloc.size:=def_cgsize(hp.paratype.def);
-            paraloc.loc:=LOC_REFERENCE;
-            paraloc.lochigh:=LOC_INVALID;
-            paraloc.alignment:=paraalign;
-            paraloc.reference.index:=NR_STACK_POINTER_REG;
-            l:=push_size(hp.paratyp,hp.paratype.def,p.proccalloption);
-            varalign:=size_2_align(l);
-            paraloc.reference.offset:=parasize;
-            varalign:=used_align(varalign,paraalign,paraalign);
-            parasize:=align(parasize+l,varalign);
-            hp.paraloc[callerside]:=paraloc;
-            hp:=tparaitem(hp.next);
-          end;
-        { We need to return the size allocated }
-        result:=parasize;
-      end;
-
-
-    function ti386paramanager.create_stdcall_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;
-      var
-        hp : tparaitem;
-        paraloc : tparalocation;
-        l,
-        varalign,
-        paraalign,
-        parasize : longint;
-      begin
-        parasize:=0;
         paraalign:=get_para_align(p.proccalloption);
         { we push Flags and CS as long
           to cope with the IRETD
@@ -323,7 +287,7 @@ unit cpupara;
           That means the for pushes the para with the
           highest offset (see para3) needs to be pushed first
         }
-        hp:=tparaitem(p.para.first);
+        hp:=firstpara;
         while assigned(hp) do
           begin
             if hp.paratyp in [vs_var,vs_out] then
@@ -373,28 +337,24 @@ unit cpupara;
                   end;
                end;
           end;
-        { We need to return the size allocated }
-        result:=parasize;
       end;
 
 
-    function ti386paramanager.create_register_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;
+    procedure ti386paramanager.create_register_paraloc_info(p : tabstractprocdef; side: tcallercallee;firstpara:tparaitem;
+                                                            var parareg,parasize:longint);
       var
         hp : tparaitem;
         paraloc : tparalocation;
         subreg : tsubregister;
         pushaddr,
         is_64bit : boolean;
-        l,parareg,
+        l,
         varalign,
-        paraalign,
-        parasize : longint;
+        paraalign : longint;
       begin
-        parareg:=0;
-        parasize:=0;
         paraalign:=get_para_align(p.proccalloption);
         { Register parameters are assigned from left to right }
-        hp:=tparaitem(p.para.first);
+        hp:=firstpara;
         while assigned(hp) do
           begin
             pushaddr:=push_addr_param(hp.paratyp,hp.paratype.def,p.proccalloption);
@@ -464,40 +424,61 @@ unit cpupara;
               end;
             hp:=tparaitem(hp.next);
           end;
-        { We need to return the size allocated }
-        result:=parasize;
       end;
 
 
     function ti386paramanager.create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;
+      var
+        parasize,
+        parareg : longint;
       begin
-        result:=0;
+        parasize:=0;
+        parareg:=0;
         case p.proccalloption of
           pocall_register :
-            result:=create_register_paraloc_info(p,side);
+            create_register_paraloc_info(p,side,tparaitem(p.para.first),parareg,parasize);
           pocall_inline,
           pocall_compilerproc,
           pocall_internproc :
             begin
               { Use default calling }
               if (pocall_default=pocall_register) then
-                result:=create_register_paraloc_info(p,side)
+                create_register_paraloc_info(p,side,tparaitem(p.para.first),parareg,parasize)
               else
-                result:=create_stdcall_paraloc_info(p,side);
+                create_stdcall_paraloc_info(p,side,tparaitem(p.para.first),parasize);
             end;
           else
-            result:=create_stdcall_paraloc_info(p,side);
+            create_stdcall_paraloc_info(p,side,tparaitem(p.para.first),parasize);
         end;
         create_funcret_paraloc_info(p,side);
+        result:=parasize;
+      end;
+
+
+    function ti386paramanager.create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargspara):longint;
+      var
+        parasize : longint;
+      begin
+        parasize:=0;
+        { calculate the registers for the normal parameters }
+        create_stdcall_paraloc_info(p,callerside,tparaitem(p.para.first),parasize);
+        { append the varargs }
+        create_stdcall_paraloc_info(p,callerside,tparaitem(varargspara.first),parasize);
+        result:=parasize;
       end;
 
 
+
 begin
    paramanager:=ti386paramanager.create;
 end.
 {
   $Log$
-  Revision 1.52  2004-06-20 08:55:31  florian
+  Revision 1.53  2004-07-09 23:09:02  peter
+    * varargs calculation fixed, it's now the same as the other
+      targets
+
+  Revision 1.52  2004/06/20 08:55:31  florian
     * logs truncated
 
   Revision 1.51  2004/06/16 20:07:10  florian