Jelajahi Sumber

+ copying of open array value parameters to the heap implemented

florian 22 tahun lalu
induk
melakukan
f72431af31
1 mengubah file dengan 73 tambahan dan 126 penghapusan
  1. 73 126
      compiler/powerpc/cgcpu.pas

+ 73 - 126
compiler/powerpc/cgcpu.pas

@@ -42,7 +42,6 @@ unit cgcpu;
         procedure done_register_allocators;override;
 
         function  getintregister(list:Taasmoutput;size:Tcgsize):Tregister;override;
-        function  getaddressregister(list:Taasmoutput):Tregister;
         function  getfpuregister(list:Taasmoutput;size:Tcgsize):Tregister;override;
         function  getmmregister(list:Taasmoutput;size:Tcgsize):Tregister;override;
         procedure getexplicitregister(list:Taasmoutput;r:Tregister);override;
@@ -95,7 +94,9 @@ unit cgcpu;
 
         procedure g_flags2reg(list: taasmoutput; size: TCgSize; const f: TResFlags; reg: TRegister); override;
 
-        procedure g_copyvaluepara_openarray(list : taasmoutput;const ref, lenref:treference;elesize:integer);override;
+        procedure g_copyvaluepara_openarray(list : taasmoutput;const ref, lenref:treference;elesize:aword);override;
+        procedure g_releasevaluepara_openarray(list : taasmoutput;const ref:treference);override;
+
         procedure g_stackframe_entry(list : taasmoutput;localsize : longint);override;
         procedure g_return_from_proc(list : taasmoutput;parasize : aword); override;
         procedure g_restore_frame_pointer(list : taasmoutput);override;
@@ -173,7 +174,7 @@ const
     uses
        globtype,globals,verbose,systems,cutils,
        symconst,symdef,symsym,
-       rgobj,tgobj,cpupi,procinfo;
+       rgobj,tgobj,cpupi,procinfo,paramgr;
 
 
     procedure tcgppc.init_register_allocators;
@@ -207,12 +208,6 @@ const
       end;
 
 
-    function tcgppc.getaddressregister(list:Taasmoutput):Tregister;
-      begin
-        result:=rgint.getregister(list,R_SUBWHOLE);
-      end;
-
-
     function tcgppc.getfpuregister(list:Taasmoutput;size:Tcgsize):Tregister;
       begin
         result:=rgfpu.getregister(list,R_SUBWHOLE);
@@ -1992,131 +1987,80 @@ const
          tg.ungetiftemp(list,source);
       end;
 
-    procedure tcgppc.g_copyvaluepara_openarray(list : taasmoutput;const ref, lenref:treference;elesize:integer);
+
+    procedure tcgppc.g_copyvaluepara_openarray(list : taasmoutput;const ref, lenref:treference;elesize:aword);
       var
-        power,len  : longint;
-{$ifndef __NOWINPECOFF__}
-        again,ok : tasmlabel;
-{$endif}
-//        r,r2,rsp:Tregister;
+        sizereg,sourcereg : tregister;
+        paraloc1,paraloc2,paraloc3 : tparalocation;
       begin
-         {$warning !!!! FIX ME !!!!}
-         internalerror(200305231);
-(* !!!!
-        lenref:=ref;
-        inc(lenref.offset,4);
-        { get stack space }
-        r.enum:=R_INTREGISTER;
-        r.number:=NR_EDI;
-        rsp.enum:=R_INTREGISTER;
-        rsp.number:=NR_ESP;
-        r2.enum:=R_INTREGISTER;
-        rg.getexplicitregisterint(list,NR_EDI);
-        list.concat(Taicpu.op_ref_reg(A_MOV,S_L,lenref,r));
-        list.concat(Taicpu.op_reg(A_INC,S_L,r));
-        if (elesize<>1) then
-         begin
-           if ispowerof2(elesize, power) then
-             list.concat(Taicpu.op_const_reg(A_SHL,S_L,power,r))
-           else
-             list.concat(Taicpu.op_const_reg(A_IMUL,S_L,elesize,r));
-         end;
-{$ifndef __NOWINPECOFF__}
-        { windows guards only a few pages for stack growing, }
-        { so we have to access every page first              }
-        if target_info.system=system_i386_win32 then
-          begin
-             objectlibrary.getlabel(again);
-             objectlibrary.getlabel(ok);
-             a_label(list,again);
-             list.concat(Taicpu.op_const_reg(A_CMP,S_L,winstackpagesize,r));
-             a_jmp_cond(list,OC_B,ok);
-             list.concat(Taicpu.op_const_reg(A_SUB,S_L,winstackpagesize-4,rsp));
-             r2.number:=NR_EAX;
-             list.concat(Taicpu.op_reg(A_PUSH,S_L,r));
-             list.concat(Taicpu.op_const_reg(A_SUB,S_L,winstackpagesize,r));
-             a_jmp_always(list,again);
-
-             a_label(list,ok);
-             list.concat(Taicpu.op_reg_reg(A_SUB,S_L,r,rsp));
-             rgint.ungetregister(list,r);
-             { now reload EDI }
-             rg.getexplicitregisterint(list,NR_EDI);
-             list.concat(Taicpu.op_ref_reg(A_MOV,S_L,lenref,r));
-             list.concat(Taicpu.op_reg(A_INC,S_L,r));
-
-             if (elesize<>1) then
-              begin
-                if ispowerof2(elesize, power) then
-                  list.concat(Taicpu.op_const_reg(A_SHL,S_L,power,r))
-                else
-                  list.concat(Taicpu.op_const_reg(A_IMUL,S_L,elesize,r));
-              end;
-          end
-        else
-{$endif __NOWINPECOFF__}
-          list.concat(Taicpu.op_reg_reg(A_SUB,S_L,r,rsp));
-        { align stack on 4 bytes }
-        list.concat(Taicpu.op_const_reg(A_AND,S_L,$fffffff4,rsp));
+        { because ppc abi doesn't support dynamic stack allocation properly
+          open array value parameters are copied onto the heap
+        }
+        { allocate two registers for len and source }
+        sizereg:=getintregister(list,OS_INT);
+        sourcereg:=getintregister(list,OS_INT);
+        { calculate necessary memory }
+        a_load_ref_reg(list,OS_INT,OS_INT,lenref,sizereg);
+        a_op_const_reg_reg(list,OP_MUL,OS_INT,elesize,sizereg,sizereg);
+        { load source }
+        a_load_ref_reg(list,OS_ADDR,OS_ADDR,ref,sourcereg);
+
+        { do getmem call }
+        paraloc1:=paramanager.getintparaloc(pocall_default,1);
+        paraloc2:=paramanager.getintparaloc(pocall_default,2);
+        paramanager.allocparaloc(list,paraloc2);
+        a_param_reg(list,OS_INT,sizereg,paraloc2);
+        paramanager.allocparaloc(list,paraloc1);
+        a_paramaddr_ref(list,ref,paraloc1);
+        paramanager.freeparaloc(list,paraloc2);
+        paramanager.freeparaloc(list,paraloc1);
+        allocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
+        a_call_name(list,'FPC_GETMEM');
+        deallocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
+
+        { do move call }
+        paraloc1:=paramanager.getintparaloc(pocall_default,1);
+        paraloc2:=paramanager.getintparaloc(pocall_default,2);
+        paraloc3:=paramanager.getintparaloc(pocall_default,3);
+        { load size }
+        paramanager.allocparaloc(list,paraloc3);
+        a_param_reg(list,OS_INT,sizereg,paraloc3);
         { load destination }
-        a_load_reg_reg(list,OS_INT,OS_INT,rsp,r);
-
-        { don't destroy the registers! }
-        r2.number:=NR_ECX;
-        list.concat(Taicpu.op_reg(A_PUSH,S_L,r2));
-        r2.number:=NR_ESI;
-        list.concat(Taicpu.op_reg(A_PUSH,S_L,r2));
-
-        { load count }
-        r2.number:=NR_ECX;
-        a_load_ref_reg(list,OS_INT,lenref,r2);
-
+        paramanager.allocparaloc(list,paraloc2);
+        a_param_ref(list,OS_ADDR,ref,paraloc2);
         { load source }
-        r2.number:=NR_ESI;
-        a_load_ref_reg(list,OS_INT,ref,r2);
-
-        { scheduled .... }
-        r2.number:=NR_ECX;
-        list.concat(Taicpu.op_reg(A_INC,S_L,r2));
+        paramanager.allocparaloc(list,paraloc1);
+        a_param_reg(list,OS_ADDR,sourcereg,paraloc1);
+        paramanager.freeparaloc(list,paraloc3);
+        paramanager.freeparaloc(list,paraloc2);
+        paramanager.freeparaloc(list,paraloc1);
+        allocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
+        a_call_name(list,'FPC_MOVE');
+        deallocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
+
+        { release used registers }
+        ungetregister(list,sizereg);
+        ungetregister(list,sourcereg);
+      end;
 
-        { calculate size }
-        len:=elesize;
-        opsize:=S_B;
-        if (len and 3)=0 then
-         begin
-           opsize:=S_L;
-           len:=len shr 2;
-         end
-        else
-         if (len and 1)=0 then
-          begin
-            opsize:=S_W;
-            len:=len shr 1;
-          end;
 
-        if ispowerof2(len, power) then
-          list.concat(Taicpu.op_const_reg(A_SHL,S_L,power,r2))
-        else
-          list.concat(Taicpu.op_const_reg(A_IMUL,S_L,len,r2));
-        list.concat(Taicpu.op_none(A_REP,S_NO));
-        case opsize of
-          S_B : list.concat(Taicpu.Op_none(A_MOVSB,S_NO));
-          S_W : list.concat(Taicpu.Op_none(A_MOVSW,S_NO));
-          S_L : list.concat(Taicpu.Op_none(A_MOVSD,S_NO));
-        end;
-        rgint.ungetregister(list,r);
-        r2.number:=NR_ESI;
-        list.concat(Taicpu.op_reg(A_POP,S_L,r2));
-        r2.number:=NR_ECX;
-        list.concat(Taicpu.op_reg(A_POP,S_L,r2));
-
-        { patch the new address }
-        a_load_reg_ref(list,OS_INT,rsp,ref);
-!!!! *)
+    procedure tcgppc.g_releasevaluepara_openarray(list : taasmoutput;const ref:treference);
+      var
+        paraloc : tparalocation;
+      begin
+        { do move call }
+        paraloc:=paramanager.getintparaloc(pocall_default,1);
+        { load source }
+        paramanager.allocparaloc(list,paraloc);
+        a_param_ref(list,OS_ADDR,ref,paraloc);
+        paramanager.freeparaloc(list,paraloc);
+        allocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
+        a_call_name(list,'FPC_FREEMEM');
+        deallocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
       end;
 
-    procedure tcgppc.g_overflowcheck(list: taasmoutput; const l: tlocation; def: tdef);
 
+    procedure tcgppc.g_overflowcheck(list: taasmoutput; const l: tlocation; def: tdef);
       var
          hl : tasmlabel;
       begin
@@ -2499,7 +2443,10 @@ begin
 end.
 {
   $Log$
-  Revision 1.135  2003-11-02 15:20:06  jonas
+  Revision 1.136  2003-11-02 17:19:33  florian
+    + copying of open array value parameters to the heap implemented
+
+  Revision 1.135  2003/11/02 15:20:06  jonas
     * fixed releasing of references (ppc also has a base and an index, not
       just a base)