瀏覽代碼

* start of sparc support for newra

peter 22 年之前
父節點
當前提交
52c73e80d1

+ 69 - 5
compiler/aasmtai.pas

@@ -444,12 +444,17 @@ interface
           procedure loadoper(opidx:longint;o:toper);
           function is_nop: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;
                                    rgget:Trggetproc;
                                    rgunget:Trgungetproc;
                                    r:Tsupregset;
                                    var unusedregsint:Tsupregset;
                                    const spilltemplist:Tspill_temp_list):boolean;virtual;abstract;
+{$endif NEWRA}
        end;
 
        { alignment for operator }
@@ -494,13 +499,13 @@ interface
 
 implementation
 
-uses
+    uses
 {$ifdef delphi}
-  sysutils,
+      sysutils,
 {$else}
-  strings,
+      strings,
 {$endif}
-  verbose;
+      verbose;
 
     const
       pputaimarker = 254;
@@ -1586,6 +1591,62 @@ uses
          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.
@@ -1838,7 +1899,10 @@ uses
 end.
 {
   $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
       the optimizer can't remove the first object
 

+ 30 - 31
compiler/cgbase.pas

@@ -370,43 +370,39 @@ implementation
       var
         paramloc : tparalocation;
       begin
+         { generate callee paraloc register info }
+         paramanager.create_paraloc_info(current_procinfo.procdef,calleeside);
+
          { temporary space is set, while the BEGIN of the procedure }
          if (symtablestack.symtabletype=localsymtable) then
            current_procinfo.firsttemp_offset := tg.direction*symtablestack.datasize
          else
            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
            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;
 
@@ -571,7 +567,10 @@ implementation
 end.
 {
   $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
     * parent framepointer code more generic
 

+ 6 - 2
compiler/fpcdefs.inc

@@ -60,7 +60,8 @@
 {$endif alpha}
 
 {$ifdef sparc}
-  {$define callparatemp}
+  {$define usetempparaloc}
+  { define callparatemp}
 {$endif sparc}
 
 {$ifdef powerpc}
@@ -83,7 +84,10 @@
 
 {
   $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
 
   Revision 1.20  2003/05/24 21:12:57  florian

+ 42 - 7
compiler/i386/cpupara.pas

@@ -33,7 +33,7 @@ unit cpupara;
        cpubase,
        globtype,
        cginfo,
-       symtype,symdef,paramgr;
+       symconst,symtype,symdef,paramgr;
 
     type
        { Returns the location for the nr-st 32 Bit int parameter
@@ -55,7 +55,7 @@ unit cpupara;
 
     uses
        systems,verbose,
-       symconst,symsym,
+       symsym,
        cpuinfo,
        cgbase;
 
@@ -153,13 +153,45 @@ unit cpupara;
                 paraloc.reference.index.number:=NR_FRAME_POINTER_REG;
               end;
             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}
-            else
-              hp.calleeparaloc:=paraloc;
             hp:=tparaitem(hp.next);
           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;
 
 
@@ -182,7 +214,10 @@ begin
 end.
 {
   $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
       callee info
     * fixed ppc cycle

+ 141 - 96
compiler/ncgcal.pas

@@ -35,6 +35,9 @@ interface
 
     type
        tcgcallparanode = class(tcallparanode)
+       private
+          tempparaloc : tparalocation;
+       public
           procedure secondcallparan(push_from_left_to_right:boolean;calloption:tproccalloption;
                 para_alignment,para_offset : longint);override;
        end;
@@ -125,19 +128,31 @@ implementation
          objectlibrary.getlabel(truelabel);
          objectlibrary.getlabel(falselabel);
          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 }
          if (nf_varargs_para in flags) then
            begin
              if paramanager.push_addr_param(left.resulttype.def,calloption) then
                begin
                  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);
                end
              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
          { hidden parameters }
          else if paraitem.is_hidden then
@@ -169,13 +184,13 @@ implementation
                     {$endif}
                     end
                   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);
                end
              else
                begin
                   push_value_para(exprasmlist,left,calloption,
-                    para_offset,para_alignment,paraitem.callerparaloc);
+                    para_offset,para_alignment,tempparaloc);
                end;
            end
          { filter array of const c styled args }
@@ -203,7 +218,7 @@ implementation
                        cg.a_load_loc_ref(exprasmlist,OS_ADDR,left.location,href);
                     end
                   else
-                    cg.a_param_loc(exprasmlist,left.location,paraitem.callerparaloc);
+                    cg.a_param_loc(exprasmlist,left.location,tempparaloc);
                   location_release(exprasmlist,left.location);
                 end
               else
@@ -228,7 +243,7 @@ implementation
                      {$endif}
                      end
                    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);
                 end;
            end
@@ -266,7 +281,7 @@ implementation
                 {$endif}
                 end
               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);
            end
          else
@@ -316,13 +331,13 @@ implementation
                      {$endif}
                      end
                    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);
                 end
               else
                 begin
                    push_value_para(exprasmlist,left,calloption,
-                     para_offset,para_alignment,paraitem.callerparaloc);
+                     para_offset,para_alignment,tempparaloc);
                 end;
            end;
          truelabel:=otlabel;
@@ -401,7 +416,9 @@ implementation
       var
         cgsize : tcgsize;
         r,hregister : tregister;
+{$ifndef NEWRA}
         href: treference;
+{$endif}
         tempnode: tnode;
       begin
         { structured results are easy to handle.... }
@@ -418,7 +435,7 @@ implementation
             is_widestring(resulttype.def) then
           begin
             r.enum:=R_INTREGISTER;
-            r.number:=NR_FUNCTION_RETURN_REG;
+            r.number:=NR_FUNCTION_RESULT_REG;
 {$ifdef newra}
             { the FUNCTION_RESULT_REG is already allocated }
             rg.ungetregisterint(exprasmlist,r);
@@ -648,9 +665,7 @@ implementation
          regs_to_push_other : tregisterset;
          unusedstate: pointer;
       {$ifdef newra}
-         i:Tsuperregister;
          regs_to_alloc,regs_to_free:Tsupregset;
-         funcretloc: tparalocation;
       {$else}
          regs_to_push_int : Tsupregset;
          pushedint : tpushedsavedint;
@@ -664,23 +679,62 @@ implementation
          href,helpref : treference;
          para_alignment,
          pop_size : longint;
-         r,
 {$ifdef x86}
          accreg,
 {$endif x86}
          vmtreg,vmtreg2 : tregister;
          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;
          var
-           paraitem : tparaitem;
+           ppn : tcgcallparanode;
          begin
            { free the resources allocated for the parameters }
-           paraitem:=tparaitem(procdefinition.para.first);
-           while assigned(paraitem) do
+           ppn:=tcgcallparanode(left);
+           while assigned(ppn) do
              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;
            { free pushed base pointer }
            if (right=nil) and
@@ -743,44 +797,10 @@ implementation
 
 {$ifdef newra}
               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}
               { save all used registers and possible registers
                 used for the return value }
               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}
 
 {$ifdef i386}
@@ -788,8 +808,6 @@ implementation
 {$else i386}
               regs_to_push_other := [];
 {$endif i386}
-              rg.saveusedotherregisters(exprasmlist,pushedother,regs_to_push_other);
-
               { 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     }
 {$ifdef i386}
@@ -800,39 +818,18 @@ implementation
            end
          else
            begin
-              {No procedure is allowed to destroy ebp.}
 {$ifdef newra}
               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}
               regs_to_push_int := VOLATILE_INTREGISTERS;
-              rg.saveusedintregisters(exprasmlist,pushedint,regs_to_push_int);
 {$endif}
 {$ifdef i386}
               regs_to_push_other := all_registers;
 {$else i386}
               regs_to_push_other := [];
 {$endif i386}
-              rg.saveusedotherregisters(exprasmlist,pushedother,regs_to_push_other);
 {$ifdef i386}
+              rg.used_in_proc_int:=VOLATILE_INTREGISTERS;
               rg.used_in_proc_other:=all_registers;
 {$endif i386}
 
@@ -840,6 +837,48 @@ implementation
               iolabel:=nil;
            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 }
          oldpushedparasize:=pushedparasize;
          pushedparasize:=0;
@@ -879,6 +918,7 @@ implementation
            end;
 {$endif not i386}
 
+         { Process parameters }
          if assigned(left) then
            begin
             {$ifndef newra}
@@ -899,6 +939,10 @@ implementation
                 if assigned(methodpointer) then
                   maybe_restore(exprasmlist,methodpointer.location,pushedregs);
             {$endif newra}
+
+{$ifdef usetempparaloc}
+             pushparas;
+{$endif}
            end;
          aktcallnode:=oldaktcallnode;
 
@@ -1058,22 +1102,23 @@ implementation
 {$endif TEMPREGDEBUG}
 
 {$ifdef newra}
+         { Release registers, but not the registers that contain the
+           function result }
          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
-             case funcretloc.loc of
+             case procdefinition.funcret_paraloc[callerside].loc of
                LOC_REGISTER,LOC_CREGISTER:
                  begin
 {$ifndef cpu64bit}
-                   if funcretloc.size in [OS_S64,OS_64] then
+                   if procdefinition.funcret_paraloc[callerside].size in [OS_S64,OS_64] then
                      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
                    else
 {$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;
@@ -1147,7 +1192,6 @@ implementation
          pushedint : tpushedsavedint;
          pushedregs : tmaybesave;
       {$endif}
-         funcretloc: tparalocation;
          oldpushedparasize : longint;
          { adress returned from an I/O-error }
          iolabel : tasmlabel;
@@ -1314,22 +1358,20 @@ implementation
            used for the return value }
          regs_to_push_int := tprocdef(procdefinition).usedintregisters;
          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
-             funcretloc := paramanager.getfuncretparaloc(procdefinition);
-             case funcretloc.loc of
+             case procdefinition.funcret_paraloc[callerside].loc of
                LOC_REGISTER,LOC_CREGISTER:
                  begin
 {$ifndef cpu64bit}
-                   if funcretloc.size in [OS_S64,OS_64] then
+                   if procdefinition.funcret_paraloc[callerside].size in [OS_S64,OS_64] then
                      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
                    else
 {$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;
@@ -1541,7 +1583,10 @@ begin
 end.
 {
   $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
 
   Revision 1.103  2003/07/23 11:01:14  jonas
@@ -1573,7 +1618,7 @@ end.
      * fixed ppc cycle
 
   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
 
   Revision 1.95  2003/06/17 16:34:44  jonas

+ 7 - 4
compiler/ncgutil.pas

@@ -1636,14 +1636,14 @@ implementation
                   internalerror(200301081);
                 if (tvarsym(hp.parasym).reg.enum<>R_NO) then
                   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
-                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
                         (tvarsym(hp.parasym).reg.enum=R_NO) then
                   begin
                     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;
                 hp:=tparaitem(hp.next);
               end;
@@ -2030,7 +2030,10 @@ implementation
 end.
 {
   $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
       allocator
     * Some preventive changes to i386 spillinh code

+ 25 - 113
compiler/paramgr.pas

@@ -35,7 +35,6 @@ unit paramgr;
        symconst,symtype,symdef;
 
     type
-       tcallercallee = (callerside,calleeside);
        {# This class defines some methods to take care of routine
           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;
 
-          {
-            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,
             when the stack frame is already created. This is used by the code
             generating the wrappers for implemented interfaces.
           }
           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;
+
+{$ifdef usetempparaloc}
+          procedure alloctempregs(list: taasmoutput;var locpara:tparalocation);virtual;
+{$endif usetempparaloc}
        end;
 
 
@@ -312,97 +296,6 @@ implementation
       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);
       begin
         if not(locpara.size in [OS_64,OS_S64]) then
@@ -433,6 +326,22 @@ implementation
       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
@@ -443,7 +352,10 @@ end.
 
 {
    $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
 
    Revision 1.48  2003/07/05 20:11:41  jonas

+ 8 - 3
compiler/pass_2.pas

@@ -164,7 +164,9 @@ implementation
          prevp : pptree;
 {$endif TEMPREGDEBUG}
 {$ifdef EXTDEBUG}
+{$ifndef newra}
          i : longint;
+{$endif newra}
 {$endif EXTDEBUG}
       begin
          if not assigned(p) then
@@ -205,9 +207,11 @@ implementation
              end;
 
 {$ifdef newra}
+  {$ifdef i386}
             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
               internalerror(200306171);
+  {$endif}
 {$else}
             { check if all scratch registers are freed }
             for i:=1 to max_scratch_regs do
@@ -280,8 +284,6 @@ implementation
               { assign parameter locations }
               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 }
               { code of the ppc (and possibly other processors)               }
               if not current_procinfo.procdef.has_paraloc_info then
@@ -315,7 +317,10 @@ implementation
 end.
 {
   $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
 
   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_move:boolean; override;
+{$ifdef newra}
          function spill_registers(list:Taasmoutput;
                                   rgget:Trggetproc;
                                   rgunget:Trgungetproc;
                                   r:Tsupregset;
                                   var unusedregsint:Tsupregset;
                                   const spilltemplist:Tspill_temp_list):boolean; override;
+{$endif}
 
 
       end;
@@ -416,7 +418,8 @@ uses cutils,rgobj;
     function taicpu.is_nop: boolean;
       begin
         { 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;
 
 
@@ -426,68 +429,16 @@ uses cutils,rgobj;
       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;
 
-      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
           result := true;
           wasload := true;
@@ -591,7 +542,7 @@ uses cutils,rgobj;
                 //
                 //   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);
                 rgget(list,pos,0,helpreg);
@@ -720,7 +671,7 @@ uses cutils,rgobj;
         for i := 1 to 2 do
           if (oper[i].typ = top_reg) then
             begin
-              supreg:=oper[i].reg.number;
+              supreg:=oper[i].reg.number shr 8;
               if supreg in r then
                 begin
                   // Example:
@@ -731,7 +682,7 @@ uses cutils,rgobj;
                   //   lwz r23d, -60(r1)
                   //   add r23d, r21d, r22d
                   //   stw r23d, -60(r1)
-      
+
                   pos := get_insert_pos(Tai(previous),reg1,reg2,reg3);
                   rgget(list,pos,0,helpreg);
                   spill_registers := true;
@@ -750,6 +701,7 @@ uses cutils,rgobj;
                 end;
             end;
       end;
+{$endif newra}
 
 
 
@@ -765,7 +717,13 @@ uses cutils,rgobj;
 end.
 {
   $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
 
   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);
                 while assigned(hp) do
                   begin
-                    if (hp.calleeparaloc.loc in [LOC_REFERENCE,LOC_CREFERENCE]) then
+                    if (hp.paraloc[calleeside].loc in [LOC_REFERENCE,LOC_CREFERENCE]) then
                       begin
                         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;
                     hp := tparaitem(hp.next);
                   end;
@@ -2672,7 +2672,10 @@ begin
 end.
 {
   $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.
 
   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;
           procedure freeintparaloc(list: taasmoutput; nr : longint); override;
           procedure create_paraloc_info(p : tabstractprocdef; side: tcallercallee);override;
-          function getfuncretparaloc(p : tabstractprocdef) : tparalocation;override;
        end;
 
   implementation
@@ -247,9 +246,9 @@ unit cpupara;
                       if nextintreg.number<=(NR_R10-ord(is_64bit)*(NR_R1-NR_R0))  then
                         begin
                            paraloc.loc:=LOC_REGISTER;
-		           if is_64bit then
+                           if is_64bit then
                              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);
                                paraloc.registerhigh:=nextintreg;
                                inc(nextintreg.number,NR_R1-NR_R0);
@@ -312,81 +311,60 @@ unit cpupara;
                  else
                    internalerror(2002071002);
               end;
-              if side = callerside then
-                hp.callerparaloc:=paraloc
-              else
+              if side = calleeside then
                 begin
                   if (paraloc.loc = LOC_REFERENCE) then
                     paraloc.reference.offset := tvarsym(hp.parasym).adjusted_address;
-                  hp.calleeparaloc:=paraloc;
                 end;
+              hp.paraloc[side]:=paraloc;
               hp:=tparaitem(hp.next);
            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
-              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;
 
-
 begin
    paramanager:=tppcparamanager.create;
 end.
 {
   $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
       callee info
     * fixed ppc cycle

+ 10 - 7
compiler/regvars.pas

@@ -183,15 +183,15 @@ implementation
                   hp:=tparaitem(current_procinfo.procdef.para.first);
                   while assigned(hp) do
                     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
-                         (TCGSize2Size[hp.calleeparaloc.size] <= sizeof(aword)) then
+                         (TCGSize2Size[hp.paraloc[calleeside].size] <= sizeof(aword)) then
                         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
-                            rg.makeregvarother(hp.calleeparaloc.register);
+                            rg.makeregvarother(hp.paraloc[calleeside].register);
                         end
                       else
                         begin
@@ -616,7 +616,10 @@ end.
 
 {
   $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
       allocator
     * 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_sym(op : tasmop;_op1 : tasmsymbol);
          constructor op_sym_ofs(op : tasmop;_op1 : tasmsymbol;_op1ofs:longint);
+
+         { register allocation }
          function is_nop: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;
 
       tai_align = class(tai_align_abstract)
@@ -250,6 +258,242 @@ implementation
       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;
       begin
       end;
@@ -262,7 +506,10 @@ implementation
 end.
 {
   $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
     * added constants for indicating source and destination operands of the
       "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 freeparaloc(list: taasmoutput; const loc: tparalocation);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;
       end;
 
@@ -209,75 +206,71 @@ implementation
                 else
                   inc(stack_offset,4);
               end;
-            if side = callerside then
-              hp.callerparaloc:=paraloc
-            else
+            hp.paraloc[side]:=paraloc;
+            if side = calleeside then
               begin
                 { update callee paraloc and use Ix registers instead
                   of Ox registers }
-                hp.calleeparaloc:=paraloc;
-                if hp.calleeparaloc.loc=LOC_REGISTER then
+                if hp.paraloc[calleeside].loc=LOC_REGISTER then
                   begin
                     { big endian }
                     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
                 else
                   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;
             hp:=TParaItem(hp.Next);
           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;
 
 
@@ -308,7 +301,10 @@ begin
 end.
 {
   $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
 
   Revision 1.25  2003/07/06 22:10:56  peter

+ 14 - 4
compiler/sparc/rgcpu.pas

@@ -36,13 +36,16 @@ interface
 
     type
       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;
         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 ClearTempGen;override;
-      private
-        UsedParaRegs: TSupRegSet;
       end;
 
 
@@ -52,6 +55,7 @@ implementation
       cgobj,verbose;
 
 
+{$ifndef NEWRA}
     function TRgCpu.GetExplicitRegisterInt(list:TAasmOutput;reg:TNewRegister):TRegister;
       begin
         if ((reg shr 8) in [RS_O0..RS_O7,RS_I0..RS_I7]) then
@@ -84,6 +88,7 @@ implementation
         else
           inherited ungetregisterint(list,reg);
       end;
+{$endif NEWRA}
 
 
     function TRgCpu.GetRegisterFpu(list:TAasmOutput;size:Tcgsize):TRegister;
@@ -144,7 +149,9 @@ implementation
     procedure trgcpu.cleartempgen;
       begin
         inherited cleartempgen;
+{$ifndef NEWRA}
         usedpararegs:=[];
+{$endif NEWRA}
       end;
 
 begin
@@ -152,7 +159,10 @@ begin
 end.
 {
   $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
     * sparc calling convention updates
 

+ 6 - 1
compiler/symconst.pas

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

+ 6 - 3
compiler/symdef.pas

@@ -107,8 +107,7 @@ interface
           defaultvalue : tsym; { tconstsym }
           defaultvaluederef : tderef;
           paratyp       : tvarspez; { required for procvar }
-          calleeparaloc,
-          callerparaloc : tparalocation;
+          paraloc       : array[tcallercallee] of tparalocation;
           is_hidden     : boolean; { is this a hidden (implicit) parameter }
 {$ifdef EXTDEBUG}
           eqval         : tequaltype;
@@ -429,6 +428,7 @@ interface
           maxparacount,
           minparacount    : byte;
           fpu_used        : byte;    { how many stack fpu must be empty }
+          funcret_paraloc : array[tcallercallee] of tparalocation;
           has_paraloc_info : boolean; { paraloc info is available }
           constructor create(level:byte);
           constructor ppuload(ppufile:tcompilerppufile);
@@ -5838,7 +5838,10 @@ implementation
 end.
 {
   $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
     * formaldef size changed to 0
 

+ 14 - 63
compiler/x86/aasmcpu.pas

@@ -201,12 +201,14 @@ interface
          procedure SetOperandOrder(order:TOperandOrder);
          function is_nop:boolean;override;
          function is_move:boolean;override;
+{$ifdef NEWRA}
          function spill_registers(list:Taasmoutput;
                                   rgget:Trggetproc;
                                   rgunget:Trgungetproc;
                                   r:Tsupregset;
                                   var unusedregsint:Tsupregset;
                                   const spilltemplist:Tspill_temp_list):boolean;override;
+{$endif}
       protected
          procedure ppuloadoper(ppufile:tcompilerppufile;var 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));
     end;
 
+
+{$ifdef NEWRA}
     function Taicpu.spill_registers(list:Taasmoutput;
                                     rgget:Trggetproc;
                                     rgunget:Trgungetproc;
@@ -2009,64 +2013,6 @@ implementation
      of the huge amount of situations you can have. The irregularity of the i386
      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;
         supreg:Tsuperregister;
@@ -2212,9 +2158,9 @@ implementation
                       begin
                         {Situation example:
                          add r20d,[r21d]      ; r20d must be spilled into [ebp-12]
-  
+
                          Change into:
-  
+
                          mov r22d,[r21d]      ; Use a help register
                          add [ebp-12],r22d    ; Replace register by helpregister }
                         pos:=get_insert_pos(Tai(previous),oper[0].ref^.base.number shr 8,
@@ -2248,9 +2194,9 @@ implementation
                       begin
                         {Situation example:
                          add r20d,r21d        ; r20d must be spilled into [ebp-12]
-  
+
                          Change into:
-  
+
                          add [ebp-12],r21d    ; Replace register by reference }
                         if (opcode=A_MOVZX) or (opcode=A_MOVSX) then
                           begin
@@ -2369,6 +2315,8 @@ implementation
           end;
       end;
     end;
+{$endif NEWRA}
+
 
 {*****************************************************************************
                               Instruction table
@@ -2419,7 +2367,10 @@ implementation
 end.
 {
   $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
       allocator
     * Some preventive changes to i386 spillinh code