2
0
Эх сурвалжийг харах

* factored out common code from get_funcretloc()
* set tcgpara.def for the function return location (field introduced for and
already used by the JVM code generator, required for future hlcg
functionality)

git-svn-id: trunk@21691 -

Jonas Maebe 13 жил өмнө
parent
commit
587244c088

+ 2 - 32
compiler/arm/cpupara.pas

@@ -587,38 +587,8 @@ unit cpupara;
         paraloc : pcgparalocation;
         paraloc : pcgparalocation;
         retcgsize  : tcgsize;
         retcgsize  : tcgsize;
       begin
       begin
-        result.init;
-        result.alignment:=get_para_align(p.proccalloption);
-        { void has no location }
-        if is_void(def) then
-          begin
-            paraloc:=result.add_location;
-            result.size:=OS_NO;
-            result.intsize:=0;
-            paraloc^.size:=OS_NO;
-            paraloc^.loc:=LOC_VOID;
-            exit;
-          end;
-        { Constructors return self instead of a boolean }
-        if (p.proctypeoption=potype_constructor) then
-          begin
-            retcgsize:=OS_ADDR;
-            result.intsize:=sizeof(pint);
-          end
-        else
-          begin
-            retcgsize:=def_cgsize(def);
-            result.intsize:=def.size;
-          end;
-        result.size:=retcgsize;
-        { Return is passed as var parameter }
-        if ret_in_param(def,p.proccalloption) then
-          begin
-            paraloc:=result.add_location;
-            paraloc^.loc:=LOC_REFERENCE;
-            paraloc^.size:=retcgsize;
-            exit;
-          end;
+         if set_common_funcretloc_info(p,def,retcgsize,result) then
+           exit;
 
 
         paraloc:=result.add_location;
         paraloc:=result.add_location;
         { Return in FPU register? }
         { Return in FPU register? }

+ 2 - 32
compiler/avr/cpupara.pas

@@ -415,38 +415,8 @@ unit cpupara;
         retcgsize : tcgsize;
         retcgsize : tcgsize;
         paraloc : pcgparalocation;
         paraloc : pcgparalocation;
       begin
       begin
-        result.init;
-        result.alignment:=get_para_align(p.proccalloption);
-        { void has no location }
-        if is_void(def) then
-          begin
-            paraloc:=result.add_location;
-            result.size:=OS_NO;
-            result.intsize:=0;
-            paraloc^.size:=OS_NO;
-            paraloc^.loc:=LOC_VOID;
-            exit;
-          end;
-        { Constructors return self instead of a boolean }
-        if (p.proctypeoption=potype_constructor) then
-          begin
-            retcgsize:=OS_ADDR;
-            result.intsize:=sizeof(pint);
-          end
-        else
-          begin
-            retcgsize:=def_cgsize(def);
-            result.intsize:=def.size;
-          end;
-        result.size:=retcgsize;
-        { Return is passed as var parameter }
-        if ret_in_param(def,p.proccalloption) then
-          begin
-            paraloc:=result.add_location;
-            paraloc^.loc:=LOC_REFERENCE;
-            paraloc^.size:=retcgsize;
-            exit;
-          end;
+         if set_common_funcretloc_info(p,def,retcgsize,result) then
+           exit;
 
 
         paraloc:=result.add_location;
         paraloc:=result.add_location;
         { Return in FPU register? }
         { Return in FPU register? }

+ 15 - 41
compiler/i386/cpupara.pas

@@ -321,18 +321,6 @@ unit cpupara;
         paraloc : pcgparalocation;
         paraloc : pcgparalocation;
         sym: tfieldvarsym;
         sym: tfieldvarsym;
       begin
       begin
-        result.init;
-        result.alignment:=get_para_align(p.proccalloption);
-        { void has no location }
-        if is_void(def) then
-          begin
-            paraloc:=result.add_location;
-            result.size:=OS_NO;
-            result.intsize:=0;
-            paraloc^.size:=OS_NO;
-            paraloc^.loc:=LOC_VOID;
-            exit;
-          end;
         { on darwin/i386, if a record has only one field and that field is a
         { on darwin/i386, if a record has only one field and that field is a
           single or double, it has to be returned like a single/double }
           single or double, it has to be returned like a single/double }
         if (target_info.system in [system_i386_darwin,system_i386_iphonesim]) and
         if (target_info.system in [system_i386_darwin,system_i386_iphonesim]) and
@@ -342,37 +330,23 @@ unit cpupara;
            (sym.vardef.typ=floatdef) and
            (sym.vardef.typ=floatdef) and
            (tfloatdef(sym.vardef).floattype in [s32real,s64real]) then
            (tfloatdef(sym.vardef).floattype in [s32real,s64real]) then
           def:=sym.vardef;
           def:=sym.vardef;
-        { Constructors return self instead of a boolean }
-        if (p.proctypeoption=potype_constructor) then
-          begin
-            retcgsize:=OS_ADDR;
-            result.intsize:=sizeof(pint);
-          end
-        else
-          begin
-            retcgsize:=def_cgsize(def);
-            { darwin/x86 requires that results < sizeof(aint) are sign/ }
-            { zero extended to sizeof(aint)                             }
-            if (target_info.system in [system_i386_darwin,system_i386_iphonesim]) and
-               (side=calleeside) and
-               (result.intsize>0) and
-               (result.intsize<sizeof(aint)) then
-              begin
-                result.intsize:=sizeof(aint);
-                retcgsize:=OS_SINT;
-              end
-            else
-              result.intsize:=def.size;
-          end;
-        result.size:=retcgsize;
-        { Return is passed as var parameter }
-        if ret_in_param(def,p.proccalloption) then
+
+        if set_common_funcretloc_info(p,def,retcgsize,result) then
+          exit;
+
+        { darwin/x86 requires that results < sizeof(aint) are sign/zero
+          extended to sizeof(aint) }
+        if (target_info.system in [system_i386_darwin,system_i386_iphonesim]) and
+           (side=calleeside) and
+           (result.intsize>0) and
+           (result.intsize<sizeof(aint)) then
           begin
           begin
-            paraloc:=result.add_location;
-            paraloc^.loc:=LOC_REFERENCE;
-            paraloc^.size:=retcgsize;
-            exit;
+            result.def:=sinttype;
+            result.intsize:=sizeof(aint);
+            retcgsize:=OS_SINT;
+            result.size:=retcgsize;
           end;
           end;
+
         { Return in FPU register? }
         { Return in FPU register? }
         if def.typ=floatdef then
         if def.typ=floatdef then
           begin
           begin

+ 2 - 32
compiler/m68k/cpupara.pas

@@ -196,38 +196,8 @@ unit cpupara;
         paraloc : pcgparalocation;
         paraloc : pcgparalocation;
         retcgsize  : tcgsize;
         retcgsize  : tcgsize;
       begin
       begin
-        result.init;
-        result.alignment:=get_para_align(p.proccalloption);
-        { void has no location }
-        if is_void(def) then
-          begin
-            paraloc:=result.add_location;
-            result.size:=OS_NO;
-            result.intsize:=0;
-            paraloc^.size:=OS_NO;
-            paraloc^.loc:=LOC_VOID;
-            exit;
-          end;
-        { Constructors return self instead of a boolean }
-        if (p.proctypeoption=potype_constructor) then
-          begin
-            retcgsize:=OS_ADDR;
-            result.intsize:=sizeof(pint);
-          end
-        else
-          begin
-            retcgsize:=def_cgsize(def);
-            result.intsize:=def.size;
-          end;
-        result.size:=retcgsize;
-        { Return is passed as var parameter }
-        if ret_in_param(def,p.proccalloption) then
-          begin
-            paraloc:=result.add_location;
-            paraloc^.loc:=LOC_REFERENCE;
-            paraloc^.size:=retcgsize;
-            exit;
-          end;
+        if set_common_funcretloc_info(p,def,retcgsize,result) then
+          exit;
 
 
         paraloc:=result.add_location;
         paraloc:=result.add_location;
         { Return in FPU register? }
         { Return in FPU register? }

+ 27 - 46
compiler/mips/cpupara.pas

@@ -192,56 +192,37 @@ implementation
         paraloc : pcgparalocation;
         paraloc : pcgparalocation;
         retcgsize  : tcgsize;
         retcgsize  : tcgsize;
       begin
       begin
-        result.init;
-        result.alignment:=get_para_align(p.proccalloption);
-        { void has no location }
-        if is_void(def) then
+        if set_common_funcretloc_info(p,def,retcgsize,result) then
           begin
           begin
-            paraloc:=result.add_location;
-            result.size:=OS_NO;
-            result.intsize:=0;
-            paraloc^.size:=OS_NO;
-            paraloc^.loc:=LOC_VOID;
-            exit;
-          end;
-        { Constructors return self instead of a boolean }
-        if (p.proctypeoption=potype_constructor) then
-          begin
-            retcgsize:=OS_ADDR;
-            result.intsize:=sizeof(pint);
-          end
-        else
-          begin
-            retcgsize:=def_cgsize(def);
-            result.intsize:=def.size;
-          end;
-        result.size:=retcgsize;
-        { Return is passed as var parameter,
-          in this case we use the first register R4 for it }
-        if ret_in_param(def,p.proccalloption) then
-          begin
-            if intparareg=0 then
-              inc(intparareg);
-            if side=calleeside then
+            { Return is passed as var parameter,
+              in this case we use the first register R4 for it }
+            if ret_in_param(def,p.proccalloption) then
               begin
               begin
-                paraloc:=result.add_location;
-                paraloc^.loc:=LOC_REFERENCE;
-                paraloc^.reference.index:=NR_STACK_POINTER_REG;
-                { return is at offset zero }
-                paraloc^.reference.offset:=0;
-                paraloc^.size:=retcgsize;
-                { Reserve first register for ret_in_param }
-                if assigned(current_procinfo) then
+                if intparareg=0 then
+                  inc(intparareg);
+                if side=calleeside then
+                  begin
+                    result.reset;
+                    paraloc:=result.add_location;
+                    paraloc^.loc:=LOC_REFERENCE;
+                    paraloc^.reference.index:=NR_STACK_POINTER_REG;
+                    { return is at offset zero }
+                    paraloc^.reference.offset:=0;
+                    paraloc^.size:=retcgsize;
+                    { Reserve first register for ret_in_param }
+                    if assigned(current_procinfo) then
+                      begin
+                        TMIPSProcInfo(current_procinfo).register_used[0]:=true;
+                        TMIPSProcInfo(current_procinfo).register_size[0]:=retcgsize;
+                        TMIPSProcInfo(current_procinfo).register_name[0]:='ret_in_param_result';
+                        TMIPSProcInfo(current_procinfo).register_offset[0]:=0;
+                      end;
+                  end
+                else
                   begin
                   begin
-                    TMIPSProcInfo(current_procinfo).register_used[0]:=true;
-                    TMIPSProcInfo(current_procinfo).register_size[0]:=retcgsize;
-                    TMIPSProcInfo(current_procinfo).register_name[0]:='ret_in_param_result';
-                    TMIPSProcInfo(current_procinfo).register_offset[0]:=0;
+                    getIntParaLoc(p.proccalloption,1,result);
                   end;
                   end;
-              end
-            else
-              begin
-                getIntParaLoc(p.proccalloption,1,result);
+                result.def:=getpointerdef(def);
               end;
               end;
             exit;
             exit;
           end;
           end;

+ 52 - 0
compiler/paramgr.pas

@@ -140,6 +140,10 @@ unit paramgr;
           function use_fixed_stack: boolean;
           function use_fixed_stack: boolean;
           { whether stack pointer can be changed in the middle of procedure }
           { whether stack pointer can be changed in the middle of procedure }
           function use_stackalloc: boolean;
           function use_stackalloc: boolean;
+         strict protected
+          { common part of get_funcretloc; returns true if retloc is completely
+            initialized afterwards }
+          function set_common_funcretloc_info(p : tabstractprocdef; def: tdef; out retcgsize: tcgsize; out retloc: tcgpara): boolean;
        end;
        end;
 
 
 
 
@@ -492,6 +496,54 @@ implementation
         result:=not use_fixed_stack;
         result:=not use_fixed_stack;
       end;
       end;
 
 
+
+    function tparamanager.set_common_funcretloc_info(p : tabstractprocdef; def: tdef; out retcgsize: tcgsize; out retloc: tcgpara): boolean;
+      var
+        paraloc : pcgparalocation;
+      begin
+        result:=true;
+        retloc.init;
+        retloc.def:=def;
+        retloc.alignment:=get_para_align(p.proccalloption);
+        { void has no location }
+        if is_void(def) then
+          begin
+            paraloc:=retloc.add_location;
+            retloc.size:=OS_NO;
+            retcgsize:=OS_NO;
+            retloc.intsize:=0;
+            paraloc^.size:=OS_NO;
+            paraloc^.loc:=LOC_VOID;
+            exit;
+          end;
+        { Constructors return self instead of a boolean }
+        if p.proctypeoption=potype_constructor then
+          begin
+            if is_implicit_pointer_object_type(tdef(p.owner.defowner)) then
+              retloc.def:=tdef(p.owner.defowner)
+            else
+              retloc.def:=getpointerdef(tdef(p.owner.defowner));
+            retcgsize:=OS_ADDR;
+            retloc.intsize:=sizeof(pint);
+          end
+        else
+          begin
+            retcgsize:=def_cgsize(def);
+            retloc.intsize:=def.size;
+          end;
+        retloc.size:=retcgsize;
+        { Return is passed as var parameter }
+        if ret_in_param(def,p.proccalloption) then
+          begin
+            retloc.def:=getpointerdef(def);
+            paraloc:=retloc.add_location;
+            paraloc^.loc:=LOC_REFERENCE;
+            paraloc^.size:=retcgsize;
+            exit;
+          end;
+        result:=false;
+      end;
+
 initialization
 initialization
   ;
   ;
 finalization
 finalization

+ 2 - 32
compiler/powerpc/cpupara.pas

@@ -256,38 +256,8 @@ unit cpupara;
         paraloc : pcgparalocation;
         paraloc : pcgparalocation;
         retcgsize  : tcgsize;
         retcgsize  : tcgsize;
       begin
       begin
-        result.init;
-        result.alignment:=get_para_align(p.proccalloption);
-        { void has no location }
-        if is_void(def) then
-          begin
-            paraloc:=result.add_location;
-            result.size:=OS_NO;
-            result.intsize:=0;
-            paraloc^.size:=OS_NO;
-            paraloc^.loc:=LOC_VOID;
-            exit;
-          end;
-        { Constructors return self instead of a boolean }
-        if (p.proctypeoption=potype_constructor) then
-          begin
-            retcgsize:=OS_ADDR;
-            result.intsize:=sizeof(pint);
-          end
-        else
-          begin
-            retcgsize:=def_cgsize(def);
-            result.intsize:=def.size;
-          end;
-        result.size:=retcgsize;
-        { Return is passed as var parameter }
-        if ret_in_param(def,p.proccalloption) then
-          begin
-            paraloc:=result.add_location;
-            paraloc^.loc:=LOC_REFERENCE;
-            paraloc^.size:=retcgsize;
-            exit;
-          end;
+        if set_common_funcretloc_info(p,def,retcgsize,result) then
+          exit;
 
 
         paraloc:=result.add_location;
         paraloc:=result.add_location;
         { Return in FPU register? }
         { Return in FPU register? }

+ 2 - 32
compiler/powerpc64/cpupara.pas

@@ -215,38 +215,8 @@ var
   paraloc : pcgparalocation;
   paraloc : pcgparalocation;
   retcgsize  : tcgsize;
   retcgsize  : tcgsize;
 begin
 begin
-  result.init;
-  result.alignment:=get_para_align(p.proccalloption);
-  { void has no location }
-  if is_void(def) then
-    begin
-      paraloc:=result.add_location;
-      result.size:=OS_NO;
-      result.intsize:=0;
-      paraloc^.size:=OS_NO;
-      paraloc^.loc:=LOC_VOID;
-      exit;
-    end;
-  { Constructors return self instead of a boolean }
-  if (p.proctypeoption=potype_constructor) then
-    begin
-      retcgsize:=OS_ADDR;
-      result.intsize:=sizeof(pint);
-    end
-  else
-    begin
-      retcgsize:=def_cgsize(def);
-      result.intsize:=def.size;
-    end;
-  result.size:=retcgsize;
-  { Return is passed as var parameter }
-  if ret_in_param(def,p.proccalloption) then
-    begin
-      paraloc:=result.add_location;
-      paraloc^.loc:=LOC_REFERENCE;
-      paraloc^.size:=retcgsize;
-      exit;
-    end;
+  if set_common_funcretloc_info(p,def,retcgsize,result) then
+    exit;
 
 
   paraloc:=result.add_location;
   paraloc:=result.add_location;
   { Return in FPU register? }
   { Return in FPU register? }

+ 2 - 32
compiler/sparc/cpupara.pas

@@ -150,38 +150,8 @@ implementation
         paraloc : pcgparalocation;
         paraloc : pcgparalocation;
         retcgsize  : tcgsize;
         retcgsize  : tcgsize;
       begin
       begin
-        result.init;
-        result.alignment:=get_para_align(p.proccalloption);
-        { void has no location }
-        if is_void(def) then
-          begin
-            paraloc:=result.add_location;
-            result.size:=OS_NO;
-            result.intsize:=0;
-            paraloc^.size:=OS_NO;
-            paraloc^.loc:=LOC_VOID;
-            exit;
-          end;
-        { Constructors return self instead of a boolean }
-        if (p.proctypeoption=potype_constructor) then
-          begin
-            retcgsize:=OS_ADDR;
-            result.intsize:=sizeof(pint);
-          end
-        else
-          begin
-            retcgsize:=def_cgsize(def);
-            result.intsize:=def.size;
-          end;
-        result.size:=retcgsize;
-        { Return is passed as var parameter }
-        if ret_in_param(def,p.proccalloption) then
-          begin
-            paraloc:=result.add_location;
-            paraloc^.loc:=LOC_REFERENCE;
-            paraloc^.size:=retcgsize;
-            exit;
-          end;
+        if set_common_funcretloc_info(p,def,retcgsize,result) then
+          exit;
 
 
         paraloc:=result.add_location;
         paraloc:=result.add_location;
         { Return in FPU register? }
         { Return in FPU register? }

+ 11 - 39
compiler/x86_64/cpupara.pas

@@ -809,46 +809,18 @@ unit cpupara;
         retcgsize : tcgsize;
         retcgsize : tcgsize;
         paraloc : pcgparalocation;
         paraloc : pcgparalocation;
       begin
       begin
-        result.init;
-        result.alignment:=get_para_align(p.proccalloption);
-        { void has no location }
-        if is_void(def) then
-          begin
-            paraloc:=result.add_location;
-            result.size:=OS_NO;
-            result.intsize:=0;
-            paraloc^.size:=OS_NO;
-            paraloc^.loc:=LOC_VOID;
-            exit;
-          end;
-        { Constructors return self instead of a boolean }
-        if (p.proctypeoption=potype_constructor) then
-          begin
-            retcgsize:=OS_ADDR;
-            result.intsize:=sizeof(pint);
-          end
-        else
-          begin
-            retcgsize:=def_cgsize(def);
-            { integer sizes < 32 bit have to be sign/zero extended to 32 bit on
-              the callee side (caller can expect those bits are valid) }
-            if (side=calleeside) and
-               (retcgsize in [OS_8,OS_S8,OS_16,OS_S16]) then
-              begin
-                retcgsize:=OS_S32;
-                result.intsize:=4;
-              end
-            else
-              result.intsize:=def.size;
-          end;
-        result.size:=retcgsize;
-        { Return is passed as var parameter }
-        if ret_in_param(def,p.proccalloption) then
+        if set_common_funcretloc_info(p,def,retcgsize,result) then
+          exit;
+
+        { integer sizes < 32 bit have to be sign/zero extended to 32 bit on
+          the callee side (caller can expect those bits are valid) }
+        if (side=calleeside) and
+           (retcgsize in [OS_8,OS_S8,OS_16,OS_S16]) then
           begin
           begin
-            paraloc:=result.add_location;
-            paraloc^.loc:=LOC_REFERENCE;
-            paraloc^.size:=retcgsize;
-            exit;
+            retcgsize:=OS_S32;
+            result.def:=s32inttype;
+            result.intsize:=4;
+            result.size:=retcgsize;
           end;
           end;
 
 
         { Return in FPU register? -> don't use classify_argument(), because
         { Return in FPU register? -> don't use classify_argument(), because