Răsfoiți Sursa

* start of sparc support for newra

peter 22 ani în urmă
părinte
comite
52c73e80d1

+ 69 - 5
compiler/aasmtai.pas

@@ -444,12 +444,17 @@ interface
           procedure loadoper(opidx:longint;o:toper);
           procedure loadoper(opidx:longint;o:toper);
           function is_nop:boolean;virtual;abstract;
           function is_nop:boolean;virtual;abstract;
           function is_move:boolean;virtual;abstract;
           function is_move:boolean;virtual;abstract;
+{$ifdef NEWRA}
+          { register allocator }
+          function get_insert_pos(p:Tai;huntfor1,huntfor2,huntfor3:Tsuperregister;var unusedregsint:Tsupregset):Tai;
+          procedure forward_allocation(p:Tai;var unusedregsint:Tsupregset);
           function spill_registers(list:Taasmoutput;
           function spill_registers(list:Taasmoutput;
                                    rgget:Trggetproc;
                                    rgget:Trggetproc;
                                    rgunget:Trgungetproc;
                                    rgunget:Trgungetproc;
                                    r:Tsupregset;
                                    r:Tsupregset;
                                    var unusedregsint:Tsupregset;
                                    var unusedregsint:Tsupregset;
                                    const spilltemplist:Tspill_temp_list):boolean;virtual;abstract;
                                    const spilltemplist:Tspill_temp_list):boolean;virtual;abstract;
+{$endif NEWRA}
        end;
        end;
 
 
        { alignment for operator }
        { alignment for operator }
@@ -494,13 +499,13 @@ interface
 
 
 implementation
 implementation
 
 
-uses
+    uses
 {$ifdef delphi}
 {$ifdef delphi}
-  sysutils,
+      sysutils,
 {$else}
 {$else}
-  strings,
+      strings,
 {$endif}
 {$endif}
-  verbose;
+      verbose;
 
 
     const
     const
       pputaimarker = 254;
       pputaimarker = 254;
@@ -1586,6 +1591,62 @@ uses
          end;
          end;
       end;
       end;
 
 
+{$ifdef NEWRA}
+{ ---------------------------------------------------------------------
+    Register allocator methods.
+  ---------------------------------------------------------------------}
+
+    function taicpu_abstract.get_insert_pos(p:Tai;huntfor1,huntfor2,huntfor3:Tsuperregister;var unusedregsint:Tsupregset):Tai;
+      var
+        back:Tsupregset;
+      begin
+        back:=unusedregsint;
+        get_insert_pos:=p;
+        while (p<>nil) and (p.typ=ait_regalloc) do
+          begin
+            {Rewind the register allocation.}
+            if Tai_regalloc(p).allocation then
+              include(unusedregsint,Tai_regalloc(p).reg.number shr 8)
+            else
+              begin
+                exclude(unusedregsint,Tai_regalloc(p).reg.number shr 8);
+                if Tai_regalloc(p).reg.number shr 8=huntfor1 then
+                  begin
+                    get_insert_pos:=Tai(p.previous);
+                    back:=unusedregsint;
+                  end;
+                if Tai_regalloc(p).reg.number shr 8=huntfor2 then
+                  begin
+                    get_insert_pos:=Tai(p.previous);
+                    back:=unusedregsint;
+                  end;
+                if Tai_regalloc(p).reg.number shr 8=huntfor3 then
+                  begin
+                    get_insert_pos:=Tai(p.previous);
+                    back:=unusedregsint;
+                  end;
+              end;
+            p:=Tai(p.previous);
+          end;
+        unusedregsint:=back;
+      end;
+
+
+    procedure taicpu_abstract.forward_allocation(p:Tai;var unusedregsint:Tsupregset);
+      begin
+        {Forward the register allocation again.}
+        while (p<>self) do
+          begin
+            if p.typ<>ait_regalloc then
+              internalerror(200305311);
+            if Tai_regalloc(p).allocation then
+              exclude(unusedregsint,Tai_regalloc(p).reg.number shr 8)
+            else
+              include(unusedregsint,Tai_regalloc(p).reg.number shr 8);
+            p:=Tai(p.next);
+          end;
+      end;
+{$endif NEWRA}
 
 
 { ---------------------------------------------------------------------
 { ---------------------------------------------------------------------
     Miscellaneous methods.
     Miscellaneous methods.
@@ -1838,7 +1899,10 @@ uses
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.30  2003-07-02 16:43:48  jonas
+  Revision 1.31  2003-08-11 21:18:20  peter
+    * start of sparc support for newra
+
+  Revision 1.30  2003/07/02 16:43:48  jonas
     * always add dummy marker object at the start of an assembler list, so
     * always add dummy marker object at the start of an assembler list, so
       the optimizer can't remove the first object
       the optimizer can't remove the first object
 
 

+ 30 - 31
compiler/cgbase.pas

@@ -370,43 +370,39 @@ implementation
       var
       var
         paramloc : tparalocation;
         paramloc : tparalocation;
       begin
       begin
+         { generate callee paraloc register info }
+         paramanager.create_paraloc_info(current_procinfo.procdef,calleeside);
+
          { temporary space is set, while the BEGIN of the procedure }
          { temporary space is set, while the BEGIN of the procedure }
          if (symtablestack.symtabletype=localsymtable) then
          if (symtablestack.symtabletype=localsymtable) then
            current_procinfo.firsttemp_offset := tg.direction*symtablestack.datasize
            current_procinfo.firsttemp_offset := tg.direction*symtablestack.datasize
          else
          else
            current_procinfo.firsttemp_offset := 0;
            current_procinfo.firsttemp_offset := 0;
-         { space for the return value }
-         { !!!!!   this means that we can not set the return value
-         in a subfunction !!!!! }
-         { because we don't know yet where the address is }
+
+         { include return value registers }
          if not is_void(procdef.rettype.def) then
          if not is_void(procdef.rettype.def) then
            begin
            begin
-              if not paramanager.ret_in_param(procdef.rettype.def,procdef.proccalloption) then
-                begin
-                  paramloc:=paramanager.getfuncresultloc(procdef,procdef.proccalloption);
-                  case paramloc.loc of
-                    LOC_FPUREGISTER,
-                    LOC_CFPUREGISTER,
-                    LOC_MMREGISTER,
-                    LOC_CMMREGISTER :
-                      begin
-                        include(rg.used_in_proc_other,paramloc.register.enum);
-                      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,paramloc.registerhigh.number shr 8);
-                            include(rg.used_in_proc_int,paramloc.registerlow.number shr 8);
-                          end
-                        else
-                          include(rg.used_in_proc_int,paramloc.register.number shr 8);
-                      end;
-                    else
-                      internalerror(20020816);
-                  end;
-                end;
+             paramloc:=procdef.funcret_paraloc[calleeside];
+             case paramloc.loc of
+               LOC_FPUREGISTER,
+               LOC_CFPUREGISTER,
+               LOC_MMREGISTER,
+               LOC_CMMREGISTER :
+                 begin
+                   include(rg.used_in_proc_other,paramloc.register.enum);
+                 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,paramloc.registerhigh.number shr 8);
+                       include(rg.used_in_proc_int,paramloc.registerlow.number shr 8);
+                     end
+                   else
+                     include(rg.used_in_proc_int,paramloc.register.number shr 8);
+                 end;
+             end;
            end;
            end;
       end;
       end;
 
 
@@ -571,7 +567,10 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.57  2003-07-06 17:58:22  peter
+  Revision 1.58  2003-08-11 21:18:20  peter
+    * start of sparc support for newra
+
+  Revision 1.57  2003/07/06 17:58:22  peter
     * framepointer fixes for sparc
     * framepointer fixes for sparc
     * parent framepointer code more generic
     * parent framepointer code more generic
 
 

+ 6 - 2
compiler/fpcdefs.inc

@@ -60,7 +60,8 @@
 {$endif alpha}
 {$endif alpha}
 
 
 {$ifdef sparc}
 {$ifdef sparc}
-  {$define callparatemp}
+  {$define usetempparaloc}
+  { define callparatemp}
 {$endif sparc}
 {$endif sparc}
 
 
 {$ifdef powerpc}
 {$ifdef powerpc}
@@ -83,7 +84,10 @@
 
 
 {
 {
   $Log$
   $Log$
-  Revision 1.21  2003-07-21 11:52:57  florian
+  Revision 1.22  2003-08-11 21:18:20  peter
+    * start of sparc support for newra
+
+  Revision 1.21  2003/07/21 11:52:57  florian
     * very basic stuff for the arm
     * very basic stuff for the arm
 
 
   Revision 1.20  2003/05/24 21:12:57  florian
   Revision 1.20  2003/05/24 21:12:57  florian

+ 42 - 7
compiler/i386/cpupara.pas

@@ -33,7 +33,7 @@ unit cpupara;
        cpubase,
        cpubase,
        globtype,
        globtype,
        cginfo,
        cginfo,
-       symtype,symdef,paramgr;
+       symconst,symtype,symdef,paramgr;
 
 
     type
     type
        { Returns the location for the nr-st 32 Bit int parameter
        { Returns the location for the nr-st 32 Bit int parameter
@@ -55,7 +55,7 @@ unit cpupara;
 
 
     uses
     uses
        systems,verbose,
        systems,verbose,
-       symconst,symsym,
+       symsym,
        cpuinfo,
        cpuinfo,
        cgbase;
        cgbase;
 
 
@@ -153,13 +153,45 @@ unit cpupara;
                 paraloc.reference.index.number:=NR_FRAME_POINTER_REG;
                 paraloc.reference.index.number:=NR_FRAME_POINTER_REG;
               end;
               end;
             paraloc.reference.offset:=tvarsym(hp.parasym).adjusted_address;
             paraloc.reference.offset:=tvarsym(hp.parasym).adjusted_address;
-            if side = callerside then
-              hp.callerparaloc:=paraloc
+            hp.paraloc[side]:=paraloc;
 {$warning callerparaloc shall not be the same as calleeparaloc}
 {$warning callerparaloc shall not be the same as calleeparaloc}
-            else
-              hp.calleeparaloc:=paraloc;
             hp:=tparaitem(hp.next);
             hp:=tparaitem(hp.next);
           end;
           end;
+
+        { Function return }
+        fillchar(paraloc,sizeof(tparalocation),0);
+        paraloc.size:=def_cgsize(p.rettype.def);
+        { Return in FPU register? }
+        if p.rettype.def.deftype=floatdef then
+          begin
+            paraloc.loc:=LOC_FPUREGISTER;
+            paraloc.register.enum:=FPU_RESULT_REG;
+          end
+        else
+         { Return in register? }
+         if not ret_in_param(p.rettype.def,p.proccalloption) then
+          begin
+            paraloc.loc:=LOC_REGISTER;
+{$ifndef cpu64bit}
+            if paraloc.size in [OS_64,OS_S64] then
+             begin
+               paraloc.register64.reglo.enum:=R_INTREGISTER;
+               paraloc.register64.reglo.number:=NR_FUNCTION_RETURN64_LOW_REG;
+               paraloc.register64.reghi.enum:=R_INTREGISTER;
+               paraloc.register64.reghi.number:=NR_FUNCTION_RETURN64_HIGH_REG;
+             end
+            else
+{$endif cpu64bit}
+             begin
+               paraloc.register.enum:=R_INTREGISTER;
+               paraloc.register.number:=NR_FUNCTION_RETURN_REG;
+             end;
+          end
+        else
+          begin
+            paraloc.loc:=LOC_REFERENCE;
+          end;
+        p.funcret_paraloc[side]:=paraloc;
       end;
       end;
 
 
 
 
@@ -182,7 +214,10 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.21  2003-07-05 20:11:41  jonas
+  Revision 1.22  2003-08-11 21:18:20  peter
+    * start of sparc support for newra
+
+  Revision 1.21  2003/07/05 20:11:41  jonas
     * create_paraloc_info() is now called separately for the caller and
     * create_paraloc_info() is now called separately for the caller and
       callee info
       callee info
     * fixed ppc cycle
     * fixed ppc cycle

+ 141 - 96
compiler/ncgcal.pas

@@ -35,6 +35,9 @@ interface
 
 
     type
     type
        tcgcallparanode = class(tcallparanode)
        tcgcallparanode = class(tcallparanode)
+       private
+          tempparaloc : tparalocation;
+       public
           procedure secondcallparan(push_from_left_to_right:boolean;calloption:tproccalloption;
           procedure secondcallparan(push_from_left_to_right:boolean;calloption:tproccalloption;
                 para_alignment,para_offset : longint);override;
                 para_alignment,para_offset : longint);override;
        end;
        end;
@@ -125,19 +128,31 @@ implementation
          objectlibrary.getlabel(truelabel);
          objectlibrary.getlabel(truelabel);
          objectlibrary.getlabel(falselabel);
          objectlibrary.getlabel(falselabel);
          secondpass(left);
          secondpass(left);
-         { allocate paraloc }
-         paramanager.allocparaloc(exprasmlist,paraitem.callerparaloc);
+
+         { Allocate (temporary) paralocation }
+{$ifdef usetempparaloc}
+         tempparaloc:=paraitem.paraloc[callerside];
+         if tempparaloc.loc=LOC_REGISTER then
+           paramanager.alloctempregs(exprasmlist,tempparaloc)
+         else
+           paramanager.allocparaloc(exprasmlist,tempparaloc);
+{$else}
+         tempparaloc:=paraitem.paraloc[callerside];
+         paramanager.allocparaloc(exprasmlist,tempparaloc);
+{$endif usetempparaloc}
+
+
          { handle varargs first, because defcoll is not valid }
          { handle varargs first, because defcoll is not valid }
          if (nf_varargs_para in flags) then
          if (nf_varargs_para in flags) then
            begin
            begin
              if paramanager.push_addr_param(left.resulttype.def,calloption) then
              if paramanager.push_addr_param(left.resulttype.def,calloption) then
                begin
                begin
                  inc(pushedparasize,POINTER_SIZE);
                  inc(pushedparasize,POINTER_SIZE);
-                 cg.a_paramaddr_ref(exprasmlist,left.location.reference,paraitem.callerparaloc);
+                 cg.a_paramaddr_ref(exprasmlist,left.location.reference,tempparaloc);
                  location_release(exprasmlist,left.location);
                  location_release(exprasmlist,left.location);
                end
                end
              else
              else
-               push_value_para(exprasmlist,left,calloption,para_offset,para_alignment,paraitem.callerparaloc);
+               push_value_para(exprasmlist,left,calloption,para_offset,para_alignment,tempparaloc);
            end
            end
          { hidden parameters }
          { hidden parameters }
          else if paraitem.is_hidden then
          else if paraitem.is_hidden then
@@ -169,13 +184,13 @@ implementation
                     {$endif}
                     {$endif}
                     end
                     end
                   else
                   else
-                    cg.a_paramaddr_ref(exprasmlist,left.location.reference,paraitem.callerparaloc);
+                    cg.a_paramaddr_ref(exprasmlist,left.location.reference,tempparaloc);
                   location_release(exprasmlist,left.location);
                   location_release(exprasmlist,left.location);
                end
                end
              else
              else
                begin
                begin
                   push_value_para(exprasmlist,left,calloption,
                   push_value_para(exprasmlist,left,calloption,
-                    para_offset,para_alignment,paraitem.callerparaloc);
+                    para_offset,para_alignment,tempparaloc);
                end;
                end;
            end
            end
          { filter array of const c styled args }
          { filter array of const c styled args }
@@ -203,7 +218,7 @@ implementation
                        cg.a_load_loc_ref(exprasmlist,OS_ADDR,left.location,href);
                        cg.a_load_loc_ref(exprasmlist,OS_ADDR,left.location,href);
                     end
                     end
                   else
                   else
-                    cg.a_param_loc(exprasmlist,left.location,paraitem.callerparaloc);
+                    cg.a_param_loc(exprasmlist,left.location,tempparaloc);
                   location_release(exprasmlist,left.location);
                   location_release(exprasmlist,left.location);
                 end
                 end
               else
               else
@@ -228,7 +243,7 @@ implementation
                      {$endif}
                      {$endif}
                      end
                      end
                    else
                    else
-                     cg.a_paramaddr_ref(exprasmlist,left.location.reference,paraitem.callerparaloc);
+                     cg.a_paramaddr_ref(exprasmlist,left.location.reference,tempparaloc);
                    location_release(exprasmlist,left.location);
                    location_release(exprasmlist,left.location);
                 end;
                 end;
            end
            end
@@ -266,7 +281,7 @@ implementation
                 {$endif}
                 {$endif}
                 end
                 end
               else
               else
-                cg.a_paramaddr_ref(exprasmlist,left.location.reference,paraitem.callerparaloc);
+                cg.a_paramaddr_ref(exprasmlist,left.location.reference,tempparaloc);
               location_release(exprasmlist,left.location);
               location_release(exprasmlist,left.location);
            end
            end
          else
          else
@@ -316,13 +331,13 @@ implementation
                      {$endif}
                      {$endif}
                      end
                      end
                    else
                    else
-                     cg.a_paramaddr_ref(exprasmlist,left.location.reference,paraitem.callerparaloc);
+                     cg.a_paramaddr_ref(exprasmlist,left.location.reference,tempparaloc);
                    location_release(exprasmlist,left.location);
                    location_release(exprasmlist,left.location);
                 end
                 end
               else
               else
                 begin
                 begin
                    push_value_para(exprasmlist,left,calloption,
                    push_value_para(exprasmlist,left,calloption,
-                     para_offset,para_alignment,paraitem.callerparaloc);
+                     para_offset,para_alignment,tempparaloc);
                 end;
                 end;
            end;
            end;
          truelabel:=otlabel;
          truelabel:=otlabel;
@@ -401,7 +416,9 @@ implementation
       var
       var
         cgsize : tcgsize;
         cgsize : tcgsize;
         r,hregister : tregister;
         r,hregister : tregister;
+{$ifndef NEWRA}
         href: treference;
         href: treference;
+{$endif}
         tempnode: tnode;
         tempnode: tnode;
       begin
       begin
         { structured results are easy to handle.... }
         { structured results are easy to handle.... }
@@ -418,7 +435,7 @@ implementation
             is_widestring(resulttype.def) then
             is_widestring(resulttype.def) then
           begin
           begin
             r.enum:=R_INTREGISTER;
             r.enum:=R_INTREGISTER;
-            r.number:=NR_FUNCTION_RETURN_REG;
+            r.number:=NR_FUNCTION_RESULT_REG;
 {$ifdef newra}
 {$ifdef newra}
             { the FUNCTION_RESULT_REG is already allocated }
             { the FUNCTION_RESULT_REG is already allocated }
             rg.ungetregisterint(exprasmlist,r);
             rg.ungetregisterint(exprasmlist,r);
@@ -648,9 +665,7 @@ implementation
          regs_to_push_other : tregisterset;
          regs_to_push_other : tregisterset;
          unusedstate: pointer;
          unusedstate: pointer;
       {$ifdef newra}
       {$ifdef newra}
-         i:Tsuperregister;
          regs_to_alloc,regs_to_free:Tsupregset;
          regs_to_alloc,regs_to_free:Tsupregset;
-         funcretloc: tparalocation;
       {$else}
       {$else}
          regs_to_push_int : Tsupregset;
          regs_to_push_int : Tsupregset;
          pushedint : tpushedsavedint;
          pushedint : tpushedsavedint;
@@ -664,23 +679,62 @@ implementation
          href,helpref : treference;
          href,helpref : treference;
          para_alignment,
          para_alignment,
          pop_size : longint;
          pop_size : longint;
-         r,
 {$ifdef x86}
 {$ifdef x86}
          accreg,
          accreg,
 {$endif x86}
 {$endif x86}
          vmtreg,vmtreg2 : tregister;
          vmtreg,vmtreg2 : tregister;
          oldaktcallnode : tcallnode;
          oldaktcallnode : tcallnode;
 
 
+         procedure pushparas;
+         var
+           ppn : tcgcallparanode;
+         begin
+           { copy all resources to the allocated registers }
+           ppn:=tcgcallparanode(left);
+           while assigned(ppn) do
+             begin
+               if ppn.tempparaloc.loc=LOC_REGISTER then
+                 begin
+                   paramanager.allocparaloc(exprasmlist,ppn.paraitem.paraloc[callerside]);
+{$ifdef sparc}
+                   case ppn.tempparaloc.size of
+                     OS_F32 :
+                       ppn.tempparaloc.size:=OS_32;
+                     OS_F64 :
+                       ppn.tempparaloc.size:=OS_64;
+                   end;
+{$endif sparc}
+{$ifndef cpu64bit}
+                   if ppn.tempparaloc.size in [OS_64,OS_S64] then
+                     begin
+                       cg.a_load_reg_reg(exprasmlist,OS_32,OS_32,ppn.tempparaloc.registerlow,
+                          ppn.paraitem.paraloc[callerside].registerlow);
+                       cg.a_load_reg_reg(exprasmlist,OS_32,OS_32,ppn.tempparaloc.registerhigh,
+                          ppn.paraitem.paraloc[callerside].registerhigh);
+                     end
+                   else
+{$endif cpu64bit}
+                     cg.a_load_reg_reg(exprasmlist,ppn.tempparaloc.size,ppn.paraitem.paraloc[callerside].size,
+                         ppn.tempparaloc.register,ppn.paraitem.paraloc[callerside].register);
+                 end;
+               ppn:=tcgcallparanode(ppn.right);
+             end;
+         end;
+
          procedure freeparas;
          procedure freeparas;
          var
          var
-           paraitem : tparaitem;
+           ppn : tcgcallparanode;
          begin
          begin
            { free the resources allocated for the parameters }
            { free the resources allocated for the parameters }
-           paraitem:=tparaitem(procdefinition.para.first);
-           while assigned(paraitem) do
+           ppn:=tcgcallparanode(left);
+           while assigned(ppn) do
              begin
              begin
-               paramanager.freeparaloc(exprasmlist,paraitem.callerparaloc);
-               paraitem:=tparaitem(paraitem.next);
+{$ifdef usetempparaloc}
+               if ppn.tempparaloc.loc=LOC_REGISTER then
+                 paramanager.freeparaloc(exprasmlist,ppn.tempparaloc);
+{$endif usetempparaloc}
+               paramanager.freeparaloc(exprasmlist,ppn.paraitem.paraloc[callerside]);
+               ppn:=tcgcallparanode(ppn.right);
              end;
              end;
            { free pushed base pointer }
            { free pushed base pointer }
            if (right=nil) and
            if (right=nil) and
@@ -743,44 +797,10 @@ implementation
 
 
 {$ifdef newra}
 {$ifdef newra}
               regs_to_alloc:=Tprocdef(procdefinition).usedintregisters;
               regs_to_alloc:=Tprocdef(procdefinition).usedintregisters;
-              if (not is_void(resulttype.def)) and
-                 not(paramanager.ret_in_param(resulttype.def,procdefinition.proccalloption)) then
-                begin
-                  funcretloc := paramanager.getfuncretparaloc(procdefinition);
-                  case funcretloc.loc of
-                    LOC_REGISTER,LOC_CREGISTER:
-                      begin
-{$ifndef cpu64bit}
-                        if funcretloc.size in [OS_S64,OS_64] then
-                          begin
-                            include(regs_to_alloc,funcretloc.registerlow.number shr 8);
-                            include(regs_to_alloc,funcretloc.registerhigh.number shr 8);
-                          end
-                       else
-{$endif cpu64bit}
-                         include(regs_to_alloc,funcretloc.register.number shr 8);
-                     end;
-                  end;
-                end;
 {$else}
 {$else}
               { save all used registers and possible registers
               { save all used registers and possible registers
                 used for the return value }
                 used for the return value }
               regs_to_push_int := tprocdef(procdefinition).usedintregisters;
               regs_to_push_int := tprocdef(procdefinition).usedintregisters;
-              if (not is_void(resulttype.def)) and
-                 (not paramanager.ret_in_param(resulttype.def,procdefinition.proccalloption)) then
-               begin
-{$ifndef cpu64bit}
-                 if resulttype.def.deftype<>floatdef then
-                   if resulttype.def.size>sizeof(aword) then
-                     begin
-                       include(regs_to_push_int,RS_FUNCTION_RESULT64_LOW_REG);
-                       include(regs_to_push_int,RS_FUNCTION_RESULT64_HIGH_REG);
-                     end
-                   else
-{$endif cpu64bit}
-                    include(regs_to_push_int,RS_FUNCTION_RESULT_REG);
-               end;
-              rg.saveusedintregisters(exprasmlist,pushedint,regs_to_push_int);
 {$endif}
 {$endif}
 
 
 {$ifdef i386}
 {$ifdef i386}
@@ -788,8 +808,6 @@ implementation
 {$else i386}
 {$else i386}
               regs_to_push_other := [];
               regs_to_push_other := [];
 {$endif i386}
 {$endif i386}
-              rg.saveusedotherregisters(exprasmlist,pushedother,regs_to_push_other);
-
               { on the ppc, ever procedure saves the non-volatile registers it uses itself }
               { on the ppc, ever procedure saves the non-volatile registers it uses itself }
               { and must make sure it saves its volatile registers before doing a call     }
               { and must make sure it saves its volatile registers before doing a call     }
 {$ifdef i386}
 {$ifdef i386}
@@ -800,39 +818,18 @@ implementation
            end
            end
          else
          else
            begin
            begin
-              {No procedure is allowed to destroy ebp.}
 {$ifdef newra}
 {$ifdef newra}
               regs_to_alloc:=VOLATILE_INTREGISTERS;
               regs_to_alloc:=VOLATILE_INTREGISTERS;
-              if (not is_void(resulttype.def)) and
-                 not(paramanager.ret_in_param(resulttype.def,procdefinition.proccalloption)) then
-                begin
-                  funcretloc := paramanager.getfuncretparaloc(procdefinition);
-                  case funcretloc.loc of
-                    LOC_REGISTER,LOC_CREGISTER:
-                      begin
-{$ifndef cpu64bit}
-                        if funcretloc.size in [OS_S64,OS_64] then
-                          begin
-                            include(regs_to_alloc,funcretloc.registerlow.number shr 8);
-                            include(regs_to_alloc,funcretloc.registerhigh.number shr 8);
-                          end
-                       else
-{$endif cpu64bit}
-                         include(regs_to_alloc,funcretloc.register.number shr 8);
-                     end;
-                  end;
-                end;
 {$else}
 {$else}
               regs_to_push_int := VOLATILE_INTREGISTERS;
               regs_to_push_int := VOLATILE_INTREGISTERS;
-              rg.saveusedintregisters(exprasmlist,pushedint,regs_to_push_int);
 {$endif}
 {$endif}
 {$ifdef i386}
 {$ifdef i386}
               regs_to_push_other := all_registers;
               regs_to_push_other := all_registers;
 {$else i386}
 {$else i386}
               regs_to_push_other := [];
               regs_to_push_other := [];
 {$endif i386}
 {$endif i386}
-              rg.saveusedotherregisters(exprasmlist,pushedother,regs_to_push_other);
 {$ifdef i386}
 {$ifdef i386}
+              rg.used_in_proc_int:=VOLATILE_INTREGISTERS;
               rg.used_in_proc_other:=all_registers;
               rg.used_in_proc_other:=all_registers;
 {$endif i386}
 {$endif i386}
 
 
@@ -840,6 +837,48 @@ implementation
               iolabel:=nil;
               iolabel:=nil;
            end;
            end;
 
 
+        { Include Function result registers }
+        if (not is_void(resulttype.def)) then
+          begin
+{$ifdef NEWRA}
+            case procdefinition.funcret_paraloc[callerside].loc of
+              LOC_REGISTER,LOC_CREGISTER:
+                begin
+{$ifndef cpu64bit}
+                  if procdefinition.funcret_paraloc[callerside].size in [OS_S64,OS_64] then
+                    begin
+                      include(regs_to_alloc,procdefinition.funcret_paraloc[callerside].registerlow.number shr 8);
+                      include(regs_to_alloc,procdefinition.funcret_paraloc[callerside].registerhigh.number shr 8);
+                    end
+                 else
+{$endif cpu64bit}
+                   include(regs_to_alloc,procdefinition.funcret_paraloc[callerside].register.number shr 8);
+                end;
+            end;
+{$else NEWRA}
+            case procdefinition.funcret_paraloc[callerside].loc of
+              LOC_REGISTER,LOC_CREGISTER:
+                begin
+{$ifndef cpu64bit}
+                  if procdefinition.funcret_paraloc[callerside].size in [OS_S64,OS_64] then
+                    begin
+                      include(regs_to_push_int,procdefinition.funcret_paraloc[callerside].registerlow.number shr 8);
+                      include(regs_to_push_int,procdefinition.funcret_paraloc[callerside].registerhigh.number shr 8);
+                    end
+                 else
+{$endif cpu64bit}
+                   include(regs_to_push_int,procdefinition.funcret_paraloc[callerside].register.number shr 8);
+                end;
+            end;
+{$endif NEWRA}
+          end;
+
+         { Save registers destroyed by the call }
+{$ifndef NEWRA}
+         rg.saveusedintregisters(exprasmlist,pushedint,regs_to_push_int);
+{$endif}
+         rg.saveusedotherregisters(exprasmlist,pushedother,regs_to_push_other);
+
          { Initialize for pushing the parameters }
          { Initialize for pushing the parameters }
          oldpushedparasize:=pushedparasize;
          oldpushedparasize:=pushedparasize;
          pushedparasize:=0;
          pushedparasize:=0;
@@ -879,6 +918,7 @@ implementation
            end;
            end;
 {$endif not i386}
 {$endif not i386}
 
 
+         { Process parameters }
          if assigned(left) then
          if assigned(left) then
            begin
            begin
             {$ifndef newra}
             {$ifndef newra}
@@ -899,6 +939,10 @@ implementation
                 if assigned(methodpointer) then
                 if assigned(methodpointer) then
                   maybe_restore(exprasmlist,methodpointer.location,pushedregs);
                   maybe_restore(exprasmlist,methodpointer.location,pushedregs);
             {$endif newra}
             {$endif newra}
+
+{$ifdef usetempparaloc}
+             pushparas;
+{$endif}
            end;
            end;
          aktcallnode:=oldaktcallnode;
          aktcallnode:=oldaktcallnode;
 
 
@@ -1058,22 +1102,23 @@ implementation
 {$endif TEMPREGDEBUG}
 {$endif TEMPREGDEBUG}
 
 
 {$ifdef newra}
 {$ifdef newra}
+         { Release registers, but not the registers that contain the
+           function result }
          regs_to_free:=regs_to_alloc;
          regs_to_free:=regs_to_alloc;
-         if (not is_void(resulttype.def)) and
-            not(paramanager.ret_in_param(resulttype.def,procdefinition.proccalloption)) then
+         if (not is_void(resulttype.def)) then
            begin
            begin
-             case funcretloc.loc of
+             case procdefinition.funcret_paraloc[callerside].loc of
                LOC_REGISTER,LOC_CREGISTER:
                LOC_REGISTER,LOC_CREGISTER:
                  begin
                  begin
 {$ifndef cpu64bit}
 {$ifndef cpu64bit}
-                   if funcretloc.size in [OS_S64,OS_64] then
+                   if procdefinition.funcret_paraloc[callerside].size in [OS_S64,OS_64] then
                      begin
                      begin
-                       exclude(regs_to_free,funcretloc.registerlow.number shr 8);
-                       exclude(regs_to_free,funcretloc.registerhigh.number shr 8);
+                       exclude(regs_to_free,procdefinition.funcret_paraloc[callerside].registerlow.number shr 8);
+                       exclude(regs_to_free,procdefinition.funcret_paraloc[callerside].registerhigh.number shr 8);
                      end
                      end
                    else
                    else
 {$endif cpu64bit}
 {$endif cpu64bit}
-                     exclude(regs_to_free,funcretloc.register.number shr 8);
+                     exclude(regs_to_free,procdefinition.funcret_paraloc[callerside].register.number shr 8);
                  end;
                  end;
              end;
              end;
            end;
            end;
@@ -1147,7 +1192,6 @@ implementation
          pushedint : tpushedsavedint;
          pushedint : tpushedsavedint;
          pushedregs : tmaybesave;
          pushedregs : tmaybesave;
       {$endif}
       {$endif}
-         funcretloc: tparalocation;
          oldpushedparasize : longint;
          oldpushedparasize : longint;
          { adress returned from an I/O-error }
          { adress returned from an I/O-error }
          iolabel : tasmlabel;
          iolabel : tasmlabel;
@@ -1314,22 +1358,20 @@ implementation
            used for the return value }
            used for the return value }
          regs_to_push_int := tprocdef(procdefinition).usedintregisters;
          regs_to_push_int := tprocdef(procdefinition).usedintregisters;
          regs_to_push_other := tprocdef(procdefinition).usedotherregisters;
          regs_to_push_other := tprocdef(procdefinition).usedotherregisters;
-         if (not is_void(resulttype.def)) and
-            not(paramanager.ret_in_param(resulttype.def,procdefinition.proccalloption)) then
+         if (not is_void(resulttype.def)) then
            begin
            begin
-             funcretloc := paramanager.getfuncretparaloc(procdefinition);
-             case funcretloc.loc of
+             case procdefinition.funcret_paraloc[callerside].loc of
                LOC_REGISTER,LOC_CREGISTER:
                LOC_REGISTER,LOC_CREGISTER:
                  begin
                  begin
 {$ifndef cpu64bit}
 {$ifndef cpu64bit}
-                   if funcretloc.size in [OS_S64,OS_64] then
+                   if procdefinition.funcret_paraloc[callerside].size in [OS_S64,OS_64] then
                      begin
                      begin
-                       include(regs_to_push_int,funcretloc.registerlow.number shr 8);
-                       include(regs_to_push_int,funcretloc.registerhigh.number shr 8);
+                       include(regs_to_push_int,procdefinition.funcret_paraloc[callerside].registerlow.number shr 8);
+                       include(regs_to_push_int,procdefinition.funcret_paraloc[callerside].registerhigh.number shr 8);
                      end
                      end
                    else
                    else
 {$endif cpu64bit}
 {$endif cpu64bit}
-                    include(regs_to_push_int,funcretloc.register.number shr 8);
+                    include(regs_to_push_int,procdefinition.funcret_paraloc[callerside].register.number shr 8);
                  end;
                  end;
              end;
              end;
            end;
            end;
@@ -1541,7 +1583,10 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.104  2003-08-11 14:22:06  mazen
+  Revision 1.105  2003-08-11 21:18:20  peter
+    * start of sparc support for newra
+
+  Revision 1.104  2003/08/11 14:22:06  mazen
   - dupplicated code removed
   - dupplicated code removed
 
 
   Revision 1.103  2003/07/23 11:01:14  jonas
   Revision 1.103  2003/07/23 11:01:14  jonas
@@ -1573,7 +1618,7 @@ end.
      * fixed ppc cycle
      * fixed ppc cycle
 
 
   Revision 1.96  2003/07/02 22:18:04  peter
   Revision 1.96  2003/07/02 22:18:04  peter
-    * paraloc splitted in callerparaloc,calleeparaloc
+    * paraloc splitted in paraloc[callerside],calleeparaloc
     * sparc calling convention updates
     * sparc calling convention updates
 
 
   Revision 1.95  2003/06/17 16:34:44  jonas
   Revision 1.95  2003/06/17 16:34:44  jonas

+ 7 - 4
compiler/ncgutil.pas

@@ -1636,14 +1636,14 @@ implementation
                   internalerror(200301081);
                   internalerror(200301081);
                 if (tvarsym(hp.parasym).reg.enum<>R_NO) then
                 if (tvarsym(hp.parasym).reg.enum<>R_NO) then
                   begin
                   begin
-                    cg.a_load_param_reg(list,hp.calleeparaloc,tvarsym(hp.parasym).reg);
+                    cg.a_load_param_reg(list,hp.paraloc[calleeside],tvarsym(hp.parasym).reg);
                   end
                   end
-                else if (hp.calleeparaloc.loc in [LOC_REGISTER,LOC_FPUREGISTER,LOC_MMREGISTER,
+                else if (hp.paraloc[calleeside].loc in [LOC_REGISTER,LOC_FPUREGISTER,LOC_MMREGISTER,
                                             LOC_CREGISTER,LOC_CFPUREGISTER,LOC_CMMREGISTER]) and
                                             LOC_CREGISTER,LOC_CFPUREGISTER,LOC_CMMREGISTER]) and
                         (tvarsym(hp.parasym).reg.enum=R_NO) then
                         (tvarsym(hp.parasym).reg.enum=R_NO) then
                   begin
                   begin
                     reference_reset_base(href,current_procinfo.framepointer,tvarsym(hp.parasym).adjusted_address);
                     reference_reset_base(href,current_procinfo.framepointer,tvarsym(hp.parasym).adjusted_address);
-                    cg.a_load_param_ref(list,hp.calleeparaloc,href);
+                    cg.a_load_param_ref(list,hp.paraloc[calleeside],href);
                   end;
                   end;
                 hp:=tparaitem(hp.next);
                 hp:=tparaitem(hp.next);
               end;
               end;
@@ -2030,7 +2030,10 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.133  2003-08-09 18:56:54  daniel
+  Revision 1.134  2003-08-11 21:18:20  peter
+    * start of sparc support for newra
+
+  Revision 1.133  2003/08/09 18:56:54  daniel
     * cs_regalloc renamed to cs_regvars to avoid confusion with register
     * cs_regalloc renamed to cs_regvars to avoid confusion with register
       allocator
       allocator
     * Some preventive changes to i386 spillinh code
     * Some preventive changes to i386 spillinh code

+ 25 - 113
compiler/paramgr.pas

@@ -35,7 +35,6 @@ unit paramgr;
        symconst,symtype,symdef;
        symconst,symtype,symdef;
 
 
     type
     type
-       tcallercallee = (callerside,calleeside);
        {# This class defines some methods to take care of routine
        {# This class defines some methods to take care of routine
           parameters. It should be overriden for each new processor
           parameters. It should be overriden for each new processor
        }
        }
@@ -100,33 +99,18 @@ unit paramgr;
           }
           }
           procedure create_paraloc_info(p : tabstractprocdef; side: tcallercallee);virtual;abstract;
           procedure create_paraloc_info(p : tabstractprocdef; side: tcallercallee);virtual;abstract;
 
 
-          {
-            Returns the location where the invisible parameter for structured
-            function results will be passed.
-          }
-          function getfuncretparaloc(p : tabstractprocdef) : tparalocation;virtual;
-
-          {
-            Returns the location where the invisible parameter for nested
-            subroutines is passed.
-          }
-          function getframepointerloc(p : tabstractprocdef) : tparalocation;virtual;
-
           { Returns the self pointer location for the given tabstractprocdef,
           { Returns the self pointer location for the given tabstractprocdef,
             when the stack frame is already created. This is used by the code
             when the stack frame is already created. This is used by the code
             generating the wrappers for implemented interfaces.
             generating the wrappers for implemented interfaces.
           }
           }
           function getselflocation(p : tabstractprocdef) : tparalocation;virtual;abstract;
           function getselflocation(p : tabstractprocdef) : tparalocation;virtual;abstract;
 
 
-          {
-            Returns the location of the result if the result is in
-            a register, the register(s) return depend on the type of
-            the result.
-
-            @param(def The definition of the result type of the function)
-          }
-          function getfuncresultloc(def : tdef;calloption:tproccalloption): tparalocation;virtual;
+          { Return the location of the low and high part of a 64bit parameter }
           procedure splitparaloc64(const locpara:tparalocation;var loclopara,lochipara:tparalocation);virtual;
           procedure splitparaloc64(const locpara:tparalocation;var loclopara,lochipara:tparalocation);virtual;
+
+{$ifdef usetempparaloc}
+          procedure alloctempregs(list: taasmoutput;var locpara:tparalocation);virtual;
+{$endif usetempparaloc}
        end;
        end;
 
 
 
 
@@ -312,97 +296,6 @@ implementation
       end;
       end;
 
 
 
 
-    function tparamanager.getfuncretparaloc(p : tabstractprocdef) : tparalocation;
-      begin
-         result.loc:=LOC_REFERENCE;
-         result.size:=OS_ADDR;
-         result.sp_fixup:=pointer_size;
-         result.reference.index.enum:=R_INTREGISTER;
-         result.reference.index.number:=NR_STACK_POINTER_REG;
-         result.reference.offset:=0;
-      end;
-
-
-    function tparamanager.getframepointerloc(p : tabstractprocdef) : tparalocation;
-      begin
-         result.loc:=LOC_REFERENCE;
-         result.size:=OS_ADDR;
-         result.sp_fixup:=pointer_size;
-         result.reference.index.enum:=R_INTREGISTER;
-         result.reference.index.number:=NR_STACK_POINTER_REG;
-         result.reference.offset:=0;
-      end;
-
-
-    function tparamanager.getfuncresultloc(def : tdef;calloption:tproccalloption): tparalocation;
-      begin
-         fillchar(result,sizeof(tparalocation),0);
-         if is_void(def) then exit;
-
-         result.size := def_cgsize(def);
-         case def.deftype of
-           orddef,
-           enumdef :
-             begin
-               result.loc := LOC_REGISTER;
-{$ifndef cpu64bit}
-               if result.size in [OS_64,OS_S64] then
-                begin
-                  result.register64.reglo.enum:=R_INTREGISTER;
-                  result.register64.reglo.number:=NR_FUNCTION_RETURN64_LOW_REG;
-                  result.register64.reghi.enum:=R_INTREGISTER;
-                  result.register64.reghi.number:=NR_FUNCTION_RETURN64_HIGH_REG;
-                end
-               else
-{$endif cpu64bit}
-                begin
-                  result.register.enum:=R_INTREGISTER;
-                  result.register.number:=NR_FUNCTION_RETURN_REG;
-                end;
-             end;
-           floatdef :
-             begin
-               result.loc := LOC_FPUREGISTER;
-{$ifdef cpufpemu}
-               if cs_fp_emulation in aktmoduleswitches then
-                 begin
-                   result.register.enum:=R_INTREGISTER;
-                   result.register.number:=FUNCTION_RETURN_REG;
-                 end
-               else
-{$endif cpufpemu}
-                 result.register.enum := FPU_RESULT_REG;
-             end;
-          else
-             begin
-                if not ret_in_param(def,calloption) then
-                  begin
-                    result.loc := LOC_REGISTER;
-                    result.register.enum:=R_INTREGISTER;
-                    result.register.number:=NR_FUNCTION_RETURN_REG;
-                  end
-                else
-                   begin
-                     result.loc := LOC_REFERENCE;
-                     internalerror(2002081602);
-(*
-{$ifdef EXTDEBUG}
-                     { it is impossible to have the
-                       return value with an index register
-                       and a symbol!
-                     }
-                     if (ref.index <> R_NO) or (assigned(ref.symbol)) then
-                        internalerror(2002081602);
-{$endif}
-                     result.reference.index := ref.base;
-                     result.reference.offset := ref.offset;
-*)
-                   end;
-             end;
-          end;
-      end;
-
-
     procedure tparamanager.splitparaloc64(const locpara:tparalocation;var loclopara,lochipara:tparalocation);
     procedure tparamanager.splitparaloc64(const locpara:tparalocation;var loclopara,lochipara:tparalocation);
       begin
       begin
         if not(locpara.size in [OS_64,OS_S64]) then
         if not(locpara.size in [OS_64,OS_S64]) then
@@ -433,6 +326,22 @@ implementation
       end;
       end;
 
 
 
 
+{$ifdef usetempparaloc}
+    procedure tparamanager.alloctempregs(list: taasmoutput;var locpara:tparalocation);
+      begin
+        if locpara.loc<>LOC_REGISTER then
+          internalerror(200308123);
+{$ifndef cpu64bit}
+        if locpara.size in [OS_64,OS_S64] then
+          begin
+            locpara.registerlow:=rg.getregisterint(list,OS_32);
+            locpara.registerhigh:=rg.getregisterint(list,OS_32);
+          end
+        else
+{$endif cpu64bit}
+          locpara.register:=rg.getregisterint(list,locpara.size);
+      end;
+{$endif usetempparaloc}
 
 
 
 
 initialization
 initialization
@@ -443,7 +352,10 @@ end.
 
 
 {
 {
    $Log$
    $Log$
-   Revision 1.49  2003-07-08 21:24:59  peter
+   Revision 1.50  2003-08-11 21:18:20  peter
+     * start of sparc support for newra
+
+   Revision 1.49  2003/07/08 21:24:59  peter
      * sparc fixes
      * sparc fixes
 
 
    Revision 1.48  2003/07/05 20:11:41  jonas
    Revision 1.48  2003/07/05 20:11:41  jonas

+ 8 - 3
compiler/pass_2.pas

@@ -164,7 +164,9 @@ implementation
          prevp : pptree;
          prevp : pptree;
 {$endif TEMPREGDEBUG}
 {$endif TEMPREGDEBUG}
 {$ifdef EXTDEBUG}
 {$ifdef EXTDEBUG}
+{$ifndef newra}
          i : longint;
          i : longint;
+{$endif newra}
 {$endif EXTDEBUG}
 {$endif EXTDEBUG}
       begin
       begin
          if not assigned(p) then
          if not assigned(p) then
@@ -205,9 +207,11 @@ implementation
              end;
              end;
 
 
 {$ifdef newra}
 {$ifdef newra}
+  {$ifdef i386}
             if rg.unusedregsint*([first_supreg..last_supreg] - [RS_FRAME_POINTER_REG,RS_STACK_POINTER_REG])<>
             if rg.unusedregsint*([first_supreg..last_supreg] - [RS_FRAME_POINTER_REG,RS_STACK_POINTER_REG])<>
                                 ([first_supreg..last_supreg] - [RS_FRAME_POINTER_REG,RS_STACK_POINTER_REG]) then
                                 ([first_supreg..last_supreg] - [RS_FRAME_POINTER_REG,RS_STACK_POINTER_REG]) then
               internalerror(200306171);
               internalerror(200306171);
+  {$endif}
 {$else}
 {$else}
             { check if all scratch registers are freed }
             { check if all scratch registers are freed }
             for i:=1 to max_scratch_regs do
             for i:=1 to max_scratch_regs do
@@ -280,8 +284,6 @@ implementation
               { assign parameter locations }
               { assign parameter locations }
               current_procinfo.after_pass1;
               current_procinfo.after_pass1;
 
 
-              { callee paraloc register info is necessary for regvars }
-              paramanager.create_paraloc_info(current_procinfo.procdef,calleeside);
               { caller paraloc info is also necessary in the stackframe_entry }
               { caller paraloc info is also necessary in the stackframe_entry }
               { code of the ppc (and possibly other processors)               }
               { code of the ppc (and possibly other processors)               }
               if not current_procinfo.procdef.has_paraloc_info then
               if not current_procinfo.procdef.has_paraloc_info then
@@ -315,7 +317,10 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.62  2003-08-10 17:25:23  peter
+  Revision 1.63  2003-08-11 21:18:20  peter
+    * start of sparc support for newra
+
+  Revision 1.62  2003/08/10 17:25:23  peter
     * fixed some reported bugs
     * fixed some reported bugs
 
 
   Revision 1.61  2003/07/06 17:58:22  peter
   Revision 1.61  2003/07/06 17:58:22  peter

+ 22 - 64
compiler/powerpc/aasmcpu.pas

@@ -82,12 +82,14 @@ uses
 
 
          function is_nop: boolean; override;
          function is_nop: boolean; override;
          function is_move:boolean; override;
          function is_move:boolean; override;
+{$ifdef newra}
          function spill_registers(list:Taasmoutput;
          function spill_registers(list:Taasmoutput;
                                   rgget:Trggetproc;
                                   rgget:Trggetproc;
                                   rgunget:Trgungetproc;
                                   rgunget:Trgungetproc;
                                   r:Tsupregset;
                                   r:Tsupregset;
                                   var unusedregsint:Tsupregset;
                                   var unusedregsint:Tsupregset;
                                   const spilltemplist:Tspill_temp_list):boolean; override;
                                   const spilltemplist:Tspill_temp_list):boolean; override;
+{$endif}
 
 
 
 
       end;
       end;
@@ -416,7 +418,8 @@ uses cutils,rgobj;
     function taicpu.is_nop: boolean;
     function taicpu.is_nop: boolean;
       begin
       begin
         { we don't insert any more nops than necessary }
         { we don't insert any more nops than necessary }
-        is_nop := false;
+        is_nop :=
+          ((opcode=A_MR) and (oper[0].typ=top_reg) and (oper[1].typ=top_reg) and (oper[0].reg.number=oper[1].reg.number));
       end;
       end;
 
 
 
 
@@ -426,68 +429,16 @@ uses cutils,rgobj;
       end;
       end;
 
 
 
 
-    function taicpu.spill_registers(list:Taasmoutput; 
-                             rgget:Trggetproc; 
-                             rgunget:Trgungetproc; 
-                             r:Tsupregset; 
-                             var unusedregsint:Tsupregset; 
+{$ifdef newra}
+    function taicpu.spill_registers(list:Taasmoutput;
+                             rgget:Trggetproc;
+                             rgunget:Trgungetproc;
+                             r:Tsupregset;
+                             var unusedregsint:Tsupregset;
                               const spilltemplist:Tspill_temp_list): boolean;
                               const spilltemplist:Tspill_temp_list): boolean;
 
 
-      function get_insert_pos(p:Tai;huntfor1,huntfor2,huntfor3:Tsuperregister):Tai;
+      function decode_loadstore(op: tasmop; var counterpart: tasmop; var wasload: boolean): boolean;
 
 
-      var back:Tsupregset;
-
-      begin
-        back:=unusedregsint;
-        get_insert_pos:=p;
-        while (p<>nil) and (p.typ=ait_regalloc) do
-          begin
-            {Rewind the register allocation.}
-            if Tai_regalloc(p).allocation then
-              include(unusedregsint,Tai_regalloc(p).reg.number shr 8)
-            else
-              begin
-                exclude(unusedregsint,Tai_regalloc(p).reg.number shr 8);
-                if Tai_regalloc(p).reg.number shr 8=huntfor1 then
-                  begin
-                    get_insert_pos:=Tai(p.previous);
-                    back:=unusedregsint;
-                  end;
-                if Tai_regalloc(p).reg.number shr 8=huntfor2 then
-                  begin
-                    get_insert_pos:=Tai(p.previous);
-                    back:=unusedregsint;
-                  end;
-                if Tai_regalloc(p).reg.number shr 8=huntfor3 then
-                  begin
-                    get_insert_pos:=Tai(p.previous);
-                    back:=unusedregsint;
-                  end;
-              end;
-            p:=Tai(p.previous);
-          end;
-        unusedregsint:=back;
-      end;
-
-      procedure forward_allocation(p:Tai);
-
-      begin
-        {Forward the register allocation again.}
-        while (p<>self) do
-          begin
-            if p.typ<>ait_regalloc then
-              internalerror(200305311);
-            if Tai_regalloc(p).allocation then
-              exclude(unusedregsint,Tai_regalloc(p).reg.number shr 8)
-            else
-              include(unusedregsint,Tai_regalloc(p).reg.number shr 8);
-            p:=Tai(p.next);
-          end;
-      end;
-
-
-      function decode_loadstore(op: tasmop; var counterpart: tasmop; wasload: boolean): boolean;
-     
         begin
         begin
           result := true;
           result := true;
           wasload := true;
           wasload := true;
@@ -591,7 +542,7 @@ uses cutils,rgobj;
                 //
                 //
                 //   l?? r21d, -60(r1)
                 //   l?? r21d, -60(r1)
                 //   st? r21d, 8(r1)
                 //   st? r21d, 8(r1)
-  
+
                 pos := get_insert_pos(Tai(previous),oper[0].reg.number shr 8,
                 pos := get_insert_pos(Tai(previous),oper[0].reg.number shr 8,
                                       oper[1].ref^.base.number shr 8,oper[1].ref^.index.number shr 8);
                                       oper[1].ref^.base.number shr 8,oper[1].ref^.index.number shr 8);
                 rgget(list,pos,0,helpreg);
                 rgget(list,pos,0,helpreg);
@@ -720,7 +671,7 @@ uses cutils,rgobj;
         for i := 1 to 2 do
         for i := 1 to 2 do
           if (oper[i].typ = top_reg) then
           if (oper[i].typ = top_reg) then
             begin
             begin
-              supreg:=oper[i].reg.number;
+              supreg:=oper[i].reg.number shr 8;
               if supreg in r then
               if supreg in r then
                 begin
                 begin
                   // Example:
                   // Example:
@@ -731,7 +682,7 @@ uses cutils,rgobj;
                   //   lwz r23d, -60(r1)
                   //   lwz r23d, -60(r1)
                   //   add r23d, r21d, r22d
                   //   add r23d, r21d, r22d
                   //   stw r23d, -60(r1)
                   //   stw r23d, -60(r1)
-      
+
                   pos := get_insert_pos(Tai(previous),reg1,reg2,reg3);
                   pos := get_insert_pos(Tai(previous),reg1,reg2,reg3);
                   rgget(list,pos,0,helpreg);
                   rgget(list,pos,0,helpreg);
                   spill_registers := true;
                   spill_registers := true;
@@ -750,6 +701,7 @@ uses cutils,rgobj;
                 end;
                 end;
             end;
             end;
       end;
       end;
+{$endif newra}
 
 
 
 
 
 
@@ -765,7 +717,13 @@ uses cutils,rgobj;
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.11  2003-07-23 10:58:06  jonas
+  Revision 1.13  2003-08-11 21:18:20  peter
+    * start of sparc support for newra
+
+  Revision 1.12  2002/09/30 23:16:49  jonas
+    * is_nop() now identifies "mr rA,rA" instructions for removal
+
+  Revision 1.11  2003/07/23 10:58:06  jonas
     - disabled some debugging code
     - disabled some debugging code
 
 
   Revision 1.10  2003/07/06 21:26:06  jonas
   Revision 1.10  2003/07/06 21:26:06  jonas

+ 7 - 4
compiler/powerpc/cgcpu.pas

@@ -1212,11 +1212,11 @@ const
                 hp:=tparaitem(current_procinfo.procdef.para.first);
                 hp:=tparaitem(current_procinfo.procdef.para.first);
                 while assigned(hp) do
                 while assigned(hp) do
                   begin
                   begin
-                    if (hp.calleeparaloc.loc in [LOC_REFERENCE,LOC_CREFERENCE]) then
+                    if (hp.paraloc[calleeside].loc in [LOC_REFERENCE,LOC_CREFERENCE]) then
                       begin
                       begin
                         reference_reset_base(href,current_procinfo.framepointer,tvarsym(hp.parasym).adjusted_address);
                         reference_reset_base(href,current_procinfo.framepointer,tvarsym(hp.parasym).adjusted_address);
-                        reference_reset_base(href2,r,hp.callerparaloc.reference.offset);
-                        cg.a_load_ref_ref(list,hp.calleeparaloc.size,hp.calleeparaloc.size,href2,href);
+                        reference_reset_base(href2,r,hp.paraloc[callerside].reference.offset);
+                        cg.a_load_ref_ref(list,hp.paraloc[calleeside].size,hp.paraloc[calleeside].size,href2,href);
                       end;
                       end;
                     hp := tparaitem(hp.next);
                     hp := tparaitem(hp.next);
                   end;
                   end;
@@ -2672,7 +2672,10 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.118  2003-08-08 15:50:45  olle
+  Revision 1.119  2003-08-11 21:18:20  peter
+    * start of sparc support for newra
+
+  Revision 1.118  2003/08/08 15:50:45  olle
     * merged macos entry/exit code generation into the general one.
     * merged macos entry/exit code generation into the general one.
 
 
   Revision 1.117  2002/10/01 05:24:28  olle
   Revision 1.117  2002/10/01 05:24:28  olle

+ 41 - 63
compiler/powerpc/cpupara.pas

@@ -39,7 +39,6 @@ unit cpupara;
           function getintparaloc(list: taasmoutput; nr : longint) : tparalocation;override;
           function getintparaloc(list: taasmoutput; nr : longint) : tparalocation;override;
           procedure freeintparaloc(list: taasmoutput; nr : longint); override;
           procedure freeintparaloc(list: taasmoutput; nr : longint); override;
           procedure create_paraloc_info(p : tabstractprocdef; side: tcallercallee);override;
           procedure create_paraloc_info(p : tabstractprocdef; side: tcallercallee);override;
-          function getfuncretparaloc(p : tabstractprocdef) : tparalocation;override;
        end;
        end;
 
 
   implementation
   implementation
@@ -247,9 +246,9 @@ unit cpupara;
                       if nextintreg.number<=(NR_R10-ord(is_64bit)*(NR_R1-NR_R0))  then
                       if nextintreg.number<=(NR_R10-ord(is_64bit)*(NR_R1-NR_R0))  then
                         begin
                         begin
                            paraloc.loc:=LOC_REGISTER;
                            paraloc.loc:=LOC_REGISTER;
-		           if is_64bit then
+                           if is_64bit then
                              begin
                              begin
-			       if odd((nextintreg.number-NR_R3) shr 8) and (target_info.abi=abi_powerpc_sysv) Then
+                               if odd((nextintreg.number-NR_R3) shr 8) and (target_info.abi=abi_powerpc_sysv) Then
                                 inc(nextintreg.number,NR_R1-NR_R0);
                                 inc(nextintreg.number,NR_R1-NR_R0);
                                paraloc.registerhigh:=nextintreg;
                                paraloc.registerhigh:=nextintreg;
                                inc(nextintreg.number,NR_R1-NR_R0);
                                inc(nextintreg.number,NR_R1-NR_R0);
@@ -312,81 +311,60 @@ unit cpupara;
                  else
                  else
                    internalerror(2002071002);
                    internalerror(2002071002);
               end;
               end;
-              if side = callerside then
-                hp.callerparaloc:=paraloc
-              else
+              if side = calleeside then
                 begin
                 begin
                   if (paraloc.loc = LOC_REFERENCE) then
                   if (paraloc.loc = LOC_REFERENCE) then
                     paraloc.reference.offset := tvarsym(hp.parasym).adjusted_address;
                     paraloc.reference.offset := tvarsym(hp.parasym).adjusted_address;
-                  hp.calleeparaloc:=paraloc;
                 end;
                 end;
+              hp.paraloc[side]:=paraloc;
               hp:=tparaitem(hp.next);
               hp:=tparaitem(hp.next);
            end;
            end;
-      end;
-
 
 
-    function tppcparamanager.getfuncretparaloc(p : tabstractprocdef) : tparalocation;
-      begin
-         fillchar(result,sizeof(result),0);
-         case p.rettype.def.deftype of
-            orddef,
-            enumdef:
-              begin
-                getfuncretparaloc.loc:=LOC_REGISTER;
-                getfuncretparaloc.register.enum:=R_INTREGISTER;
-                getfuncretparaloc.register.number:=NR_R3;
-                getfuncretparaloc.size:=def_cgsize(p.rettype.def);
-                if getfuncretparaloc.size in [OS_S64,OS_64] then
-                  begin
-                    getfuncretparaloc.registerhigh.enum:=R_INTREGISTER;
-                    getfuncretparaloc.registerhigh.number:=NR_R3;
-		    getfuncretparaloc.register.number:=NR_R4;
-                  end;
-              end;
-            floatdef:
-              begin
-                getfuncretparaloc.loc:=LOC_FPUREGISTER;
-                getfuncretparaloc.register.enum:=R_F1;
-                getfuncretparaloc.size:=def_cgsize(p.rettype.def);
-              end;
-            { smallsets are OS_INT in R3, others are OS_ADDR in R3 -> the same }
-            { ugly, I know :) (JM)                                             }
-            setdef,
-            variantdef,
-            pointerdef,
-            formaldef,
-            classrefdef,
-            recorddef,
-            objectdef,
-            procvardef,
-            filedef,
-            arraydef,
-            stringdef:
-              begin
-                if (p.rettype.def.deftype <> stringdef) or
-                   (is_ansistring(p.rettype.def) or
-                    is_widestring(p.rettype.def)) then
-                  begin
-                    getfuncretparaloc.loc:=LOC_REGISTER;
-                    getfuncretparaloc.register.enum:=R_INTREGISTER;
-                    getfuncretparaloc.register.number:=NR_R3;
-                    getfuncretparaloc.size:=OS_ADDR;
-                  end
-                else
-                  internalerror(2003061601);
-              end;
+        { Function return }
+        fillchar(paraloc,sizeof(tparalocation),0);
+        paraloc.size:=def_cgsize(p.rettype.def);
+        { Return in FPU register? }
+        if p.rettype.def.deftype=floatdef then
+          begin
+            paraloc.loc:=LOC_FPUREGISTER;
+            paraloc.register.enum:=FPU_RESULT_REG;
+          end
+        else
+         { Return in register? }
+         if not ret_in_param(p.rettype.def,p.proccalloption) then
+          begin
+            paraloc.loc:=LOC_REGISTER;
+{$ifndef cpu64bit}
+            if paraloc.size in [OS_64,OS_S64] then
+             begin
+               paraloc.register64.reglo.enum:=R_INTREGISTER;
+               paraloc.register64.reglo.number:=NR_FUNCTION_RETURN64_LOW_REG;
+               paraloc.register64.reghi.enum:=R_INTREGISTER;
+               paraloc.register64.reghi.number:=NR_FUNCTION_RETURN64_HIGH_REG;
+             end
             else
             else
-              internalerror(2002090903);
-        end;
+{$endif cpu64bit}
+             begin
+               paraloc.register.enum:=R_INTREGISTER;
+               paraloc.register.number:=NR_FUNCTION_RETURN_REG;
+             end;
+          end
+        else
+          begin
+            paraloc.loc:=LOC_REFERENCE;
+          end;
+        p.funcret_paraloc[side]:=paraloc;
       end;
       end;
 
 
-
 begin
 begin
    paramanager:=tppcparamanager.create;
    paramanager:=tppcparamanager.create;
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.41  2003-07-05 20:11:41  jonas
+  Revision 1.42  2003-08-11 21:18:20  peter
+    * start of sparc support for newra
+
+  Revision 1.41  2003/07/05 20:11:41  jonas
     * create_paraloc_info() is now called separately for the caller and
     * create_paraloc_info() is now called separately for the caller and
       callee info
       callee info
     * fixed ppc cycle
     * fixed ppc cycle

+ 10 - 7
compiler/regvars.pas

@@ -183,15 +183,15 @@ implementation
                   hp:=tparaitem(current_procinfo.procdef.para.first);
                   hp:=tparaitem(current_procinfo.procdef.para.first);
                   while assigned(hp) do
                   while assigned(hp) do
                     begin
                     begin
-                      if (hp.calleeparaloc.loc in [LOC_REGISTER,LOC_FPUREGISTER,
+                      if (hp.paraloc[calleeside].loc in [LOC_REGISTER,LOC_FPUREGISTER,
                             LOC_CREGISTER,LOC_CFPUREGISTER]) and
                             LOC_CREGISTER,LOC_CFPUREGISTER]) and
-                         (TCGSize2Size[hp.calleeparaloc.size] <= sizeof(aword)) then
+                         (TCGSize2Size[hp.paraloc[calleeside].size] <= sizeof(aword)) then
                         begin
                         begin
-                          tvarsym(hp.parasym).reg := hp.calleeparaloc.register;
-                          if (hp.calleeparaloc.loc in [LOC_REGISTER,LOC_CREGISTER]) then
-                            rg.makeregvarint(hp.calleeparaloc.register.number shr 8)
+                          tvarsym(hp.parasym).reg := hp.paraloc[calleeside].register;
+                          if (hp.paraloc[calleeside].loc in [LOC_REGISTER,LOC_CREGISTER]) then
+                            rg.makeregvarint(hp.paraloc[calleeside].register.number shr 8)
                           else
                           else
-                            rg.makeregvarother(hp.calleeparaloc.register);
+                            rg.makeregvarother(hp.paraloc[calleeside].register);
                         end
                         end
                       else
                       else
                         begin
                         begin
@@ -616,7 +616,10 @@ end.
 
 
 {
 {
   $Log$
   $Log$
-  Revision 1.59  2003-08-09 18:56:54  daniel
+  Revision 1.60  2003-08-11 21:18:20  peter
+    * start of sparc support for newra
+
+  Revision 1.59  2003/08/09 18:56:54  daniel
     * cs_regalloc renamed to cs_regvars to avoid confusion with register
     * cs_regalloc renamed to cs_regvars to avoid confusion with register
       allocator
       allocator
     * Some preventive changes to i386 spillinh code
     * Some preventive changes to i386 spillinh code

+ 248 - 1
compiler/sparc/aasmcpu.pas

@@ -59,8 +59,16 @@ uses
          constructor op_cond_sym(op : tasmop;cond:TAsmCond;_op1 : tasmsymbol);
          constructor op_cond_sym(op : tasmop;cond:TAsmCond;_op1 : tasmsymbol);
          constructor op_sym(op : tasmop;_op1 : tasmsymbol);
          constructor op_sym(op : tasmop;_op1 : tasmsymbol);
          constructor op_sym_ofs(op : tasmop;_op1 : tasmsymbol;_op1ofs:longint);
          constructor op_sym_ofs(op : tasmop;_op1 : tasmsymbol;_op1ofs:longint);
+
+         { register allocation }
          function is_nop:boolean;override;
          function is_nop:boolean;override;
          function is_move:boolean;override;
          function is_move:boolean;override;
+         function spill_registers(list:Taasmoutput;
+                                  rgget:Trggetproc;
+                                  rgunget:Trgungetproc;
+                                  r:Tsupregset;
+                                  var unusedregsint:Tsupregset;
+                                  const spilltemplist:Tspill_temp_list):boolean; override;
       end;
       end;
 
 
       tai_align = class(tai_align_abstract)
       tai_align = class(tai_align_abstract)
@@ -250,6 +258,242 @@ implementation
       end;
       end;
 
 
 
 
+    function taicpu.spill_registers(list:Taasmoutput;
+                             rgget:Trggetproc;
+                             rgunget:Trgungetproc;
+                             r:Tsupregset;
+                             var unusedregsint:Tsupregset;
+                              const spilltemplist:Tspill_temp_list): boolean;
+
+      function decode_loadstore(op: tasmop; var counterpart: tasmop; var wasload: boolean): boolean;
+
+        begin
+          result := true;
+          wasload := true;
+          case op of
+            A_LDSB,
+            A_LDUB :
+              begin
+                counterpart := A_STB;
+              end;
+            A_LDSH,
+            A_LDUH:
+              begin
+                counterpart := A_STH;
+              end;
+            A_LD :
+              begin
+                counterpart := A_ST;
+                wasload := false;
+              end;
+            A_LDD:
+              begin
+                counterpart := A_STD;
+                wasload := false;
+              end;
+            else
+              result := false;
+          end;
+       end;
+
+
+    var i:byte;
+        supreg, reg1, reg2, reg3: Tsuperregister;
+        helpreg:Tregister;
+        helpins:Taicpu;
+        op:Tasmop;
+        pos:Tai;
+        wasload: boolean;
+
+      begin
+        spill_registers:=false;
+        if (ops = 2) and
+           (oper[1].typ=top_ref) and
+           { oper[1] can also be ref in case of "lis r3,symbol@ha" or so }
+           decode_loadstore(opcode,op,wasload) then
+          begin
+            { the register that's being stored/loaded }
+            supreg:=oper[0].reg.number shr 8;
+            if supreg in r then
+              begin
+                // Example:
+                //   l?? r20d, 8(r1)   ; r20d must be spilled into -60(r1)
+                //
+                //   Change into:
+                //
+                //   l?? r21d, 8(r1)
+                //   st? r21d, -60(r1)
+                //
+                // And:
+                //
+                //   st? r20d, 8(r1)   ; r20d must be spilled into -60(r1)
+                //
+                //   Change into:
+                //
+                //   l?? r21d, -60(r1)
+                //   st? r21d, 8(r1)
+
+                pos := get_insert_pos(Tai(previous),oper[0].reg.number shr 8,
+                                      oper[1].ref^.base.number shr 8,
+                                      oper[1].ref^.index.number shr 8,
+                                      unusedregsint);
+                rgget(list,pos,0,helpreg);
+                spill_registers := true;
+                if wasload then
+                  begin
+                    helpins := taicpu.op_reg_ref(opcode,helpreg,oper[1].ref^);
+                    loadref(1,spilltemplist[supreg]);
+                    opcode := op;
+                  end
+                else
+                  helpins := taicpu.op_reg_ref(op,helpreg,spilltemplist[supreg]);
+                if pos=nil then
+                  list.insertafter(helpins,list.first)
+                else
+                  list.insertafter(helpins,pos.next);
+                loadreg(0,helpreg);
+                rgunget(list,helpins,helpreg);
+                forward_allocation(tai(helpins.next),unusedregsint);
+{
+                writeln('spilling!');
+                list.insertafter(tai_comment.Create(strpnew('Spilling!')),helpins);
+}
+              end;
+
+            { now the registers used in the reference }
+            { a) base                                 }
+            supreg := oper[1].ref^.base.number shr 8;
+            if supreg in r then
+              begin
+                if wasload then
+                  pos:=get_insert_pos(Tai(previous),oper[1].ref^.index.number shr 8,oper[0].reg.number shr 8,0,unusedregsint)
+                else
+                  pos:=get_insert_pos(Tai(previous),oper[1].ref^.index.number shr 8,0,0,unusedregsint);
+                rgget(list,pos,0,helpreg);
+                spill_registers:=true;
+                helpins:=Taicpu.op_reg_ref(A_LD,helpreg,spilltemplist[supreg]);
+                if pos=nil then
+                  list.insertafter(helpins,list.first)
+                else
+                  list.insertafter(helpins,pos.next);
+                oper[1].ref^.base:=helpreg;
+                rgunget(list,helpins,helpreg);
+                forward_allocation(Tai(helpins.next),unusedregsint);
+{
+                writeln('spilling!');
+                list.insertafter(tai_comment.Create(strpnew('Spilling!')),helpins);
+}
+              end;
+
+            { b) index }
+            supreg := oper[1].ref^.index.number shr 8;
+            if supreg in r then
+              begin
+                if wasload then
+                  pos:=get_insert_pos(Tai(previous),oper[1].ref^.base.number shr 8,oper[0].reg.number shr 8,0,unusedregsint)
+                else
+                  pos:=get_insert_pos(Tai(previous),oper[1].ref^.base.number shr 8,0,0,unusedregsint);
+                rgget(list,pos,0,helpreg);
+                spill_registers:=true;
+                helpins:=Taicpu.op_reg_ref(A_LD,helpreg,spilltemplist[supreg]);
+                if pos=nil then
+                  list.insertafter(helpins,list.first)
+                else
+                  list.insertafter(helpins,pos.next);
+                oper[1].ref^.index:=helpreg;
+                rgunget(list,helpins,helpreg);
+                forward_allocation(Tai(helpins.next),unusedregsint);
+{
+                writeln('spilling!');
+                list.insertafter(tai_comment.Create(strpnew('Spilling!')),helpins);
+}
+              end;
+            { load/store is done }
+            exit;
+          end;
+
+        { all other instructions the compiler generates are the same (I hope):   }
+        { operand 0 is a register and is the destination, the others are sources }
+        { and can be either registers or constants                               }
+        { exception: branches (is_jmp isn't always set for them)                 }
+        if oper[0].typ <> top_reg then
+          exit;
+        reg1 := oper[0].reg.number shr 8;
+        if oper[1].typ = top_reg then
+          reg2 := oper[1].reg.number shr 8
+        else
+          reg2 := 0;
+        if (ops >= 3) and
+           (oper[2].typ = top_reg) then
+          reg3 := oper[2].reg.number shr 8
+        else
+          reg3 := 0;
+
+        supreg:=reg1;
+        if supreg in r then
+          begin
+            // Example:
+            //   add r20d, r21d, r22d   ; r20d must be spilled into -60(r1)
+            //
+            //   Change into:
+            //
+            //   lwz r23d, -60(r1)
+            //   add r23d, r21d, r22d
+            //   stw r23d, -60(r1)
+
+            pos := get_insert_pos(Tai(previous),reg1,reg2,reg3,unusedregsint);
+            rgget(list,pos,0,helpreg);
+            spill_registers := true;
+            helpins := taicpu.op_reg_ref(A_ST,helpreg,spilltemplist[supreg]);
+            list.insertafter(helpins,self);
+            helpins := taicpu.op_reg_ref(A_LD,helpreg,spilltemplist[supreg]);
+            if pos=nil then
+              list.insertafter(helpins,list.first)
+            else
+              list.insertafter(helpins,pos.next);
+            loadreg(0,helpreg);
+            rgunget(list,helpins,helpreg);
+            forward_allocation(tai(helpins.next),unusedregsint);
+{
+            writeln('spilling!');
+            list.insertafter(tai_comment.Create(strpnew('Spilling!')),helpins);
+}
+          end;
+
+        for i := 1 to 2 do
+          if (oper[i].typ = top_reg) then
+            begin
+              supreg:=oper[i].reg.number shr 8;
+              if supreg in r then
+                begin
+                  // Example:
+                  //   add r20d, r21d, r22d   ; r20d must be spilled into -60(r1)
+                  //
+                  //   Change into:
+                  //
+                  //   lwz r23d, -60(r1)
+                  //   add r23d, r21d, r22d
+                  //   stw r23d, -60(r1)
+
+                  pos := get_insert_pos(Tai(previous),reg1,reg2,reg3,unusedregsint);
+                  rgget(list,pos,0,helpreg);
+                  spill_registers := true;
+                  helpins := taicpu.op_reg_ref(A_LD,helpreg,spilltemplist[supreg]);
+                  if pos=nil then
+                    list.insertafter(helpins,list.first)
+                  else
+                    list.insertafter(helpins,pos.next);
+                  loadreg(i,helpreg);
+                  rgunget(list,helpins,helpreg);
+                  forward_allocation(tai(helpins.next),unusedregsint);
+{
+                  writeln('spilling!');
+                  list.insertafter(tai_comment.Create(strpnew('Spilling!')),helpins);
+}
+                end;
+            end;
+      end;
+
     procedure InitAsm;
     procedure InitAsm;
       begin
       begin
       end;
       end;
@@ -262,7 +506,10 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.30  2003-06-14 14:53:50  jonas
+  Revision 1.31  2003-08-11 21:18:20  peter
+    * start of sparc support for newra
+
+  Revision 1.30  2003/06/14 14:53:50  jonas
     * fixed newra cycle for x86
     * fixed newra cycle for x86
     * added constants for indicating source and destination operands of the
     * added constants for indicating source and destination operands of the
       "move reg,reg" instruction to aasmcpu (and use those in rgobj)
       "move reg,reg" instruction to aasmcpu (and use those in rgobj)

+ 55 - 59
compiler/sparc/cpupara.pas

@@ -42,9 +42,6 @@ interface
         procedure allocparaloc(list: taasmoutput; const loc: tparalocation);override;
         procedure allocparaloc(list: taasmoutput; const loc: tparalocation);override;
         procedure freeparaloc(list: taasmoutput; const loc: tparalocation);override;
         procedure freeparaloc(list: taasmoutput; const loc: tparalocation);override;
         procedure create_paraloc_info(p:TAbstractProcDef; side: tcallercallee);override;
         procedure create_paraloc_info(p:TAbstractProcDef; side: tcallercallee);override;
-        {Returns the location where the invisible parameter for structured function
-        results will be passed.}
-        function GetFuncRetParaLoc(p:TAbstractProcDef):TParaLocation;override;
         procedure splitparaloc64(const locpara:tparalocation;var loclopara,lochipara:tparalocation);override;
         procedure splitparaloc64(const locpara:tparalocation;var loclopara,lochipara:tparalocation);override;
       end;
       end;
 
 
@@ -209,75 +206,71 @@ implementation
                 else
                 else
                   inc(stack_offset,4);
                   inc(stack_offset,4);
               end;
               end;
-            if side = callerside then
-              hp.callerparaloc:=paraloc
-            else
+            hp.paraloc[side]:=paraloc;
+            if side = calleeside then
               begin
               begin
                 { update callee paraloc and use Ix registers instead
                 { update callee paraloc and use Ix registers instead
                   of Ox registers }
                   of Ox registers }
-                hp.calleeparaloc:=paraloc;
-                if hp.calleeparaloc.loc=LOC_REGISTER then
+                if hp.paraloc[calleeside].loc=LOC_REGISTER then
                   begin
                   begin
                     { big endian }
                     { big endian }
                     if is_64bit then
                     if is_64bit then
-                      inc(hp.calleeparaloc.registerhigh.number,(RS_I0-RS_O0) shl 8);
-                    inc(hp.calleeparaloc.registerlow.number,(RS_I0-RS_O0) shl 8);
+                      inc(hp.paraloc[calleeside].registerhigh.number,(RS_I0-RS_O0) shl 8);
+                    inc(hp.paraloc[calleeside].registerlow.number,(RS_I0-RS_O0) shl 8);
                   end
                   end
                 else
                 else
                   begin
                   begin
-                    if hp.calleeparaloc.low_in_reg then
-                      inc(hp.calleeparaloc.lowreg.number,(RS_I0-RS_O0) shl 8);
-                    inc(hp.calleeparaloc.reference.index.number,(RS_I0-RS_O0) shl 8);
+                    if hp.paraloc[calleeside].low_in_reg then
+                      inc(hp.paraloc[calleeside].lowreg.number,(RS_I0-RS_O0) shl 8);
+                    inc(hp.paraloc[calleeside].reference.index.number,(RS_I0-RS_O0) shl 8);
                   end;
                   end;
               end;
               end;
             hp:=TParaItem(hp.Next);
             hp:=TParaItem(hp.Next);
           end;
           end;
-      end;
 
 
-
-    function tSparcParaManager.GetFuncRetParaLoc(p:TAbstractProcDef):TParaLocation;
-      begin
-        with GetFuncRetParaLoc do
-         begin
-           case p.rettype.def.deftype of
-             orddef,enumdef:
-               begin
-                 loc:=LOC_REGISTER;
-                 register.enum:=R_INTREGISTER;
-                 register.number:=NR_FUNCTION_RETURN_REG;
-                 size:=def_cgsize(p.rettype.def);
-                 if size in [OS_S64,OS_64] then
-                   internalerror(200305309);
-               end;
-             floatdef:
-               begin
-                 loc:=LOC_FPUREGISTER;
-                 register.enum:=R_F1;
-                 size:=def_cgsize(p.rettype.def);
-               end;
-             setdef,
-             variantdef,
-             pointerdef,
-             formaldef,
-             classrefdef,
-             recorddef,
-             objectdef,
-             stringdef,
-             procvardef,
-             filedef,
-             arraydef,
-             errordef:
-               begin
-                 loc:=LOC_REFERENCE;
-                 reference.index.enum:=R_INTREGISTER;
-                 reference.index.number:=NR_FRAME_POINTER_REG;
-                 reference.offset:=64;
-                 size:=OS_ADDR;
-               end;
-             else
-               internalerror(2002090903);
-           end;
-         end;
+        { Function return }
+        fillchar(paraloc,sizeof(tparalocation),0);
+        paraloc.size:=def_cgsize(p.rettype.def);
+        { Return in FPU register? }
+        if p.rettype.def.deftype=floatdef then
+          begin
+            paraloc.loc:=LOC_FPUREGISTER;
+            paraloc.register.enum:=FPU_RESULT_REG;
+          end
+        else
+         { Return in register? }
+         if not ret_in_param(p.rettype.def,p.proccalloption) then
+          begin
+            paraloc.loc:=LOC_REGISTER;
+{$ifndef cpu64bit}
+            if paraloc.size in [OS_64,OS_S64] then
+             begin
+               paraloc.register64.reglo.enum:=R_INTREGISTER;
+               if side=callerside then
+                 paraloc.register64.reglo.number:=NR_FUNCTION_RESULT64_LOW_REG
+               else
+                 paraloc.register64.reglo.number:=NR_FUNCTION_RETURN64_LOW_REG;
+               paraloc.register64.reghi.enum:=R_INTREGISTER;
+               if side=callerside then
+                 paraloc.register64.reghi.number:=NR_FUNCTION_RESULT64_HIGH_REG
+               else
+                 paraloc.register64.reghi.number:=NR_FUNCTION_RETURN64_HIGH_REG;
+             end
+            else
+{$endif cpu64bit}
+             begin
+               paraloc.register.enum:=R_INTREGISTER;
+               if side=callerside then
+                 paraloc.register.number:=NR_FUNCTION_RESULT_REG
+               else
+                 paraloc.register.number:=NR_FUNCTION_RETURN_REG;
+             end;
+          end
+        else
+          begin
+            paraloc.loc:=LOC_REFERENCE;
+          end;
+        p.funcret_paraloc[side]:=paraloc;
       end;
       end;
 
 
 
 
@@ -308,7 +301,10 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.26  2003-07-08 21:25:00  peter
+  Revision 1.27  2003-08-11 21:18:20  peter
+    * start of sparc support for newra
+
+  Revision 1.26  2003/07/08 21:25:00  peter
     * sparc fixes
     * sparc fixes
 
 
   Revision 1.25  2003/07/06 22:10:56  peter
   Revision 1.25  2003/07/06 22:10:56  peter

+ 14 - 4
compiler/sparc/rgcpu.pas

@@ -36,13 +36,16 @@ interface
 
 
     type
     type
       trgcpu=class(trgobj)
       trgcpu=class(trgobj)
-        function GetRegisterFpu(list:TAasmOutput;size:Tcgsize):TRegister;override;
+{$ifndef NEWRA}
+      private
+        UsedParaRegs: TSupRegSet;
+      public
         function GetExplicitRegisterInt(list:taasmoutput;Reg:Tnewregister):tregister;override;
         function GetExplicitRegisterInt(list:taasmoutput;Reg:Tnewregister):tregister;override;
         procedure UngetregisterInt(list:taasmoutput;Reg:tregister);override;
         procedure UngetregisterInt(list:taasmoutput;Reg:tregister);override;
+{$endif NEWRA}
+        function GetRegisterFpu(list:TAasmOutput;size:Tcgsize):TRegister;override;
         procedure UngetRegisterFpu(list:taasmoutput;reg:tregister;size:TCGsize);override;
         procedure UngetRegisterFpu(list:taasmoutput;reg:tregister;size:TCGsize);override;
         procedure ClearTempGen;override;
         procedure ClearTempGen;override;
-      private
-        UsedParaRegs: TSupRegSet;
       end;
       end;
 
 
 
 
@@ -52,6 +55,7 @@ implementation
       cgobj,verbose;
       cgobj,verbose;
 
 
 
 
+{$ifndef NEWRA}
     function TRgCpu.GetExplicitRegisterInt(list:TAasmOutput;reg:TNewRegister):TRegister;
     function TRgCpu.GetExplicitRegisterInt(list:TAasmOutput;reg:TNewRegister):TRegister;
       begin
       begin
         if ((reg shr 8) in [RS_O0..RS_O7,RS_I0..RS_I7]) then
         if ((reg shr 8) in [RS_O0..RS_O7,RS_I0..RS_I7]) then
@@ -84,6 +88,7 @@ implementation
         else
         else
           inherited ungetregisterint(list,reg);
           inherited ungetregisterint(list,reg);
       end;
       end;
+{$endif NEWRA}
 
 
 
 
     function TRgCpu.GetRegisterFpu(list:TAasmOutput;size:Tcgsize):TRegister;
     function TRgCpu.GetRegisterFpu(list:TAasmOutput;size:Tcgsize):TRegister;
@@ -144,7 +149,9 @@ implementation
     procedure trgcpu.cleartempgen;
     procedure trgcpu.cleartempgen;
       begin
       begin
         inherited cleartempgen;
         inherited cleartempgen;
+{$ifndef NEWRA}
         usedpararegs:=[];
         usedpararegs:=[];
+{$endif NEWRA}
       end;
       end;
 
 
 begin
 begin
@@ -152,7 +159,10 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.15  2003-07-02 22:18:04  peter
+  Revision 1.16  2003-08-11 21:18:20  peter
+    * start of sparc support for newra
+
+  Revision 1.15  2003/07/02 22:18:04  peter
     * paraloc splitted in callerparaloc,calleeparaloc
     * paraloc splitted in callerparaloc,calleeparaloc
     * sparc calling convention updates
     * sparc calling convention updates
 
 

+ 6 - 1
compiler/symconst.pas

@@ -165,6 +165,8 @@ type
     normset,smallset,varset
     normset,smallset,varset
   );
   );
 
 
+  tcallercallee = (callerside,calleeside);
+
   { basic type for tprocdef and tprocvardef }
   { basic type for tprocdef and tprocvardef }
   tproctypeoption=(potype_none,
   tproctypeoption=(potype_none,
     potype_proginit,     { Program initialization }
     potype_proginit,     { Program initialization }
@@ -355,7 +357,10 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.59  2003-08-10 17:25:23  peter
+  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
     * fixed some reported bugs
     * fixed some reported bugs
 
 
   Revision 1.58  2003/06/25 18:31:23  peter
   Revision 1.58  2003/06/25 18:31:23  peter

+ 6 - 3
compiler/symdef.pas

@@ -107,8 +107,7 @@ interface
           defaultvalue : tsym; { tconstsym }
           defaultvalue : tsym; { tconstsym }
           defaultvaluederef : tderef;
           defaultvaluederef : tderef;
           paratyp       : tvarspez; { required for procvar }
           paratyp       : tvarspez; { required for procvar }
-          calleeparaloc,
-          callerparaloc : tparalocation;
+          paraloc       : array[tcallercallee] of tparalocation;
           is_hidden     : boolean; { is this a hidden (implicit) parameter }
           is_hidden     : boolean; { is this a hidden (implicit) parameter }
 {$ifdef EXTDEBUG}
 {$ifdef EXTDEBUG}
           eqval         : tequaltype;
           eqval         : tequaltype;
@@ -429,6 +428,7 @@ interface
           maxparacount,
           maxparacount,
           minparacount    : byte;
           minparacount    : byte;
           fpu_used        : byte;    { how many stack fpu must be empty }
           fpu_used        : byte;    { how many stack fpu must be empty }
+          funcret_paraloc : array[tcallercallee] of tparalocation;
           has_paraloc_info : boolean; { paraloc info is available }
           has_paraloc_info : boolean; { paraloc info is available }
           constructor create(level:byte);
           constructor create(level:byte);
           constructor ppuload(ppufile:tcompilerppufile);
           constructor ppuload(ppufile:tcompilerppufile);
@@ -5838,7 +5838,10 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.157  2003-07-08 15:20:56  peter
+  Revision 1.158  2003-08-11 21:18:20  peter
+    * start of sparc support for newra
+
+  Revision 1.157  2003/07/08 15:20:56  peter
     * don't allow add/assignments for formaldef
     * don't allow add/assignments for formaldef
     * formaldef size changed to 0
     * formaldef size changed to 0
 
 

+ 14 - 63
compiler/x86/aasmcpu.pas

@@ -201,12 +201,14 @@ interface
          procedure SetOperandOrder(order:TOperandOrder);
          procedure SetOperandOrder(order:TOperandOrder);
          function is_nop:boolean;override;
          function is_nop:boolean;override;
          function is_move:boolean;override;
          function is_move:boolean;override;
+{$ifdef NEWRA}
          function spill_registers(list:Taasmoutput;
          function spill_registers(list:Taasmoutput;
                                   rgget:Trggetproc;
                                   rgget:Trggetproc;
                                   rgunget:Trgungetproc;
                                   rgunget:Trgungetproc;
                                   r:Tsupregset;
                                   r:Tsupregset;
                                   var unusedregsint:Tsupregset;
                                   var unusedregsint:Tsupregset;
                                   const spilltemplist:Tspill_temp_list):boolean;override;
                                   const spilltemplist:Tspill_temp_list):boolean;override;
+{$endif}
       protected
       protected
          procedure ppuloadoper(ppufile:tcompilerppufile;var o:toper);override;
          procedure ppuloadoper(ppufile:tcompilerppufile;var o:toper);override;
          procedure ppuwriteoper(ppufile:tcompilerppufile;const o:toper);override;
          procedure ppuwriteoper(ppufile:tcompilerppufile;const o:toper);override;
@@ -1997,6 +1999,8 @@ implementation
         ((oper[0].typ=top_reg) and (oper[1].typ=top_reg));
         ((oper[0].typ=top_reg) and (oper[1].typ=top_reg));
     end;
     end;
 
 
+
+{$ifdef NEWRA}
     function Taicpu.spill_registers(list:Taasmoutput;
     function Taicpu.spill_registers(list:Taasmoutput;
                                     rgget:Trggetproc;
                                     rgget:Trggetproc;
                                     rgunget:Trgungetproc;
                                     rgunget:Trgungetproc;
@@ -2009,64 +2013,6 @@ implementation
      of the huge amount of situations you can have. The irregularity of the i386
      of the huge amount of situations you can have. The irregularity of the i386
      instruction set doesn't help either. (DM)}
      instruction set doesn't help either. (DM)}
 
 
-    
-      function get_insert_pos(p:Tai;huntfor1,huntfor2,huntfor3:Tsuperregister):Tai;
-
-      var back:Tsupregset;
-
-      begin
-        back:=unusedregsint;
-        get_insert_pos:=p;
-        while (p<>nil) and not (p.typ in [ait_instruction,ait_label]) do
-          begin
-            if p.typ=ait_regalloc then
-              begin
-                {Rewind the register allocation.}
-                if Tai_regalloc(p).allocation then
-                  include(unusedregsint,Tai_regalloc(p).reg.number shr 8)
-                else
-                  begin
-                    exclude(unusedregsint,Tai_regalloc(p).reg.number shr 8);
-                    if Tai_regalloc(p).reg.number shr 8=huntfor1 then
-                      begin
-                        get_insert_pos:=Tai(p.previous);
-                        back:=unusedregsint;
-                      end;
-                    if Tai_regalloc(p).reg.number shr 8=huntfor2 then
-                      begin
-                        get_insert_pos:=Tai(p.previous);
-                        back:=unusedregsint;
-                      end;
-                    if Tai_regalloc(p).reg.number shr 8=huntfor3 then
-                      begin
-                        get_insert_pos:=Tai(p.previous);
-                        back:=unusedregsint;
-                      end;
-                end;
-            end {else writeln('!!!!'^g,byte(p.typ))};
-            p:=Tai(p.previous);
-          end;
-        unusedregsint:=back;
-      end;
-
-      procedure forward_allocation(p:Tai);
-
-      begin
-        {Forward the register allocation again.}
-        while (p<>self) do
-          begin
-            if p.typ in [ait_instruction,ait_label] then
-              internalerror(200305311);
-            if p.typ=ait_regalloc then
-              begin
-              if Tai_regalloc(p).allocation then
-                exclude(unusedregsint,Tai_regalloc(p).reg.number shr 8)
-              else
-                include(unusedregsint,Tai_regalloc(p).reg.number shr 8);
-              end;
-            p:=Tai(p.next);
-          end;
-      end;
 
 
     var i:byte;
     var i:byte;
         supreg:Tsuperregister;
         supreg:Tsuperregister;
@@ -2212,9 +2158,9 @@ implementation
                       begin
                       begin
                         {Situation example:
                         {Situation example:
                          add r20d,[r21d]      ; r20d must be spilled into [ebp-12]
                          add r20d,[r21d]      ; r20d must be spilled into [ebp-12]
-  
+
                          Change into:
                          Change into:
-  
+
                          mov r22d,[r21d]      ; Use a help register
                          mov r22d,[r21d]      ; Use a help register
                          add [ebp-12],r22d    ; Replace register by helpregister }
                          add [ebp-12],r22d    ; Replace register by helpregister }
                         pos:=get_insert_pos(Tai(previous),oper[0].ref^.base.number shr 8,
                         pos:=get_insert_pos(Tai(previous),oper[0].ref^.base.number shr 8,
@@ -2248,9 +2194,9 @@ implementation
                       begin
                       begin
                         {Situation example:
                         {Situation example:
                          add r20d,r21d        ; r20d must be spilled into [ebp-12]
                          add r20d,r21d        ; r20d must be spilled into [ebp-12]
-  
+
                          Change into:
                          Change into:
-  
+
                          add [ebp-12],r21d    ; Replace register by reference }
                          add [ebp-12],r21d    ; Replace register by reference }
                         if (opcode=A_MOVZX) or (opcode=A_MOVSX) then
                         if (opcode=A_MOVZX) or (opcode=A_MOVSX) then
                           begin
                           begin
@@ -2369,6 +2315,8 @@ implementation
           end;
           end;
       end;
       end;
     end;
     end;
+{$endif NEWRA}
+
 
 
 {*****************************************************************************
 {*****************************************************************************
                               Instruction table
                               Instruction table
@@ -2419,7 +2367,10 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.8  2003-08-09 18:56:54  daniel
+  Revision 1.9  2003-08-11 21:18:20  peter
+    * start of sparc support for newra
+
+  Revision 1.8  2003/08/09 18:56:54  daniel
     * cs_regalloc renamed to cs_regvars to avoid confusion with register
     * cs_regalloc renamed to cs_regvars to avoid confusion with register
       allocator
       allocator
     * Some preventive changes to i386 spillinh code
     * Some preventive changes to i386 spillinh code