Browse Source

* fixed regvars so they work with newra (at least for ppc)
* fixed some volatile register bugs
+ -dnotranslation option for -dnewra, which causes the registers not to
be translated from virtual to normal registers. Requires support in
the assembler writer as well, which is only implemented in aggas/
agppcgas currently

Jonas Maebe 22 years ago
parent
commit
4f8c390198

+ 12 - 1
compiler/aasmtai.pas

@@ -1860,6 +1860,9 @@ implementation
         r:Preference;
 
     begin
+{$ifdef notranslation}
+      exit;
+{$endif notranslation}  
       p:=Tai(first);
       while assigned(p) do
         begin
@@ -1899,7 +1902,15 @@ implementation
 end.
 {
   $Log$
-  Revision 1.31  2003-08-11 21:18:20  peter
+  Revision 1.32  2003-08-17 16:59:20  jonas
+    * fixed regvars so they work with newra (at least for ppc)
+    * fixed some volatile register bugs
+    + -dnotranslation option for -dnewra, which causes the registers not to
+      be translated from virtual to normal registers. Requires support in
+      the assembler writer as well, which is only implemented in aggas/
+      agppcgas currently
+
+  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

+ 14 - 1
compiler/aggas.pas

@@ -387,10 +387,15 @@ var
              begin
                if (cs_asm_regalloc in aktglobalswitches) then
                  begin
+{$ifndef notranslation}
                    if Tai_Regalloc(hp).reg.enum>lastreg then
                      internalerror(200201081);
                    AsmWriteLn(target_asm.comment+'Register '+std_reg2str[tai_regalloc(hp).reg.enum]+
                      allocstr[tai_regalloc(hp).allocation]);
+{$else not notranslation}
+                   AsmWriteLn(target_asm.comment+'Register r'+tostr(ord(tai_regalloc(hp).reg.enum)-1)+
+                     allocstr[tai_regalloc(hp).allocation]);
+{$endif not notranslation}
                  end;
              end;
 
@@ -820,7 +825,15 @@ var
 end.
 {
   $Log$
-  Revision 1.24  2003-04-28 21:17:53  peter
+  Revision 1.25  2003-08-17 16:59:20  jonas
+    * fixed regvars so they work with newra (at least for ppc)
+    * fixed some volatile register bugs
+    + -dnotranslation option for -dnewra, which causes the registers not to
+      be translated from virtual to normal registers. Requires support in
+      the assembler writer as well, which is only implemented in aggas/
+      agppcgas currently
+
+  Revision 1.24  2003/04/28 21:17:53  peter
     * write sec_none info in extdebug
 
   Revision 1.23  2003/04/25 20:59:33  peter

+ 40 - 4
compiler/cgobj.pas

@@ -719,9 +719,27 @@ unit cgobj;
           LOC_REGISTER:
             begin
               if (locpara.size in [OS_S64,OS_64]) then
-                cg64.a_load64_reg_ref(list,locpara.register64,ref)
+                begin
+{$ifdef newra}
+{$ifdef cpu64bit} 
+                  rg.ungetregisterint(list,locpara.register64);
+{$else cpu64bit}
+                  rg.getexplicitregisterint(list,locpara.registerlow.number);
+                  rg.getexplicitregisterint(list,locpara.registerhigh.number);
+                  rg.ungetregisterint(list,locpara.registerlow);
+                  rg.ungetregisterint(list,locpara.registerhigh);
+{$endif cpu64bit}
+{$endif newra}
+                  cg64.a_load64_reg_ref(list,locpara.register64,ref)
+                end
               else
-                cg.a_load_reg_ref(list,locpara.size,locpara.size,locpara.register,ref);
+                begin
+{$ifdef newra}
+                  rg.getexplicitregisterint(list,locpara.register.number);
+                  rg.ungetregisterint(list,locpara.register);
+{$endif newra}
+                  cg.a_load_reg_ref(list,locpara.size,locpara.size,locpara.register,ref);
+                end;
             end;
           LOC_FPUREGISTER,
           LOC_CFPUREGISTER:
@@ -741,7 +759,14 @@ unit cgobj;
           LOC_REGISTER:
             begin
               if not(locpara.size in [OS_S64,OS_64]) then
-                cg.a_load_reg_reg(list,locpara.size,locpara.size,locpara.register,reg)
+                begin
+{$ifdef newra}
+                  rg.getexplicitregisterint(list,locpara.register.number);
+                  rg.ungetregisterint(list,locpara.register);
+                  rg.getexplicitregisterint(list,reg.number);
+{$endif newra}
+                  cg.a_load_reg_reg(list,locpara.size,locpara.size,locpara.register,reg)
+                end
               else
                 internalerror(2003053011);
             end;
@@ -752,6 +777,9 @@ unit cgobj;
           LOC_CREFERENCE:
             begin
               reference_reset_base(href,locpara.reference.index,locpara.reference.offset);
+{$ifdef newra}
+              rg.getexplicitregisterint(list,reg.number);
+{$endif newra}
               cg.a_load_ref_reg(list,locpara.size,locpara.size,href,reg);
             end;
           else
@@ -1851,7 +1879,15 @@ finalization
 end.
 {
   $Log$
-  Revision 1.115  2003-07-23 11:01:14  jonas
+  Revision 1.116  2003-08-17 16:59:20  jonas
+    * fixed regvars so they work with newra (at least for ppc)
+    * fixed some volatile register bugs
+    + -dnotranslation option for -dnewra, which causes the registers not to
+      be translated from virtual to normal registers. Requires support in
+      the assembler writer as well, which is only implemented in aggas/
+      agppcgas currently
+
+  Revision 1.115  2003/07/23 11:01:14  jonas
     * several rg.allocexplicitregistersint/rg.deallocexplicitregistersint
       pairs round calls to helpers
 

+ 15 - 2
compiler/m68k/cpubase.pas

@@ -175,8 +175,11 @@ uses
       last_supreg     = $10;
 
 {$warning FIXME!!!}
-      { registers which may be destroyed by calls }
+      { integer registers which may be destroyed by calls }
       VOLATILE_INTREGISTERS = [first_supreg..last_supreg];
+{$warning FIXME!!!}
+      { fpu registers which may be destroyed by calls }
+      VOLATILE_FPUREGISTERS = [first_supreg..last_supreg];
 
       first_imreg     = $11;
       last_imreg      = $ff;
@@ -396,6 +399,8 @@ uses
        c_countusableregsxxx = amount of registers in the usableregsxxx set    }
 
       maxintregs = 8;
+      { to determine how many registers to use for regvars }
+      maxintscratchregs = 1;
       intregs    = [R_D0..R_D7];
       usableregsint = [RS_D2..RS_D7];
       c_countusableregsint = 6;
@@ -709,7 +714,15 @@ implementation
 end.
 {
   $Log$
-  Revision 1.22  2003-06-17 16:34:44  jonas
+  Revision 1.23  2003-08-17 16:59:20  jonas
+    * fixed regvars so they work with newra (at least for ppc)
+    * fixed some volatile register bugs
+    + -dnotranslation option for -dnewra, which causes the registers not to
+      be translated from virtual to normal registers. Requires support in
+      the assembler writer as well, which is only implemented in aggas/
+      agppcgas currently
+
+  Revision 1.22  2003/06/17 16:34:44  jonas
     * lots of newra fixes (need getfuncretparaloc implementation for i386)!
     * renamed all_intregisters to volatile_intregisters and made it
       processor dependent

+ 12 - 5
compiler/ncgcal.pas

@@ -806,7 +806,7 @@ implementation
 {$ifdef i386}
               regs_to_push_other := tprocdef(procdefinition).usedotherregisters;
 {$else i386}
-              regs_to_push_other := [];
+              regs_to_push_other := VOLATILE_FPUREGISTERS;
 {$endif i386}
               { 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     }
@@ -826,7 +826,7 @@ implementation
 {$ifdef i386}
               regs_to_push_other := all_registers;
 {$else i386}
-              regs_to_push_other := [];
+              regs_to_push_other := VOLATILE_FPUREGISTERS;
 {$endif i386}
 {$ifdef i386}
               rg.used_in_proc_int:=VOLATILE_INTREGISTERS;
@@ -1043,12 +1043,11 @@ implementation
                       cg.a_load_reg_reg(exprasmlist,OS_ADDR,OS_ADDR,
                                         right.location.reference.base,helpref.base);
                     end;
-	          reference_release(exprasmlist,helpref);
+                  reference_release(exprasmlist,helpref);
                 end
               else
                 rg.ungetregisterint(exprasmlist,right.location.register);
 
-
               location_freetemp(exprasmlist,right.location);
 {$endif newra}
 
@@ -1584,7 +1583,15 @@ begin
 end.
 {
   $Log$
-  Revision 1.106  2003-08-16 18:56:40  marco
+  Revision 1.107  2003-08-17 16:59:20  jonas
+    * fixed regvars so they work with newra (at least for ppc)
+    * fixed some volatile register bugs
+    + -dnotranslation option for -dnewra, which causes the registers not to
+      be translated from virtual to normal registers. Requires support in
+      the assembler writer as well, which is only implemented in aggas/
+      agppcgas currently
+
+  Revision 1.106  2003/08/16 18:56:40  marco
    * fix from Jonas.
 
   Revision 1.105  2003/08/11 21:18:20  peter

+ 51 - 1
compiler/ncgutil.pas

@@ -1351,6 +1351,9 @@ implementation
             if not assigned(ressym) then
               internalerror(200305058);
             reference_reset_base(href,current_procinfo.framepointer,tvarsym(ressym).adjusted_address);
+{$ifdef newra}
+            rg.ungetregisterint(list,r);
+{$endif newra}
             cg.a_load_ref_reg(list,OS_ADDR,OS_ADDR,href,r);
             uses_acc:=true;
             exit;
@@ -1396,6 +1399,10 @@ implementation
                  r2.number:=NR_FUNCTION_RETURN64_HIGH_REG;
                  cg.a_reg_alloc(list,r2);
 {$endif}
+{$ifdef newra}
+                 rg.ungetregisterint(list,r);
+                 rg.ungetregisterint(list,r2);
+{$endif newra}
                  cg64.a_load64_loc_reg(list,resloc,joinreg64(r,r2){$ifdef newra},false{$endif});
                end
               else
@@ -1409,6 +1416,9 @@ implementation
                  cg.a_reg_alloc(list,hreg);
 {$endif}
                  hreg:=rg.makeregsize(hreg,resloc.size);
+{$ifdef newra}
+                 rg.ungetregisterint(list,hreg);
+{$endif newra}
                  cg.a_load_loc_reg(list,resloc.size,resloc,hreg);
                end;
             end;
@@ -1444,6 +1454,10 @@ implementation
                     r2.number:=NR_FUNCTION_RETURN64_HIGH_REG;
                     cg.a_reg_alloc(list,r2);
 {$endif}
+{$ifdef newra}
+                    rg.ungetregisterint(list,r);
+                    rg.ungetregisterint(list,r2);
+{$endif newra}
                     cg64.a_load64_loc_reg(list,resloc,joinreg64(r,r2){$ifdef newra},false{$endif});
                   end
                  else
@@ -1457,6 +1471,9 @@ implementation
                     cg.a_reg_alloc(list,hreg);
 {$endif}
                     hreg:=rg.makeregsize(hreg,resloc.size);
+{$ifdef newra}
+                    rg.ungetregisterint(list,hreg);
+{$endif newra}
                     cg.a_load_loc_reg(list,resloc.size,resloc,hreg);
                   end;
                 end
@@ -1613,6 +1630,9 @@ implementation
         href : treference;
         hp : tparaitem;
         rsp : tregister;
+{$ifdef newra}
+        gotregvarparas: boolean;
+{$endif newra}
       begin
         { the actual stack allocation code, symbol entry point and
           gdb stabs information is generated AFTER the rest of this
@@ -1630,12 +1650,21 @@ implementation
             { we do this before init_paras because that one calls routines which may overwrite these  }
             { registers and it also expects the values to be in memory                                }
             hp:=tparaitem(current_procinfo.procdef.para.first);
+{$ifdef newra}
+            gotregvarparas := false;
+{$endif newra}
             while assigned(hp) do
               begin
                 if Tvarsym(hp.parasym).reg.enum>R_INTREGISTER then
                   internalerror(200301081);
                 if (tvarsym(hp.parasym).reg.enum<>R_NO) then
                   begin
+{$ifdef newra}
+                    gotregvarparas := true;
+                    { cg.a_load_param_reg will first allocate and then deallocate paraloc }
+                    { register (if the parameter resides in a register) and then allocate }
+                    { the regvar (which is currently not allocated)                       }
+{$endif newra}
                     cg.a_load_param_reg(list,hp.paraloc[calleeside],tvarsym(hp.parasym).reg);
                   end
                 else if (hp.paraloc[calleeside].loc in [LOC_REGISTER,LOC_FPUREGISTER,LOC_MMREGISTER,
@@ -1647,6 +1676,19 @@ implementation
                   end;
                 hp:=tparaitem(hp.next);
               end;
+{$ifdef newra}
+            if gotregvarparas then
+              begin
+                { deallocate all register variables again }
+                hp:=tparaitem(current_procinfo.procdef.para.first);
+                while assigned(hp) do
+                  begin
+                    if (tvarsym(hp.parasym).reg.enum<>R_NO) then
+                      rg.ungetregisterint(list,tvarsym(hp.parasym).reg);
+                    hp:=tparaitem(hp.next);
+                  end;
+              end;
+{$endif newra}
           end;
 
         { for the save all registers we can simply use a pusha,popa which
@@ -2030,7 +2072,15 @@ implementation
 end.
 {
   $Log$
-  Revision 1.134  2003-08-11 21:18:20  peter
+  Revision 1.135  2003-08-17 16:59:20  jonas
+    * fixed regvars so they work with newra (at least for ppc)
+    * fixed some volatile register bugs
+    + -dnotranslation option for -dnewra, which causes the registers not to
+      be translated from virtual to normal registers. Requires support in
+      the assembler writer as well, which is only implemented in aggas/
+      agppcgas currently
+
+  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

+ 23 - 15
compiler/powerpc/agppcgas.pas

@@ -173,10 +173,12 @@ unit agppcgas;
            if (symaddr <> refs_full) then
              s := s+')'+symaddr2str[symaddr];
 
+{$ifndef notranslation}
            if (index.enum < firstreg) or (index.enum > lastreg) then
              internalerror(20030312);
            if (base.enum < firstreg) or (base.enum > lastreg) then
              internalerror(200303123);
+{$endif notranslation}
            if (index.enum=R_NO) and (base.enum<>R_NO) then
              begin
                 if offset=0 then
@@ -186,12 +188,20 @@ unit agppcgas;
                      else
                        s:=s+'0';
                   end;
+{$ifndef notranslation}
                 s:=s+'('+gas_reg2str[base.enum]+')'
+{$else not notranslation}
+                s:=s+'(r'+tostr(ord(base.enum)-1)+')'
+{$endif notranslation}
              end
            else if (index.enum<>R_NO) and (base.enum<>R_NO) and (offset=0) then
+{$ifndef notranslation}
              s:=s+gas_reg2str[base.enum]+','+gas_reg2str[index.enum]
            else if ((index.enum<>R_NO) or (base.enum<>R_NO)) then
              internalerror(19992);
+{$else not notranslation}
+             s:=s+'r'+tostr(ord(base.enum)-1)+',r'+tostr(ord(index.enum)-1);
+{$endif notranslation}
         end;
       getreferencestring:=s;
     end;
@@ -224,14 +234,7 @@ unit agppcgas;
         top_none:
           getopstr_jmp:='';
         else
-{$ifndef testing}
           internalerror(2002070603);
-{$else testing}
-          begin
-            writeln('internalerror 10001');
-            halt(1);
-          end;
-{$endif testing}
       end;
     end;
 
@@ -242,9 +245,13 @@ unit agppcgas;
       case o.typ of
         top_reg:
           begin
+{$ifndef notranslation}
             if (o.reg.enum < R_0) or (o.reg.enum > lastreg) then
               internalerror(200303125);
             getopstr:=gas_reg2str[o.reg.enum];
+{$else not notranslation}
+            getopstr:='r'+tostr(ord(o.reg.enum)-1);
+{$endif not notranslation}
           end;
         top_const:
           getopstr:=tostr(longint(o.val));
@@ -261,14 +268,7 @@ unit agppcgas;
             getopstr:=hs;
           end;
         else
-{$ifndef testing}
           internalerror(2002070604);
-{$else testing}
-          begin
-            writeln('internalerror 10001');
-            halt(1);
-          end;
-{$endif testing}
       end;
     end;
 
@@ -379,7 +379,15 @@ begin
 end.
 {
   $Log$
-  Revision 1.23  2003-04-24 22:29:58  florian
+  Revision 1.24  2003-08-17 16:59:20  jonas
+    * fixed regvars so they work with newra (at least for ppc)
+    * fixed some volatile register bugs
+    + -dnotranslation option for -dnewra, which causes the registers not to
+      be translated from virtual to normal registers. Requires support in
+      the assembler writer as well, which is only implemented in aggas/
+      agppcgas currently
+
+  Revision 1.23  2003/04/24 22:29:58  florian
     * fixed a lot of PowerPC related stuff
 
   Revision 1.22  2003/04/23 12:35:35  florian

+ 19 - 2
compiler/powerpc/cgcpu.pas

@@ -1034,6 +1034,8 @@ const
 
         usesfpr:=false;
         if not (po_assembler in current_procinfo.procdef.procoptions) then
+{$warning FIXME!!}
+          { FIXME: has to be R_F8 instad of R_F14 for SYSV abi }
           for regcounter.enum:=R_F14 to R_F31 do
             if regcounter.enum in rg.used_in_proc_other then
               begin
@@ -1217,7 +1219,14 @@ const
                         reference_reset_base(href,current_procinfo.framepointer,tvarsym(hp.parasym).adjusted_address);
                         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
+{$ifdef newra2}
+                    else if (hp.calleeparaloc.loc in [LOC_REGISTER,LOC_CREGISTER]) then
+                      begin
+                        rg.getexplicitregisterint(list,hp.calleeparaloc.register.number);
+                      end
+{$endif newra}
+                      ;
                     hp := tparaitem(hp.next);
                   end;
               end;
@@ -2672,7 +2681,15 @@ begin
 end.
 {
   $Log$
-  Revision 1.119  2003-08-11 21:18:20  peter
+  Revision 1.120  2003-08-17 16:59:20  jonas
+    * fixed regvars so they work with newra (at least for ppc)
+    * fixed some volatile register bugs
+    + -dnotranslation option for -dnewra, which causes the registers not to
+      be translated from virtual to normal registers. Requires support in
+      the assembler writer as well, which is only implemented in aggas/
+      agppcgas currently
+
+  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

+ 20 - 39
compiler/powerpc/cpubase.pas

@@ -239,6 +239,10 @@ uses
 
       { registers which may be destroyed by calls }
       VOLATILE_INTREGISTERS = [RS_R3..RS_R12];
+{$warning FIXME!!}
+      { FIXME: only R_F1..R_F8 under the SYSV ABI -> has to become a }
+      {   typed const (JM) 																					 }
+      VOLATILE_FPUREGISTERS = [R_F3..R_F13];
       {Number of first and last imaginary register.}
       first_imreg     = $21;
       last_imreg      = $ff;
@@ -508,6 +512,8 @@ uses
       { c_countusableregsxxx = amount of registers in the usableregsxxx set    }
 
       maxintregs = 18;
+      { to determine how many registers to use for regvars }
+      maxintscratchregs = 3;
       intregs    = [R_0..R_31];
       usableregsint = [RS_R13..RS_R27];
       c_countusableregsint = 18;
@@ -835,48 +841,15 @@ implementation
     procedure convert_register_to_enum(var r:Tregister);
       begin
         if r.enum = R_INTREGISTER then
+{$ifndef notranslation}
          if (r.number >= NR_NO) and
             (r.number <= NR_R31) then
+{$endif not notranslation}
            r.enum := toldregister(r.number shr 8)
+{$ifndef notranslation}
          else
-{        case r.number of
-            NR_NO: r.enum:= R_NO;
-
-            NR_R0: r.enum:= R_0;
-            NR_R1: r.enum:= R_1;
-            NR_R2: r.enum:= R_2;
-            NR_R3: r.enum:= R_3;
-            NR_R4: r.enum:= R_4;
-            NR_R5: r.enum:= R_5;
-            NR_R6: r.enum:= R_6;
-            NR_R7: r.enum:= R_7;
-            NR_R8: r.enum:= R_8;
-            NR_R9: r.enum:= R_9;
-            NR_R10: r.enum:= R_10;
-            NR_R11: r.enum:= R_11;
-            NR_R12: r.enum:= R_12;
-            NR_R13: r.enum:= R_13;
-            NR_R14: r.enum:= R_14;
-            NR_R15: r.enum:= R_15;
-            NR_R16: r.enum:= R_16;
-            NR_R17: r.enum:= R_17;
-            NR_R18: r.enum:= R_18;
-            NR_R19: r.enum:= R_19;
-            NR_R20: r.enum:= R_20;
-            NR_R21: r.enum:= R_21;
-            NR_R22: r.enum:= R_22;
-            NR_R23: r.enum:= R_23;
-            NR_R24: r.enum:= R_24;
-            NR_R25: r.enum:= R_25;
-            NR_R26: r.enum:= R_26;
-            NR_R27: r.enum:= R_27;
-            NR_R28: r.enum:= R_28;
-            NR_R29: r.enum:= R_29;
-            NR_R30: r.enum:= R_30;
-            NR_R31: r.enum:= R_31;
-        else}
-            internalerror(200301082);
-{        end;}
+           internalerror(200301082);
+{$endif notranslation}
       end;
 
 
@@ -888,7 +861,15 @@ implementation
 end.
 {
   $Log$
-  Revision 1.63  2003-08-08 15:51:16  olle
+  Revision 1.64  2003-08-17 16:59:20  jonas
+    * fixed regvars so they work with newra (at least for ppc)
+    * fixed some volatile register bugs
+    + -dnotranslation option for -dnewra, which causes the registers not to
+      be translated from virtual to normal registers. Requires support in
+      the assembler writer as well, which is only implemented in aggas/
+      agppcgas currently
+
+  Revision 1.63  2003/08/08 15:51:16  olle
     * merged macos entry/exit code generation into the general one.
 
   Revision 1.62  2003/07/23 11:00:09  jonas

+ 53 - 9
compiler/psub.pas

@@ -88,7 +88,7 @@ implementation
        pbase,pstatmnt,pdecl,pdecsub,pexports,
        { codegen }
        tgobj,rgobj,
-       ncgutil
+       ncgutil,regvars
        {$ifndef NOOPT}
          {$ifdef i386}
            ,aopt386
@@ -569,7 +569,7 @@ implementation
         oldprocinfo : tprocinfo;
         oldaktmaxfpuregisters : longint;
         oldfilepos : tfileposinfo;
-        templist,
+        templist, templist2,
         stackalloccode : Taasmoutput;
         usesacc,
         usesfpu,
@@ -592,15 +592,33 @@ implementation
         aktbreaklabel:=nil;
         aktcontinuelabel:=nil;
         templist:=Taasmoutput.create;
+        templist2:=Taasmoutput.create;
 
         { add parast/localst to symtablestack }
         add_to_symtablestack;
 
         { reset the temporary memory }
         rg.cleartempgen;
-{        exclude(rg.unusedregsint,RS_STACK_POINTER_REG);}
-        rg.used_in_proc_int:=[{RS_STACK_POINTER_REG}];
-        rg.used_in_proc_other:=[];
+
+{$warning FIXME!!}
+        { FIXME!! If a procedure contains assembler blocks (or is pure assembler), }
+        { then rg.used_in_proc_int already contains info because of that. However, }
+        { adding that info happened before initialisation of rg.used_in_proc_int,  }
+        { so this info cannot be valid! Currently only changing this for entire    }
+        { assembler procedures... For non-i386, the changed registers are even     }
+        { always all volatile registers (JM)                                       }
+{$ifdef i386}
+        if not(po_assembler in current_procinfo.procdef.procoptions) then
+          begin
+            rg.used_in_proc_int:=[{RS_STACK_POINTER_REG}];
+            rg.used_in_proc_other:=[];
+          end
+        else
+{$endif i386}
+          begin
+            rg.used_in_proc_int:={$ifdef i386}[]{$else}VOLATILE_INTREGISTERS{$endif};
+            rg.used_in_proc_other:=VOLATILE_FPUREGISTERS;
+          end;
 
         { set the start offset to the start of the temp area in the stack }
         tg.setfirsttemp(firsttemp_offset);
@@ -613,8 +631,6 @@ implementation
         aktlocalswitches:=entryswitches;
         gen_initialize_code(templist,false);
         aktproccode.insertlistafter(tasmnode(initasmnode).currenttai,templist);
-        gen_entry_code(templist,false);
-        aktproccode.insertlist(templist);
 
         { now generate finalize and exit code with the correct position
           and switches }
@@ -629,13 +645,29 @@ implementation
         else
           aktproccode.concatlist(templist);
 
+{$ifdef newra}
+        { note: this must be done only after as much code as possible has  }
+        {   been generated. The result is that when you ungetregister() a  }
+        {   regvar, it will actually free the regvar (and alse free the    }
+        {   the regvars at the same time). Doing this too early will       }
+        {   confuse the register allocator, as the regvars will still be   }
+        {   used. It should be done before loading the result regs (so     }
+        {   they don't conflict with the regvars) and before               }
+        {   gen_entry_code (that one has to be able to allocate the        }
+        {   regvars again) (JM)                                            }
+        free_regvars(aktproccode);
+{$endif newra}
         { handle return value, this is not done for assembler routines when
           they didn't reference the result variable }
         usesacc:=false;
         usesfpu:=false;
         usesacchi:=false;
-        gen_load_return_value(aktproccode,usesacc,usesacchi,usesfpu);
+        gen_load_return_value(templist2,usesacc,usesacchi,usesfpu);
 
+        gen_entry_code(templist,false);
+        aktproccode.insertlist(templist);
+
+        aktproccode.concatlist(templist2);
 {$ifdef newra}
 {$ifdef ra_debug2}
         rg.writegraph;
@@ -663,6 +695,9 @@ implementation
 {$endif newra}
           end;
 
+{$ifdef newra}
+        translate_regvars(aktproccode,rg.colour);
+{$endif newra}
         stackalloccode:=Taasmoutput.create;
         gen_stackalloc_code(stackalloccode);
         stackalloccode.convert_registers;
@@ -706,6 +741,7 @@ implementation
 
         { restore }
         templist.free;
+        templist2.free;
         aktmaxfpuregisters:=oldaktmaxfpuregisters;
         aktfilepos:=oldfilepos;
         current_procinfo:=oldprocinfo;
@@ -1266,7 +1302,15 @@ begin
 end.
 {
   $Log$
-  Revision 1.133  2003-07-23 11:04:15  jonas
+  Revision 1.134  2003-08-17 16:59:20  jonas
+    * fixed regvars so they work with newra (at least for ppc)
+    * fixed some volatile register bugs
+    + -dnotranslation option for -dnewra, which causes the registers not to
+      be translated from virtual to normal registers. Requires support in
+      the assembler writer as well, which is only implemented in aggas/
+      agppcgas currently
+
+  Revision 1.133  2003/07/23 11:04:15  jonas
     * split en_exit_code into a part that may allocate a register and a part
       that doesn't, so the former can be done before the register colouring
       has been performed

+ 92 - 6
compiler/regvars.pas

@@ -39,6 +39,10 @@ interface
     procedure load_regvar(asml: TAAsmoutput; vsym: tvarsym);
     procedure load_regvar_reg(asml: TAAsmoutput; reg: tregister);
     procedure load_all_regvars(asml: TAAsmoutput);
+{$ifdef newra}
+   procedure free_regvars(list: taasmoutput);
+   procedure translate_regvars(list: taasmoutput; const table:Ttranstable);
+{$endif newra}
 
 {$ifdef i386}
     procedure sync_regvars_other(list1, list2: taasmoutput; const regvarsloaded1,
@@ -150,7 +154,6 @@ implementation
       r : Tregister;
       siz : tcgsize;
     begin
-{$ifndef newra}
       { max. optimizations     }
       { only if no asm is used }
       { and no try statement   }
@@ -171,12 +174,15 @@ implementation
               symtablestack.foreach_static({$ifdef FPCPROCVAR}@{$endif}searchregvars,@parasym);
               { copy parameter into a register ? }
               parasym:=true;
+{$ifndef newra}
 {$ifndef i386}
               if (pi_do_call in current_procinfo.flags) then
-{$endif i386}
+{$endif not i386}
+{$endif not newra}
                 begin
                   symtablestack.next.foreach_static({$ifdef FPCPROCVAR}@{$endif}searchregvars,@parasym);
                 end
+{$ifndef newra}
 {$ifndef i386}
               else
                 begin
@@ -202,24 +208,35 @@ implementation
                   end;
                 end
 {$endif not i386}
+{$endif not newra}
               ;
               { hold needed registers free }
-              for i:=maxvarregs downto maxvarregs-p.registers32+1 do
+              for i:=maxvarregs downto maxvarregs-p.registers32+1{$ifdef newra}-maxintscratchregs{$endif newra} do
                 begin
                   regvarinfo^.regvars[i]:=nil;
                   regvarinfo^.regvars_para[i] := false;
                 end;
               { now assign register }
-              for i:=1 to maxvarregs-p.registers32 do
+              for i:=1 to maxvarregs-p.registers32{$ifdef newra}-maxintscratchregs{$endif newra} do
                 begin
                   if assigned(regvarinfo^.regvars[i]) and
+{$ifdef newra}
+                    { currently we assume we can use volatile registers for all }
+                    { regvars if procedure does no call                         }
+                     (not(pi_do_call in current_procinfo.flags) or
+                    { otherwise, demand some (arbitrary) minimum usage }
+                      (regvarinfo^.regvars[i].refs > 100)) then
+{$else newra}
                      (rg.reg_pushes_int[varregs[i]] < regvarinfo^.regvars[i].refs) then
+{$endif newra}
                     begin
                       { register is no longer available for }
                       { expressions                          }
                       { search the register which is the most }
                       { unused                                }
+{$ifndef newra}
                       rg.makeregvarint(varregs[i]);
+{$endif newra}
 
                       { call by reference/const ? }
                       if (regvarinfo^.regvars[i].varspez in [vs_var,vs_out]) or
@@ -237,12 +254,19 @@ implementation
                       else
                         siz:=OS_32;
 
+{$ifdef newra}
+                      { allocate a register for this regvar }
+                      regvarinfo^.regvars[i].reg:=rg.getregisterint(exprasmlist,siz);
+                      { and make sure it can't be freed }
+                      rg.makeregvarint(regvarinfo^.regvars[i].reg.number shr 8);
+{$else newra}
                       regvarinfo^.regvars[i].reg.enum:=R_INTREGISTER;
                       regvarinfo^.regvars[i].reg.number:=(varregs[i] shl 8) or cgsize2subreg(siz);
 {$ifdef i386}
                       { procedure uses this register }
                       include(rg.used_in_proc_int,varregs[i]);
 {$endif i386}
+{$endif newra}
                     end
                   else
                     begin
@@ -304,7 +328,6 @@ implementation
                   end;
               end;
         end;
-{$endif}
      end;
 
 
@@ -476,6 +499,7 @@ implementation
           { can happen when inlining assembler procedures (JM) }
           if not assigned(regvarinfo) then
             exit;
+{$ifndef newra}
           for i:=1 to maxvarregs do
             begin
              if assigned(regvarinfo^.regvars[i]) then
@@ -490,6 +514,7 @@ implementation
                   tostr(regvarinfo^.regvars[i].refs),regvarinfo^.regvars[i].name);
                end;
             end;
+{$endif newra}
           for i:=1 to maxfpuvarregs do
             begin
               if assigned(regvarinfo^.fpuregvars[i]) then
@@ -594,29 +619,90 @@ implementation
                   reg:=regvars[i].reg;
                   if reg.enum=R_INTREGISTER then
                     begin
+{$ifndef newra}
                       if (reg.number shr 8 in rg.regvar_loaded_int) then
                        asml.concat(tai_regalloc.dealloc(reg));
+{$endif newra}
                     end
                   else
                     begin
                       reg.number:=(reg.number and not $ff) or cgsize2subreg(OS_INT);
                       r:=reg;
                       convert_register_to_enum(r);
+{$ifndef notranslation}
                       if r.enum>lastreg then
                         internalerror(200201081);
                       if (rg.regvar_loaded_other[r.enum]) then
                        asml.concat(tai_regalloc.dealloc(reg));
+{$endif notranslation}
                     end;
                 end;
              end;
           end;
     end;
 
+
+{$ifdef newra}
+    procedure free_regvars(list: taasmoutput);
+      var
+        i: longint;
+      begin
+        if not assigned(current_procinfo.procdef.regvarinfo) then
+          exit;
+        with pregvarinfo(current_procinfo.procdef.regvarinfo)^ do
+          for i := 1 to maxvarregs do
+            if assigned(regvars[i]) { and
+              (regvars[i] <> tvarsym(current_procinfo.procdef.funcretsym))} then
+              begin
+                { make sure the unget isn't just a nop }
+                exclude(rg.is_reg_var_int,regvars[i].reg.number shr 8);
+                rg.ungetregisterint(list,regvars[i].reg);
+              end;
+      end;
+
+
+    procedure translate_regvars(list: taasmoutput; const table:Ttranstable);
+      var
+        i: longint;
+        r: tregister;
+      begin
+{$ifndef notranslation}
+        if not assigned(current_procinfo.procdef.regvarinfo) then
+          exit;
+        with pregvarinfo(current_procinfo.procdef.regvarinfo)^ do
+          for i := 1 to maxvarregs do
+            if assigned(regvars[i]) { and
+              (regvars[i] <> tvarsym(current_procinfo.procdef.funcretsym))} then
+              begin
+                regvars[i].reg.number :=
+                  (regvars[i].reg.number and $ff) or
+                  (table[regvars[i].reg.number shr 8] shl 8);
+                r:=regvars[i].reg;
+                convert_register_to_enum(r);
+                if cs_asm_source in aktglobalswitches then
+                 list.insert(tai_comment.Create(strpnew(regvars[i].name+
+                  ' with weight '+tostr(regvars[i].refs)+' assigned to register '+
+                  std_reg2str[r.enum])));
+                Message3(cg_d_register_weight,std_reg2str[r.enum],
+                  tostr(regvars[i].refs),regvars[i].name);
+              end;
+{$endif notranslation}
+      end;
+{$endif newra}
+
 end.
 
 {
   $Log$
-  Revision 1.60  2003-08-11 21:18:20  peter
+  Revision 1.61  2003-08-17 16:59:20  jonas
+    * fixed regvars so they work with newra (at least for ppc)
+    * fixed some volatile register bugs
+    + -dnotranslation option for -dnewra, which causes the registers not to
+      be translated from virtual to normal registers. Requires support in
+      the assembler writer as well, which is only implemented in aggas/
+      agppcgas currently
+
+  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

+ 14 - 3
compiler/rgobj.pas

@@ -676,6 +676,9 @@ unit rgobj;
 {$ifndef newra}
       if not(supreg in usableregs) then
         exit;
+{$else}
+      if supreg in is_reg_var_int then
+        exit;
 {$endif}
 {$ifdef TEMPREGDEBUG}
          if (supreg in unusedregs) then
@@ -1310,13 +1313,13 @@ unit rgobj;
     procedure trgobj.makeregvarint(reg:Tsuperregister);
       begin
         dec(countusableregsint);
+        include(is_reg_var_int,reg);
       {$ifndef newra}
         dec(countunusedregsint);
-      {$endif}
         exclude(usableregsint,reg);
         exclude(unusedregsint,reg);
-        include(is_reg_var_int,reg);
         include(used_in_proc_int,reg);
+      {$endif}
       end;
 
     procedure trgobj.makeregvarother(reg: tregister);
@@ -2560,7 +2563,15 @@ end.
 
 {
   $Log$
-  Revision 1.65  2003-08-17 14:32:48  daniel
+  Revision 1.66  2003-08-17 16:59:20  jonas
+    * fixed regvars so they work with newra (at least for ppc)
+    * fixed some volatile register bugs
+    + -dnotranslation option for -dnewra, which causes the registers not to
+      be translated from virtual to normal registers. Requires support in
+      the assembler writer as well, which is only implemented in aggas/
+      agppcgas currently
+
+  Revision 1.65  2003/08/17 14:32:48  daniel
     * Precoloured nodes now have an infinite degree approached with 255,
       like they should.
 

+ 13 - 2
compiler/sparc/cpubase.pas

@@ -363,7 +363,8 @@ uses
 {$warning FIXME!!}
       { registers which may be destroyed by calls }
       VOLATILE_INTREGISTERS = [first_supreg..last_supreg];
-
+{$warning FIXME!!}
+      VOLATILE_FPUREGISTERS = [];
 
       first_imreg = $21;
       last_imreg = $ff;
@@ -766,6 +767,8 @@ type
       { c_countusableregsxxx = amount of registers in the usableregsxxx set    }
 
       maxintregs = 8;
+      { to determine how many registers to use for regvars }
+      maxintscratchregs = 3;      
       intregs = [R_G0..R_I7];
       usableregsint = [RS_L0..RS_L7];
       c_countusableregsint = 8;
@@ -1054,7 +1057,15 @@ implementation
 end.
 {
   $Log$
-  Revision 1.45  2003-07-06 17:58:22  peter
+  Revision 1.46  2003-08-17 16:59:20  jonas
+    * fixed regvars so they work with newra (at least for ppc)
+    * fixed some volatile register bugs
+    + -dnotranslation option for -dnewra, which causes the registers not to
+      be translated from virtual to normal registers. Requires support in
+      the assembler writer as well, which is only implemented in aggas/
+      agppcgas currently
+
+  Revision 1.45  2003/07/06 17:58:22  peter
     * framepointer fixes for sparc
     * parent framepointer code more generic
 

+ 12 - 1
compiler/x86/cpubase.pas

@@ -178,6 +178,7 @@ uses
 
       { registers which may be destroyed by calls }
       VOLATILE_INTREGISTERS = [first_supreg..last_supreg]-[RS_EBP,RS_ESP];
+      VOLATILE_FPUREGISTERS = [];
 
       {Number of first and last imaginary register.}
       first_imreg     = $12;
@@ -522,6 +523,8 @@ uses
 
       maxintregs = 4;
       intregs = [R_EAX..R_BL]-[R_ESI,R_SI];
+      { to determine how many registers to use for regvars }
+      maxintscratchregs = 1;
 
       maxfpuregs = 8;
       fpuregs = [R_ST0..R_ST7];
@@ -732,7 +735,15 @@ implementation
 end.
 {
   $Log$
-  Revision 1.11  2003-07-06 21:50:33  jonas
+  Revision 1.12  2003-08-17 16:59:20  jonas
+    * fixed regvars so they work with newra (at least for ppc)
+    * fixed some volatile register bugs
+    + -dnotranslation option for -dnewra, which causes the registers not to
+      be translated from virtual to normal registers. Requires support in
+      the assembler writer as well, which is only implemented in aggas/
+      agppcgas currently
+
+  Revision 1.11  2003/07/06 21:50:33  jonas
     * fixed ppc compilation problems and changed VOLATILE_REGISTERS for x86
       so that it doesn't include ebp and esp anymore