Parcourir la source

* function results can now also be regvars
- removed tprocinfo.return_offset, never use it again since it's invalid
if the result is a regvar

Jonas Maebe il y a 22 ans
Parent
commit
6f3e16298a

+ 6 - 7
compiler/cgbase.pas

@@ -78,8 +78,6 @@ unit cgbase;
              frame pointer from the outer procedure is stored.
           }
           framepointer_offset : longint;
-          {# result value offset in stack (functions only) }
-          return_offset : longint;
           {# firsttemp position }
           firsttemp_offset : longint;
 
@@ -347,7 +345,6 @@ implementation
         parent:=aparent;
         procdef:=nil;
         framepointer_offset:=0;
-        return_offset:=0;
         firsttemp_offset:=0;
         flags:=[];
         framepointer.enum:=R_INTREGISTER;
@@ -414,9 +411,6 @@ implementation
       var
         srsym : tvarsym;
       begin
-         { Retrieve function result offset }
-         if assigned(procdef.funcretsym) then
-           current_procinfo.return_offset:=tvarsym(procdef.funcretsym).adjusted_address;
       end;
 
 
@@ -579,7 +573,12 @@ implementation
 end.
 {
   $Log$
-  Revision 1.52  2003-05-26 21:17:17  peter
+  Revision 1.53  2003-06-02 21:42:05  jonas
+    * function results can now also be regvars
+    - removed tprocinfo.return_offset, never use it again since it's invalid
+      if the result is a regvar
+
+  Revision 1.52  2003/05/26 21:17:17  peter
     * procinlinenode removed
     * aktexit2label removed, fast exit removed
     + tcallnode.inlined_pass_2 added

+ 10 - 4
compiler/i386/popt386.pas

@@ -38,6 +38,7 @@ Implementation
 Uses
   globtype,systems,
   globals,cgbase,
+  symsym,symdef,
 {$ifdef finaldestdebug}
   cobjects,
 {$endif finaldestdebug}
@@ -76,7 +77,7 @@ begin
          ((Taicpu(hp2).opcode = A_LEAVE) or
           (Taicpu(hp2).opcode = A_RET)) and
          (Taicpu(p).oper[0].ref^.Base.enum = current_procinfo.FramePointer.enum) and
-         (Taicpu(p).oper[0].ref^.Offset >= current_procinfo.Return_Offset) and
+         (Taicpu(p).oper[0].ref^.Offset >= tvarsym(current_procinfo.procdef.funcretsym).adjusted_address) and
          (Taicpu(p).oper[0].ref^.Index.enum = R_NO) then
         begin
           asml.remove(p);
@@ -995,7 +996,7 @@ Begin
                                   (Taicpu(hp1).opcode = A_RET)) And
                                  (Taicpu(p).oper[1].typ = top_ref) And
                                  (Taicpu(p).oper[1].ref^.base.enum = current_procinfo.FramePointer.enum) And
-                                 (Taicpu(p).oper[1].ref^.offset >= current_procinfo.Return_Offset) And
+                                 (Taicpu(p).oper[1].ref^.offset >= tvarsym(current_procinfo.procdef.funcretsym).adjusted_address) And
                                  (Taicpu(p).oper[1].ref^.index.enum = R_NO) And
                                  (Taicpu(p).oper[0].typ = top_reg)
                                 Then
@@ -1565,7 +1566,7 @@ Begin
                       (Taicpu(hp2).opcode = A_RET)) And
                      (Taicpu(p).oper[0].ref^.Base.enum = current_procinfo.FramePointer.enum) And
                      (Taicpu(p).oper[0].ref^.Index.enum = R_NO) And
-                     (Taicpu(p).oper[0].ref^.Offset >= current_procinfo.Return_Offset) And
+                     (Taicpu(p).oper[0].ref^.Offset >= tvarsym(current_procinfo.procdef.funcretsym).adjusted_address) And
                      (hp1.typ = ait_instruction) And
                      (Taicpu(hp1).opcode = A_MOV) And
                      (Taicpu(hp1).opsize = S_B) And
@@ -2060,7 +2061,12 @@ End.
 
 {
   $Log$
-  Revision 1.44  2003-05-30 23:57:08  peter
+  Revision 1.45  2003-06-02 21:42:05  jonas
+    * function results can now also be regvars
+    - removed tprocinfo.return_offset, never use it again since it's invalid
+      if the result is a regvar
+
+  Revision 1.44  2003/05/30 23:57:08  peter
     * more sparc cleanup
     * accumulator removed, splitted in function_return_reg (called) and
       function_result_reg (caller)

+ 70 - 59
compiler/ncgutil.pas

@@ -1224,33 +1224,6 @@ implementation
       begin
         if not is_void(current_procdef.rettype.def) then
           begin
-             { for now the pointer to the result can't be a register }
-             if paramanager.ret_in_param(current_procdef.rettype.def,current_procdef.proccalloption) then
-               begin
-{$ifdef powerpc}
-                  { no stack space is allocated in this case -> can't save the result reg on the stack }
-                  if not(po_assembler in current_procdef.procoptions) then
-{$endif powerpc}
-                    begin
-                      paraloc:=paramanager.getfuncretparaloc(current_procdef);
-                      reference_reset_base(href,current_procinfo.framepointer,current_procinfo.return_offset);
-                      case paraloc.loc of
-                        LOC_CREGISTER,
-                        LOC_REGISTER:
-                          if not(paraloc.size in [OS_64,OS_S64]) then
-                            cg.a_load_reg_ref(list,paraloc.size,paraloc.register,href)
-                          else
-                            cg64.a_load64_reg_ref(list,paraloc.register64,href);
-                        LOC_CFPUREGISTER,
-                        LOC_FPUREGISTER:
-                          cg.a_load_reg_ref(list,paraloc.size,paraloc.register,href);
-                        LOC_CMMREGISTER,
-                        LOC_MMREGISTER:
-                          cg.a_loadmm_reg_ref(list,paraloc.register,href);
-                      end;
-                    end;
-               end;
-
              { initialize return value }
              if (current_procdef.rettype.def.needs_inittable) then
                begin
@@ -1260,8 +1233,11 @@ implementation
 {$endif powerpc}
                   if (cs_implicit_exceptions in aktmoduleswitches) then
                     include(current_procinfo.flags,pi_needs_implicit_finally);
-                  reference_reset_base(href,current_procinfo.framepointer,current_procinfo.return_offset);
+                  reference_reset_base(href,current_procinfo.framepointer,tvarsym(current_procdef.funcretsym).adjusted_address);
                   cg.g_initialize(list,current_procdef.rettype.def,href,paramanager.ret_in_param(current_procdef.rettype.def,current_procdef.proccalloption));
+                  { load the pointer to the initialized retvalue in te register }
+                  if (tvarsym(current_procdef.funcretsym).reg.enum <> R_NO) then
+                    cg.a_load_ref_reg(list,OS_ADDR,href,tvarsym(current_procdef.funcretsym).reg);
                end;
           end;
       end;
@@ -1269,14 +1245,29 @@ implementation
 
     procedure load_return_value(list:TAAsmoutput; var uses_acc,uses_acchi,uses_fpu : boolean);
       var
-        href : treference;
+        ressym: tvarsym;
+        resloc: tlocation;
         hreg,r,r2 : tregister;
-        cgsize : TCGSize;
       begin
         if not is_void(current_procdef.rettype.def) then
          begin
-           reference_reset_base(href,current_procinfo.framepointer,current_procinfo.return_offset);
-           cgsize:=def_cgsize(current_procdef.rettype.def);
+           ressym := tvarsym(current_procdef.funcretsym);
+           if ressym.reg.enum <> R_NO then
+             begin
+               if paramanager.ret_in_param(current_procdef.rettype.def,current_procdef.proccalloption) then
+                 location_reset(resloc,LOC_CREGISTER,OS_ADDR)
+               else
+                 if ressym.vartype.def.deftype = floatdef then
+                   location_reset(resloc,LOC_CFPUREGISTER,def_cgsize(current_procdef.rettype.def))
+                 else
+                   location_reset(resloc,LOC_CREGISTER,def_cgsize(current_procdef.rettype.def));
+               resloc.register := ressym.reg;
+             end
+           else 
+             begin
+               location_reset(resloc,LOC_REFERENCE,def_cgsize(current_procdef.rettype.def));
+               reference_reset_base(resloc.reference,current_procinfo.framepointer,tvarsym(current_procdef.funcretsym).adjusted_address);
+             end;
            { Here, we return the function result. In most architectures, the value is
              passed into the FUNCTION_RETURN_REG, but in a windowed architecure like sparc a
              function returns in a register and the caller receives it in an other one }
@@ -1286,7 +1277,7 @@ implementation
                begin
                  uses_acc:=true;
 {$ifndef cpu64bit}
-                 if cgsize in [OS_64,OS_S64] then
+                 if resloc.size in [OS_64,OS_S64] then
                   begin
                     uses_acchi:=true;
                     r.enum:=R_INTREGISTER;
@@ -1295,14 +1286,14 @@ implementation
                     r2.enum:=R_INTREGISTER;
                     r2.number:=NR_FUNCTION_RETURN64_HIGH_REG;
                     cg.a_reg_alloc(list,r2);
-                    cg64.a_load64_ref_reg(list,href,joinreg64(r,r2));
+                    cg64.a_load64_loc_reg(list,resloc,joinreg64(r,r2));
                   end
                  else
 {$endif cpu64bit}
                   begin
                     hreg.enum:=R_INTREGISTER;
-                    hreg.number:=(RS_FUNCTION_RETURN_REG shl 8) or cgsize2subreg(cgsize);
-                    cg.a_load_ref_reg(list,cgsize,href,hreg);
+                    hreg.number:=(RS_FUNCTION_RETURN_REG shl 8) or cgsize2subreg(resloc.size);
+                    cg.a_load_loc_reg(list,resloc.size,resloc,hreg);
                   end;
                end;
              floatdef :
@@ -1314,7 +1305,7 @@ implementation
                  else
 {$endif cpufpemu}
                   r.enum:=FPU_RESULT_REG;
-                 cg.a_loadfpu_ref_reg(list,cgsize,href,r);
+                 cg.a_loadfpu_loc_reg(list,resloc,r);
                end;
              else
                begin
@@ -1323,7 +1314,7 @@ implementation
                     uses_acc:=true;
 {$ifndef cpu64bit}
                     { Win32 can return records in EAX:EDX }
-                    if cgsize in [OS_64,OS_S64] then
+                    if resloc.size in [OS_64,OS_S64] then
                      begin
                        uses_acchi:=true;
                        r.enum:=R_INTREGISTER;
@@ -1332,14 +1323,14 @@ implementation
                        r2.enum:=R_INTREGISTER;
                        r2.number:=NR_FUNCTION_RETURN64_HIGH_REG;
                        cg.a_reg_alloc(list,r2);
-                       cg64.a_load64_ref_reg(list,href,joinreg64(r,r2));
+                       cg64.a_load64_loc_reg(list,resloc,joinreg64(r,r2));
                      end
                     else
 {$endif cpu64bit}
                      begin
                        hreg.enum:=R_INTREGISTER;
-                       hreg.number:=(RS_FUNCTION_RETURN_REG shl 8) or cgsize2subreg(cgsize);
-                       cg.a_load_ref_reg(list,cgsize,href,hreg);
+                       hreg.number:=(RS_FUNCTION_RETURN_REG shl 8) or cgsize2subreg(resloc.size);
+                       cg.a_load_loc_reg(list,resloc.size,resloc,hreg);
                      end;
                    end
                end;
@@ -1768,20 +1759,20 @@ implementation
                 if paramanager.ret_in_param(current_procdef.rettype.def,current_procdef.proccalloption) then
                   list.concat(Tai_stabs.Create(strpnew(
                    '"'+current_procdef.procsym.name+':X*'+tstoreddef(current_procdef.rettype.def).numberstring+'",'+
-                   tostr(N_tsym)+',0,0,'+tostr(current_procinfo.return_offset))))
+                   tostr(N_tsym)+',0,0,'+tostr(tvarsym(current_procdef.funcretsym).adjusted_address))))
                 else
                   list.concat(Tai_stabs.Create(strpnew(
                    '"'+current_procdef.procsym.name+':X'+tstoreddef(current_procdef.rettype.def).numberstring+'",'+
-                   tostr(N_tsym)+',0,0,'+tostr(current_procinfo.return_offset))));
+                   tostr(N_tsym)+',0,0,'+tostr(tvarsym(current_procdef.funcretsym).adjusted_address))));
                 if (m_result in aktmodeswitches) then
                   if paramanager.ret_in_param(current_procdef.rettype.def,current_procdef.proccalloption) then
                     list.concat(Tai_stabs.Create(strpnew(
                      '"RESULT:X*'+tstoreddef(current_procdef.rettype.def).numberstring+'",'+
-                     tostr(N_tsym)+',0,0,'+tostr(current_procinfo.return_offset))))
+                     tostr(N_tsym)+',0,0,'+tostr(tvarsym(current_procdef.funcretsym).adjusted_address))))
                   else
                     list.concat(Tai_stabs.Create(strpnew(
                      '"RESULT:X'+tstoreddef(current_procdef.rettype.def).numberstring+'",'+
-                     tostr(N_tsym)+',0,0,'+tostr(current_procinfo.return_offset))));
+                     tostr(N_tsym)+',0,0,'+tostr(tvarsym(current_procdef.funcretsym).adjusted_address))));
               end;
             mangled_length:=length(current_procdef.mangledname);
             getmem(p,2*mangled_length+50);
@@ -1822,14 +1813,29 @@ implementation
 
     procedure load_inlined_return_value(list:TAAsmoutput);
       var
-        href : treference;
+        ressym: tvarsym;
+        resloc: tlocation;
         r,r2 : tregister;
-        cgsize : TCGSize;
       begin
         if not is_void(current_procdef.rettype.def) then
          begin
-           reference_reset_base(href,current_procinfo.framepointer,current_procinfo.return_offset);
-           cgsize:=def_cgsize(current_procdef.rettype.def);
+           ressym := tvarsym(current_procdef.funcretsym);
+           if ressym.reg.enum <> R_NO then
+             begin
+               if paramanager.ret_in_param(current_procdef.rettype.def,current_procdef.proccalloption) then
+                 location_reset(resloc,LOC_CREGISTER,OS_ADDR)
+               else
+                 if ressym.vartype.def.deftype = floatdef then
+                   location_reset(resloc,LOC_CFPUREGISTER,def_cgsize(current_procdef.rettype.def))
+                 else
+                   location_reset(resloc,LOC_CREGISTER,def_cgsize(current_procdef.rettype.def));
+               resloc.register := ressym.reg;
+             end
+           else   
+             begin
+               location_reset(resloc,LOC_CREGISTER,def_cgsize(current_procdef.rettype.def));
+               reference_reset_base(resloc.reference,current_procinfo.framepointer,tvarsym(current_procdef.funcretsym).adjusted_address);
+             end;
            { Here, we return the function result. In most architectures, the value is
              passed into the FUNCTION_RETURN_REG, but in a windowed architecure like sparc a
              function returns in a register and the caller receives it in an other one }
@@ -1838,17 +1844,17 @@ implementation
              enumdef :
                begin
 {$ifndef cpu64bit}
-                 if cgsize in [OS_64,OS_S64] then
+                 if resloc.size in [OS_64,OS_S64] then
                   begin
                     r:=rg.getregisterint(list,OS_INT);
                     r2:=rg.getregisterint(list,OS_INT);
-                    cg64.a_load64_ref_reg(list,href,joinreg64(r,r2));
+                    cg64.a_load64_loc_reg(list,resloc,joinreg64(r,r2));
                   end
                  else
 {$endif cpu64bit}
                   begin
-                    r:=rg.getregisterint(list,cgsize);
-                    cg.a_load_ref_reg(list,cgsize,href,r);
+                    r:=rg.getregisterint(list,resloc.size);
+                    cg.a_load_loc_reg(list,resloc.size,resloc,r);
                   end;
                end;
              floatdef :
@@ -1859,7 +1865,7 @@ implementation
                  else
 {$endif cpufpemu}
                   r.enum:=FPU_RESULT_REG;
-                 cg.a_loadfpu_ref_reg(list,cgsize,href,r);
+                 cg.a_loadfpu_loc_reg(list,resloc,r);
                end;
              else
                begin
@@ -1867,17 +1873,17 @@ implementation
                   begin
 {$ifndef cpu64bit}
                     { Win32 can return records in EAX:EDX }
-                    if cgsize in [OS_64,OS_S64] then
+                    if resloc.size in [OS_64,OS_S64] then
                      begin
                        r:=rg.getregisterint(list,OS_INT);
                        r2:=rg.getregisterint(list,OS_INT);
-                       cg64.a_load64_ref_reg(list,href,joinreg64(r,r2));
+                       cg64.a_load64_loc_reg(list,resloc,joinreg64(r,r2));
                      end
                     else
 {$endif cpu64bit}
                      begin
-                       r:=rg.getregisterint(list,cgsize);
-                       cg.a_load_ref_reg(list,cgsize,href,r);
+                       r:=rg.getregisterint(list,resloc.size);
+                       cg.a_load_loc_reg(list,resloc.size,resloc,r);
                      end;
                    end
                end;
@@ -1946,7 +1952,12 @@ implementation
 end.
 {
   $Log$
-  Revision 1.116  2003-06-01 21:38:06  peter
+  Revision 1.117  2003-06-02 21:42:05  jonas
+    * function results can now also be regvars
+    - removed tprocinfo.return_offset, never use it again since it's invalid
+      if the result is a regvar
+
+  Revision 1.116  2003/06/01 21:38:06  peter
     * getregisterfpu size parameter added
     * op_const_reg size parameter added
     * sparc updates

+ 11 - 1
compiler/pdecsub.pas

@@ -111,6 +111,7 @@ implementation
            { Generate result variable accessing function result }
            vs:=tvarsym.create('$result',vs_var,pd.rettype);
            include(vs.varoptions,vo_is_funcret);
+           include(vs.varoptions,vo_regable);
            pd.parast.insert(vs);
            pd.insertpara(vs.vartype,vs,nil,true);
            { Store the this symbol as funcretsym for procedures }
@@ -210,6 +211,10 @@ implementation
             begin
               vs:=tvarsym.create('$result',vs_value,pd.rettype);
               include(vs.varoptions,vo_is_funcret);
+              if tstoreddef(pd.rettype.def).is_intregable then
+                include(vs.varoptions,vo_regable);
+              if tstoreddef(pd.rettype.def).is_fpuregable then
+                include(vs.varoptions,vo_fpuregable);
               pd.localst.insert(vs);
               pd.localst.insertvardata(vs);
               pd.funcretsym:=vs;
@@ -2163,7 +2168,12 @@ const
 end.
 {
   $Log$
-  Revision 1.125  2003-05-22 21:31:35  peter
+  Revision 1.126  2003-06-02 21:42:05  jonas
+    * function results can now also be regvars
+    - removed tprocinfo.return_offset, never use it again since it's invalid
+      if the result is a regvar
+
+  Revision 1.125  2003/05/22 21:31:35  peter
     * defer codegeneration for nested procedures
 
   Revision 1.124  2003/05/15 18:58:53  peter

+ 6 - 3
compiler/powerpc/cpupi.pas

@@ -78,8 +78,6 @@ unit cpupi;
                aktproccode.insert(Tai_comment.Create(strpnew('Parameter copies start at: r1+'+tostr(procdef.parast.address_fixup))));
 
              procdef.localst.address_fixup:=procdef.parast.address_fixup+procdef.parast.datasize;
-             if assigned(procdef.funcretsym) then
-               return_offset:=tvarsym(procdef.funcretsym).address+tvarsym(procdef.funcretsym).owner.address_fixup;
 
              if cs_asm_source in aktglobalswitches then
                aktproccode.insert(Tai_comment.Create(strpnew('Locals start at: r1+'+tostr(procdef.localst.address_fixup))));
@@ -100,7 +98,12 @@ begin
 end.
 {
   $Log$
-  Revision 1.21  2003-05-24 11:47:27  jonas
+  Revision 1.22  2003-06-02 21:42:05  jonas
+    * function results can now also be regvars
+    - removed tprocinfo.return_offset, never use it again since it's invalid
+      if the result is a regvar
+
+  Revision 1.21  2003/05/24 11:47:27  jonas
     * fixed framepointer storage: it's now always stored at r1+12, which is
       a place in the link area reserved for compiler use.
 

+ 7 - 2
compiler/powerpc/radirect.pas

@@ -114,7 +114,7 @@ interface
          tvarsym(current_procdef.funcretsym).varstate:=vs_assigned;
        { !!!!!
        if (not is_void(current_procdef.rettype.def)) then
-         retstr:=upper(tostr(procinfo^.return_offset)+'('+gas_reg2str[procinfo^.framepointer]+')')
+         retstr:=upper(tostr(tvarsym(current_procdef.funcretsym).adjusted_address)+'('+gas_reg2str[procinfo^.framepointer]+')')
        else
        }
          retstr:='';
@@ -351,7 +351,12 @@ initialization
 end.
 {
   $Log$
-  Revision 1.14  2003-05-30 23:57:08  peter
+  Revision 1.15  2003-06-02 21:42:05  jonas
+    * function results can now also be regvars
+    - removed tprocinfo.return_offset, never use it again since it's invalid
+      if the result is a regvar
+
+  Revision 1.14  2003/05/30 23:57:08  peter
     * more sparc cleanup
     * accumulator removed, splitted in function_return_reg (called) and
       function_result_reg (caller)

+ 7 - 2
compiler/sparc/radirect.pas

@@ -99,7 +99,7 @@ interface
        framereg:=current_procinfo.framepointer;
        convert_register_to_enum(framereg);
        if (not is_void(current_procdef.rettype.def)) then
-         retstr:=upper(tostr(current_procinfo.return_offset)+'('+std_reg2str[framereg.enum]+')')
+         retstr:=upper(tostr(tvarsym(current_procdef.funcretsym).adjusted_address)+'('+std_reg2str[framereg.enum]+')')
        else
          retstr:='';
 
@@ -349,7 +349,12 @@ initialization
 end.
 {
   $Log$
-  Revision 1.10  2003-05-23 22:33:48  florian
+  Revision 1.11  2003-06-02 21:42:05  jonas
+    * function results can now also be regvars
+    - removed tprocinfo.return_offset, never use it again since it's invalid
+      if the result is a regvar
+
+  Revision 1.10  2003/05/23 22:33:48  florian
     * fix some small flaws which prevent sparc linux system unit from compiling
     * some reformatting done
 

+ 7 - 2
compiler/x86/radirect.pas

@@ -94,7 +94,7 @@ interface
        framereg:=current_procinfo.framepointer;
        convert_register_to_enum(framereg);
        if (not is_void(current_procdef.rettype.def)) then
-         retstr:=upper(tostr(current_procinfo.return_offset)+'('+gas_reg2str[framereg.enum]+')')
+         retstr:=upper(tostr(tvarsym(current_procdef.funcretsym).adjusted_address)+'('+gas_reg2str[framereg.enum]+')')
        else
          retstr:='';
        c:=current_scanner.asmgetchar;
@@ -361,7 +361,12 @@ initialization
 end.
 {
   $Log$
-  Revision 1.5  2003-05-22 21:33:31  peter
+  Revision 1.6  2003-06-02 21:42:05  jonas
+    * function results can now also be regvars
+    - removed tprocinfo.return_offset, never use it again since it's invalid
+      if the result is a regvar
+
+  Revision 1.5  2003/05/22 21:33:31  peter
     * removed some unit dependencies
 
   Revision 1.4  2003/05/15 18:58:54  peter