Browse Source

* reg allocations for imaginary register are now inserted just
before reg allocation
* tregister changed to enum to allow compile time check
* fixed several tregister-tsuperregister errors

peter 21 years ago
parent
commit
1367e342db

+ 19 - 2
compiler/aasmtai.pas

@@ -447,6 +447,7 @@ interface
 
       Taasmoutput=class;
 
+      tadd_reg_instruction_proc=procedure(instr:Tai;r:tregister) of object;
       Trggetproc=procedure(list:Taasmoutput;position:Tai;subreg:Tsubregister;var result:Tregister) of object;
       Trgungetproc=procedure(list:Taasmoutput;position:Tai;r:Tregister) of object;
 
@@ -491,7 +492,7 @@ interface
           procedure loadoper(opidx:longint;o:toper);
           procedure clearop(opidx:longint);
           function is_nop:boolean;virtual;abstract;
-          function is_move:boolean;virtual;abstract;
+          function is_reg_move:boolean;virtual;abstract;
           { register allocator }
           function get_insert_pos(p:Tai;huntfor1,huntfor2,huntfor3:Tsuperregister;var live_registers_int:Tsuperregisterworklist):Tai;
           procedure forward_allocation(p:Tai;var {unusedregsint:tsuperregisterset}live_registers_int:Tsuperregisterworklist);
@@ -542,6 +543,9 @@ interface
       { label when the result is true or false }
       truelabel,falselabel : tasmlabel;
 
+      { hook to notify uses of registers }
+      add_reg_instruction_hook : tadd_reg_instruction_proc;
+
       { default lists }
       datasegment,codesegment,bsssegment,
       debuglist,withdebuglist,consts,
@@ -1677,6 +1681,8 @@ implementation
               segprefix:=ref^.segment;
 {$endif}
             typ:=top_ref;
+            add_reg_instruction_hook(self,ref^.base);
+            add_reg_instruction_hook(self,ref^.index);
             { mark symbol as used }
             if assigned(ref^.symbol) then
               ref^.symbol.increfs;
@@ -1694,6 +1700,7 @@ implementation
            reg:=r;
            typ:=top_reg;
          end;
+        add_reg_instruction_hook(self,r);
 {$ifdef ARM}
         { R15 is the PC on the ARM thus moves to R15 are jumps.
           Due to speed considerations we don't use a virtual overridden method here.
@@ -1714,10 +1721,14 @@ implementation
         with oper[opidx]^ do
           begin
             case typ of
+              top_reg:
+                add_reg_instruction_hook(self,reg);
               top_ref:
                 begin
                   new(ref);
                   ref^:=o.ref^;
+                  add_reg_instruction_hook(self,ref^.base);
+                  add_reg_instruction_hook(self,ref^.index);
                 end;
 {$ifdef ARM}
               top_shifterop:
@@ -2202,7 +2213,13 @@ implementation
 end.
 {
   $Log$
-  Revision 1.60  2003-12-14 20:24:28  daniel
+  Revision 1.61  2003-12-15 21:25:48  peter
+    * reg allocations for imaginary register are now inserted just
+      before reg allocation
+    * tregister changed to enum to allow compile time check
+    * fixed several tregister-tsuperregister errors
+
+  Revision 1.60  2003/12/14 20:24:28  daniel
     * Register allocator speed optimizations
       - Worklist no longer a ringbuffer
       - No find operations are left

+ 22 - 11
compiler/cgbase.pas

@@ -133,12 +133,17 @@ interface
       {
         The new register coding:
 
-        SuperRegister   (bits 0..7)
-        Unused          (bits 8..15)
+        SuperRegister   (bits 0..15)
         Subregister     (bits 16..23)
         Register type   (bits 24..31)
+
+        TRegister is defined as an enum to make it incompatible
+        with TSuperRegister to avoid mixing them
       }
-      TRegister = type cardinal;
+      TRegister = (
+        TRegisterLowEnum := $80000000,
+        TRegisterHighEnum := $7fffffff
+      );
       TRegisterRec=packed record
 {$ifdef FPC_BIG_ENDIAN}
          regtype : Tregistertype;
@@ -316,7 +321,7 @@ implementation
     end;
 
     destructor tsuperregisterworklist.done;
-    
+
     begin
       if assigned(buf) then
         freemem(buf);
@@ -324,7 +329,7 @@ implementation
 
 
     procedure tsuperregisterworklist.add(s:tsuperregister);
-    
+
     begin
       inc(length);
       { Need to increase buffer length? }
@@ -341,14 +346,14 @@ implementation
 
 
     procedure tsuperregisterworklist.clear;
-    
+
     begin
       length:=0;
     end;
 
 
     procedure tsuperregisterworklist.deleteidx(i:word);
-    
+
     begin
       if length=0 then
         internalerror(200310144);
@@ -358,7 +363,7 @@ implementation
 
 
     function tsuperregisterworklist.get:tsuperregister;
-    
+
     begin
       if length=0 then
         internalerror(200310142);
@@ -369,9 +374,9 @@ implementation
 
 
     function tsuperregisterworklist.delete(s:tsuperregister):boolean;
-    
+
     var i:word;
-    
+
     begin
       delete:=false;
       for i:=1 to length do
@@ -569,7 +574,13 @@ finalization
 end.
 {
   $Log$
-  Revision 1.78  2003-12-14 20:24:28  daniel
+  Revision 1.79  2003-12-15 21:25:48  peter
+    * reg allocations for imaginary register are now inserted just
+      before reg allocation
+    * tregister changed to enum to allow compile time check
+    * fixed several tregister-tsuperregister errors
+
+  Revision 1.78  2003/12/14 20:24:28  daniel
     * Register allocator speed optimizations
       - Worklist no longer a ringbuffer
       - No find operations are left

+ 25 - 6
compiler/cgobj.pas

@@ -84,6 +84,7 @@ unit cgobj;
           procedure ungetregister(list:Taasmoutput;r:Tregister);virtual;
           procedure ungetreference(list:Taasmoutput;const r:Treference);virtual;
 
+          procedure add_reg_instruction(instr:Tai;r:tregister);virtual;
           procedure add_move_instruction(instr:Taicpu);virtual;
 
           function  uses_registers(rt:Tregistertype):boolean;virtual;
@@ -553,6 +554,7 @@ implementation
 
     constructor tcg.create;
       begin
+        add_reg_instruction_hook:={$ifdef FPCPROCVAR}@{$endif}add_reg_instruction;
       end;
 
 
@@ -627,6 +629,8 @@ implementation
       begin
         if r.base<>NR_NO then
           ungetregister(list,r.base);
+        if r.index<>NR_NO then
+          ungetregister(list,r.index);
       end;
 
 
@@ -657,6 +661,19 @@ implementation
       end;
 
 
+    procedure tcg.add_reg_instruction(instr:Tai;r:tregister);
+      var
+        rt : tregistertype;
+      begin
+        rt:=getregtype(r);
+        { Only add it when a register allocator is configured.
+          No IE can be generated, because the VMT is written
+          without a valid rg[] }
+        if assigned(rg[rt]) then
+          rg[rt].add_reg_instruction(instr,r);
+      end;
+
+
     procedure tcg.add_move_instruction(instr:Taicpu);
       var
         rt : tregistertype;
@@ -676,11 +693,7 @@ implementation
         for rt:=low(tregistertype) to high(tregistertype) do
           begin
             if assigned(rg[rt]) then
-              begin
-                rg[rt].check_unreleasedregs;
-                rg[rt].do_register_allocation(list,headertai);
-                rg[rt].translate_registers(list);
-              end;
+              rg[rt].do_register_allocation(list,headertai);
           end;
       end;
 
@@ -1941,7 +1954,13 @@ finalization
 end.
 {
   $Log$
-  Revision 1.138  2003-12-12 17:16:17  peter
+  Revision 1.139  2003-12-15 21:25:48  peter
+    * reg allocations for imaginary register are now inserted just
+      before reg allocation
+    * tregister changed to enum to allow compile time check
+    * fixed several tregister-tsuperregister errors
+
+  Revision 1.138  2003/12/12 17:16:17  peter
     * rg[tregistertype] added in tcg
 
   Revision 1.137  2003/12/06 22:11:47  jonas

+ 9 - 3
compiler/i386/csopt386.pas

@@ -178,7 +178,7 @@ begin
               tmpRef.base := NR_EDI;
               tmpRef.index := NR_EDI;
               for regCounter := RS_EAX to RS_EDI do
-                if writeToMemDestroysContents(NR_NO,tmpRef,regCounter,c[regCounter],dummy) then
+                if writeToMemDestroysContents(RS_INVALID,tmpRef,regCounter,c[regCounter],dummy) then
                   begin
                     exclude(regsStillValid,regCounter);
                     modifiesConflictingMemLocation := not(supreg in regsStillValid);
@@ -1954,7 +1954,7 @@ begin
                               if (memreg <> NR_NO) and
                                  (not getNextInstruction(p,hp1) or
                                   (RegLoadedWithNewValue(getsupreg(memreg),false,hp1) or
-                                   FindRegDealloc(getsupreg(regcounter),hp1))) then
+                                   FindRegDealloc(regcounter,hp1))) then
                                 begin
                                   hp1 := Tai_Marker.Create(NoPropInfoEnd);
                                   insertllitem(asml,p,p.next,hp1);
@@ -2074,7 +2074,13 @@ end.
 
 {
   $Log$
-  Revision 1.57  2003-12-15 16:08:15  jonas
+  Revision 1.58  2003-12-15 21:25:49  peter
+    * reg allocations for imaginary register are now inserted just
+      before reg allocation
+    * tregister changed to enum to allow compile time check
+    * fixed several tregister-tsuperregister errors
+
+  Revision 1.57  2003/12/15 16:08:15  jonas
     - disable removal of dead loads before a call, because register
       parameters are released before a call
     * fix storeback of registers in case of different sizes (e.g., first

+ 10 - 4
compiler/i386/daopt386.pas

@@ -1785,7 +1785,7 @@ begin
           (typ in [con_ref,con_noRemoveRef]) and
           (not(cs_UncertainOpts in aktglobalswitches) or
          { for movsl }
-           ((ref.base = RS_EDI) and (ref.index = RS_EDI)) or
+           ((ref.base = NR_EDI) and (ref.index = NR_EDI)) or
          { don't destroy if reg contains a parameter, local or global variable }
            containsPointerLoad(c)
           );
@@ -1963,7 +1963,7 @@ var
   p, prev: tai;
   hp1, hp2: tai;
 {$ifdef i386}
-  regcounter: tregister;
+  regcounter,
   supreg : tsuperregister;
 {$endif i386}
   usedregs, nodeallocregs: tregset;
@@ -2052,7 +2052,7 @@ begin
   usedRegs := usedRegs - noDeallocRegs;
   for regCounter := RS_EAX to RS_EDI do
     if regCounter in usedRegs then
-      addRegDeallocFor(list,regCounter,prev);
+      addRegDeallocFor(list,newreg(R_INTREGISTER,regCounter,R_SUBWHOLE),prev);
 {$endif i386}
 end;
 
@@ -2714,7 +2714,13 @@ end.
 
 {
   $Log$
-  Revision 1.60  2003-12-15 15:58:58  peter
+  Revision 1.61  2003-12-15 21:25:49  peter
+    * reg allocations for imaginary register are now inserted just
+      before reg allocation
+    * tregister changed to enum to allow compile time check
+    * fixed several tregister-tsuperregister errors
+
+  Revision 1.60  2003/12/15 15:58:58  peter
     * fix statedebug compile
 
   Revision 1.59  2003/12/14 22:42:14  peter

+ 8 - 2
compiler/i386/popt386.pas

@@ -1808,7 +1808,7 @@ begin
                       TmpUsedRegs := UsedRegs;
                       UpdateUsedRegs(TmpUsedRegs,tai(hp1.next));
                       if (RefsEqual(taicpu(hp2).oper[1]^.ref^, taicpu(p).oper[0]^.ref^) and
-                         not(RegUsedAfterInstruction(getsupreg(taicpu(p).oper[1]^.reg),
+                         not(RegUsedAfterInstruction(taicpu(p).oper[1]^.reg,
                               hp2, TmpUsedRegs))) then
   { change   mov            (ref), reg            }
   {          add/sub/or/... reg2/$const, reg      }
@@ -1996,7 +1996,13 @@ end.
 
 {
   $Log$
-  Revision 1.52  2003-12-14 22:42:14  peter
+  Revision 1.53  2003-12-15 21:25:49  peter
+    * reg allocations for imaginary register are now inserted just
+      before reg allocation
+    * tregister changed to enum to allow compile time check
+    * fixed several tregister-tsuperregister errors
+
+  Revision 1.52  2003/12/14 22:42:14  peter
     * fixed csdebug
 
   Revision 1.51  2003/12/13 15:48:47  jonas

+ 71 - 71
compiler/i386/r386con.inc

@@ -1,72 +1,72 @@
 { don't edit, this file is generated from x86reg.dat }
-NR_NO = $00000000;
-NR_AL = $01010000;
-NR_AH = $01020000;
-NR_AX = $01030000;
-NR_EAX = $01040000;
-NR_CL = $01010001;
-NR_CH = $01020001;
-NR_CX = $01030001;
-NR_ECX = $01040001;
-NR_DL = $01010002;
-NR_DH = $01020002;
-NR_DX = $01030002;
-NR_EDX = $01040002;
-NR_BL = $01010003;
-NR_BH = $01020003;
-NR_BX = $01030003;
-NR_EBX = $01040003;
-NR_SI = $01030004;
-NR_ESI = $01040004;
-NR_DI = $01030005;
-NR_EDI = $01040005;
-NR_BP = $01030006;
-NR_EBP = $01040006;
-NR_SP = $01030007;
-NR_ESP = $01040007;
-NR_CS = $05000001;
-NR_DS = $05000002;
-NR_ES = $05000003;
-NR_SS = $05000004;
-NR_FS = $05000005;
-NR_GS = $05000006;
-NR_DR0 = $05000007;
-NR_DR1 = $05000008;
-NR_DR2 = $05000009;
-NR_DR3 = $0500000a;
-NR_DR6 = $0500000b;
-NR_DR7 = $0500000c;
-NR_CR0 = $0500000d;
-NR_CR2 = $0500000e;
-NR_CR3 = $0500000f;
-NR_CR4 = $05000010;
-NR_TR3 = $05000011;
-NR_TR4 = $05000012;
-NR_TR5 = $05000013;
-NR_TR6 = $05000014;
-NR_TR7 = $05000015;
-NR_ST0 = $02000000;
-NR_ST1 = $02000001;
-NR_ST2 = $02000002;
-NR_ST3 = $02000003;
-NR_ST4 = $02000004;
-NR_ST5 = $02000005;
-NR_ST6 = $02000006;
-NR_ST7 = $02000007;
-NR_ST = $02000008;
-NR_MM0 = $03000000;
-NR_MM1 = $03000001;
-NR_MM2 = $03000002;
-NR_MM3 = $03000003;
-NR_MM4 = $03000004;
-NR_MM5 = $03000005;
-NR_MM6 = $03000006;
-NR_MM7 = $03000007;
-NR_XMM0 = $04000000;
-NR_XMM1 = $04000001;
-NR_XMM2 = $04000002;
-NR_XMM3 = $04000003;
-NR_XMM4 = $04000004;
-NR_XMM5 = $04000005;
-NR_XMM6 = $04000006;
-NR_XMM7 = $04000007;
+NR_NO = tregister($00000000);
+NR_AL = tregister($01010000);
+NR_AH = tregister($01020000);
+NR_AX = tregister($01030000);
+NR_EAX = tregister($01040000);
+NR_CL = tregister($01010001);
+NR_CH = tregister($01020001);
+NR_CX = tregister($01030001);
+NR_ECX = tregister($01040001);
+NR_DL = tregister($01010002);
+NR_DH = tregister($01020002);
+NR_DX = tregister($01030002);
+NR_EDX = tregister($01040002);
+NR_BL = tregister($01010003);
+NR_BH = tregister($01020003);
+NR_BX = tregister($01030003);
+NR_EBX = tregister($01040003);
+NR_SI = tregister($01030004);
+NR_ESI = tregister($01040004);
+NR_DI = tregister($01030005);
+NR_EDI = tregister($01040005);
+NR_BP = tregister($01030006);
+NR_EBP = tregister($01040006);
+NR_SP = tregister($01030007);
+NR_ESP = tregister($01040007);
+NR_CS = tregister($05000001);
+NR_DS = tregister($05000002);
+NR_ES = tregister($05000003);
+NR_SS = tregister($05000004);
+NR_FS = tregister($05000005);
+NR_GS = tregister($05000006);
+NR_DR0 = tregister($05000007);
+NR_DR1 = tregister($05000008);
+NR_DR2 = tregister($05000009);
+NR_DR3 = tregister($0500000a);
+NR_DR6 = tregister($0500000b);
+NR_DR7 = tregister($0500000c);
+NR_CR0 = tregister($0500000d);
+NR_CR2 = tregister($0500000e);
+NR_CR3 = tregister($0500000f);
+NR_CR4 = tregister($05000010);
+NR_TR3 = tregister($05000011);
+NR_TR4 = tregister($05000012);
+NR_TR5 = tregister($05000013);
+NR_TR6 = tregister($05000014);
+NR_TR7 = tregister($05000015);
+NR_ST0 = tregister($02000000);
+NR_ST1 = tregister($02000001);
+NR_ST2 = tregister($02000002);
+NR_ST3 = tregister($02000003);
+NR_ST4 = tregister($02000004);
+NR_ST5 = tregister($02000005);
+NR_ST6 = tregister($02000006);
+NR_ST7 = tregister($02000007);
+NR_ST = tregister($02000008);
+NR_MM0 = tregister($03000000);
+NR_MM1 = tregister($03000001);
+NR_MM2 = tregister($03000002);
+NR_MM3 = tregister($03000003);
+NR_MM4 = tregister($03000004);
+NR_MM5 = tregister($03000005);
+NR_MM6 = tregister($03000006);
+NR_MM7 = tregister($03000007);
+NR_XMM0 = tregister($04000000);
+NR_XMM1 = tregister($04000001);
+NR_XMM2 = tregister($04000002);
+NR_XMM3 = tregister($04000003);
+NR_XMM4 = tregister($04000004);
+NR_XMM5 = tregister($04000005);
+NR_XMM6 = tregister($04000006);
+NR_XMM7 = tregister($04000007);

+ 71 - 71
compiler/i386/r386num.inc

@@ -1,72 +1,72 @@
 { don't edit, this file is generated from x86reg.dat }
-$00000000,
-$01010000,
-$01020000,
-$01030000,
-$01040000,
-$01010001,
-$01020001,
-$01030001,
-$01040001,
-$01010002,
-$01020002,
-$01030002,
-$01040002,
-$01010003,
-$01020003,
-$01030003,
-$01040003,
-$01030004,
-$01040004,
-$01030005,
-$01040005,
-$01030006,
-$01040006,
-$01030007,
-$01040007,
-$05000001,
-$05000002,
-$05000003,
-$05000004,
-$05000005,
-$05000006,
-$05000007,
-$05000008,
-$05000009,
-$0500000a,
-$0500000b,
-$0500000c,
-$0500000d,
-$0500000e,
-$0500000f,
-$05000010,
-$05000011,
-$05000012,
-$05000013,
-$05000014,
-$05000015,
-$02000000,
-$02000001,
-$02000002,
-$02000003,
-$02000004,
-$02000005,
-$02000006,
-$02000007,
-$02000008,
-$03000000,
-$03000001,
-$03000002,
-$03000003,
-$03000004,
-$03000005,
-$03000006,
-$03000007,
-$04000000,
-$04000001,
-$04000002,
-$04000003,
-$04000004,
-$04000005,
-$04000006,
-$04000007
+tregister($00000000),
+tregister($01010000),
+tregister($01020000),
+tregister($01030000),
+tregister($01040000),
+tregister($01010001),
+tregister($01020001),
+tregister($01030001),
+tregister($01040001),
+tregister($01010002),
+tregister($01020002),
+tregister($01030002),
+tregister($01040002),
+tregister($01010003),
+tregister($01020003),
+tregister($01030003),
+tregister($01040003),
+tregister($01030004),
+tregister($01040004),
+tregister($01030005),
+tregister($01040005),
+tregister($01030006),
+tregister($01040006),
+tregister($01030007),
+tregister($01040007),
+tregister($05000001),
+tregister($05000002),
+tregister($05000003),
+tregister($05000004),
+tregister($05000005),
+tregister($05000006),
+tregister($05000007),
+tregister($05000008),
+tregister($05000009),
+tregister($0500000a),
+tregister($0500000b),
+tregister($0500000c),
+tregister($0500000d),
+tregister($0500000e),
+tregister($0500000f),
+tregister($05000010),
+tregister($05000011),
+tregister($05000012),
+tregister($05000013),
+tregister($05000014),
+tregister($05000015),
+tregister($02000000),
+tregister($02000001),
+tregister($02000002),
+tregister($02000003),
+tregister($02000004),
+tregister($02000005),
+tregister($02000006),
+tregister($02000007),
+tregister($02000008),
+tregister($03000000),
+tregister($03000001),
+tregister($03000002),
+tregister($03000003),
+tregister($03000004),
+tregister($03000005),
+tregister($03000006),
+tregister($03000007),
+tregister($04000000),
+tregister($04000001),
+tregister($04000002),
+tregister($04000003),
+tregister($04000004),
+tregister($04000005),
+tregister($04000006),
+tregister($04000007)

+ 15 - 8
compiler/ncgcal.pas

@@ -113,7 +113,7 @@ implementation
         if not(left.location.loc in [LOC_CREFERENCE,LOC_REFERENCE]) then
           internalerror(200304235);
         location_release(exprasmlist,left.location);
-        allocate_tempparaloc;
+//        allocate_tempparaloc;
         cg.a_paramaddr_ref(exprasmlist,left.location.reference,tempparaloc);
         inc(tcgcallnode(aktcallnode).pushedparasize,POINTER_SIZE);
       end;
@@ -137,7 +137,7 @@ implementation
         if left.resulttype.def.deftype=floatdef then
          begin
            location_release(exprasmlist,left.location);
-           allocate_tempparaloc;
+//           allocate_tempparaloc;
 {$ifdef i386}
            if tempparaloc.loc<>LOC_REFERENCE then
              internalerror(200309291);
@@ -215,7 +215,6 @@ implementation
                   aktcallnode.procdefinition.proccalloption) then
             begin
               location_release(exprasmlist,left.location);
-              allocate_tempparaloc;
 {$ifdef i386}
               if tempparaloc.loc<>LOC_REFERENCE then
                 internalerror(200309292);
@@ -249,14 +248,14 @@ implementation
                     if cgsize in [OS_64,OS_S64] then
                      begin
                        inc(tcgcallnode(aktcallnode).pushedparasize,8);
-                       allocate_tempparaloc;
+//                       allocate_tempparaloc;
                        cg64.a_param64_loc(exprasmlist,left.location,tempparaloc);
                        location_release(exprasmlist,left.location);
                      end
                     else
                      begin
                        location_release(exprasmlist,left.location);
-                       allocate_tempparaloc;
+//                       allocate_tempparaloc;
                        inc(tcgcallnode(aktcallnode).pushedparasize,align(tcgsize2size[tempparaloc.size],tempparaloc.alignment));
                        cg.a_param_loc(exprasmlist,left.location,tempparaloc);
                      end;
@@ -266,7 +265,7 @@ implementation
                 LOC_CMMXREGISTER:
                   begin
                      location_release(exprasmlist,left.location);
-                     allocate_tempparaloc;
+//                     allocate_tempparaloc;
                      inc(tcgcallnode(aktcallnode).pushedparasize,8);
                      cg.a_parammm_reg(exprasmlist,left.location.register);
                   end;
@@ -301,6 +300,8 @@ implementation
              objectlibrary.getlabel(falselabel);
              secondpass(left);
 
+             allocate_tempparaloc;
+
              { handle varargs first, because paraitem.parasym is not valid }
              if (nf_varargs_para in flags) then
                begin
@@ -337,7 +338,7 @@ implementation
                     begin
                       inc(tcgcallnode(aktcallnode).pushedparasize,POINTER_SIZE);
                       location_release(exprasmlist,left.location);
-                      allocate_tempparaloc;
+//                      allocate_tempparaloc;
                       cg.a_param_loc(exprasmlist,left.location,tempparaloc);
                     end
                   else
@@ -1129,7 +1130,13 @@ begin
 end.
 {
   $Log$
-  Revision 1.145  2003-12-07 12:41:32  jonas
+  Revision 1.146  2003-12-15 21:25:48  peter
+    * reg allocations for imaginary register are now inserted just
+      before reg allocation
+    * tregister changed to enum to allow compile time check
+    * fixed several tregister-tsuperregister errors
+
+  Revision 1.145  2003/12/07 12:41:32  jonas
     * fixed ansistring/widestring results: deallocate result reg only after
       it has been stored to memory, as the storing itself may require extra
       results (e.g. on ppc)

+ 28 - 16
compiler/pdecl.pas

@@ -526,26 +526,32 @@ implementation
                   tt.def.needs_inittable) then
                 generate_inittable(newtype);
 
-              { Always generate RTTI info for all types. This is to have typeinfo() return
-                the same pointer }
-              generate_rtti(newtype);
-
               { for objects we should write the vmt and interfaces.
                 This need to be done after the rtti has been written, because
                 it can contain a reference to that data (PFV)
                 This is not for forward classes }
-              if (tt.def.deftype=objectdef) and
-                 not(oo_is_forward in tobjectdef(tt.def).objectoptions) then
+              if (tt.def.deftype=objectdef) then
+               begin
+                 if not(oo_is_forward in tobjectdef(tt.def).objectoptions) then
+                   begin
+                     ch:=cclassheader.create(tobjectdef(tt.def));
+                     { generate and check virtual methods, must be done
+                       before RTTI is written }
+                     ch.genvmt;
+                     { Generate RTTI for class }
+                     generate_rtti(newtype);
+                     if is_interface(tobjectdef(tt.def)) then
+                       ch.writeinterfaceids;
+                     if (oo_has_vmt in tobjectdef(tt.def).objectoptions) then
+                       ch.writevmt;
+                     ch.free;
+                   end;
+               end
+              else
                begin
-                 ch:=cclassheader.create(tobjectdef(tt.def));
-                 { generate and check virtual methods, must be done
-                   before RTTI is written }
-                 ch.genvmt;
-                 if is_interface(tobjectdef(tt.def)) then
-                   ch.writeinterfaceids;
-                 if (oo_has_vmt in tobjectdef(tt.def).objectoptions) then
-                   ch.writevmt;
-                 ch.free;
+                 { Always generate RTTI info for all types. This is to have typeinfo() return
+                   the same pointer }
+                 generate_rtti(newtype);
                end;
 
               aktfilepos:=oldfilepos;
@@ -656,7 +662,13 @@ implementation
 end.
 {
   $Log$
-  Revision 1.74  2003-12-12 12:09:40  marco
+  Revision 1.75  2003-12-15 21:25:48  peter
+    * reg allocations for imaginary register are now inserted just
+      before reg allocation
+    * tregister changed to enum to allow compile time check
+    * fixed several tregister-tsuperregister errors
+
+  Revision 1.74  2003/12/12 12:09:40  marco
    * always generate RTTI patch from peter
 
   Revision 1.73  2003/12/10 16:37:01  peter

+ 8 - 5
compiler/psub.pas

@@ -749,10 +749,7 @@ implementation
 
             { The procedure body is finished, we can now
               allocate the registers }
-            if not(cs_no_regalloc in aktglobalswitches) then
-              begin
-                cg.do_register_allocation(aktproccode,headertai);
-              end;
+            cg.do_register_allocation(aktproccode,headertai);
 
             { Add save and restore of used registers }
             aktfilepos:=entrypos;
@@ -1333,7 +1330,13 @@ implementation
 end.
 {
   $Log$
-  Revision 1.176  2003-12-10 16:37:01  peter
+  Revision 1.177  2003-12-15 21:25:48  peter
+    * reg allocations for imaginary register are now inserted just
+      before reg allocation
+    * tregister changed to enum to allow compile time check
+    * fixed several tregister-tsuperregister errors
+
+  Revision 1.176  2003/12/10 16:37:01  peter
     * global property support for fpc modes
 
   Revision 1.175  2003/12/03 23:13:20  peter

+ 179 - 88
compiler/rgobj.pas

@@ -146,6 +146,9 @@ unit rgobj;
       Treginfoflagset=set of Treginfoflag;
 
       Treginfo=record
+        live_start,
+        live_end   : Tai;
+        subreg   : tsubregister;
         alias    : Tsuperregister;
         { The register allocator assigns each register a colour }
         colour   : Tsuperregister;
@@ -156,21 +159,6 @@ unit rgobj;
       end;
       Preginfo=^TReginfo;
 
-      { This is the base class used for a register allocator. }
-      trgbase=class
-        function getregister(list:Taasmoutput;subreg:Tsubregister):Tregister;virtual;abstract;
-        {# Get the register specified.}
-        procedure getexplicitregister(list:Taasmoutput;r:Tregister);virtual;abstract;
-        {# Get multiple registers specified.}
-        procedure allocexplicitregisters(list:Taasmoutput;r:Tcpuregisterset);virtual;abstract;
-        {# Free multiple registers specified.}
-        procedure deallocexplicitregisters(list:Taasmoutput;r:Tcpuregisterset);virtual;abstract;
-        function uses_registers:boolean;virtual;abstract;
-        {# Deallocate any kind of register }
-        procedure ungetregister(list:Taasmoutput;r:Tregister);virtual;abstract;
-      end;
-
-
       {#------------------------------------------------------------------
 
       This class implements the default register allocator. It is used by the
@@ -181,7 +169,7 @@ unit rgobj;
       by cpu-specific implementations.
 
       --------------------------------------------------------------------}
-      trgobj=class(trgbase)
+      trgobj=class
         preserved_by_proc : tcpuregisterset;
         used_in_proc : tcpuregisterset;
 //        is_reg_var : Tsuperregisterset; {old regvars}
@@ -206,37 +194,18 @@ unit rgobj;
         function uses_registers:boolean;virtual;
         {# Deallocate any kind of register }
         procedure ungetregister(list:Taasmoutput;r:Tregister);virtual;
-        procedure add_constraints(reg:Tregister);virtual;
-
+        procedure add_reg_instruction(instr:Tai;r:tregister);
+        procedure add_move_instruction(instr:Taicpu);
         {# Do the register allocation.}
         procedure do_register_allocation(list:Taasmoutput;headertai:tai);virtual;
-
-{        procedure resetusableregisters;virtual;}
-
-{        procedure makeregvar(reg:Tsuperregister);}
-
-{$ifdef EXTDEBUG}
-        procedure writegraph(loopidx:longint);
-{$endif EXTDEBUG}
-        procedure add_move_instruction(instr:Taicpu);
-        {# Prepare the register colouring.}
-        procedure prepare_colouring;
-        {# Clean up after register colouring.}
-        procedure epilogue_colouring;
-        {# Colour the registers; that is do the register allocation.}
-        procedure colour_registers;
-        {# Spills certain registers in the specified assembler list.}
-        function  spill_registers(list:Taasmoutput;headertai:tai):boolean;
-        procedure translate_registers(list:Taasmoutput);
-        {# Adds an interference edge.}
-        procedure add_edge(u,v:Tsuperregister);
-        procedure check_unreleasedregs;
-
-
       protected
         regtype           : Tregistertype;
         { default subregister used }
         defaultsub        : tsubregister;
+        {# Adds an interference edge.}
+        procedure add_edge(u,v:Tsuperregister);
+        procedure add_constraints(reg:Tregister);virtual;
+      private
         {# First imaginary register.}
         first_imaginary   : Tsuperregister;
         {# Highest register allocated until now.}
@@ -259,7 +228,21 @@ unit rgobj;
         coalesced_moves,
         constrained_moves : Tlinkedlist;
         live_registers:Tsuperregisterworklist;
-        function  getnewreg:tsuperregister;
+{$ifdef EXTDEBUG}
+        procedure writegraph(loopidx:longint);
+{$endif EXTDEBUG}
+        {# Prepare the register colouring.}
+        procedure prepare_colouring;
+        {# Clean up after register colouring.}
+        procedure epilogue_colouring;
+        {# Colour the registers; that is do the register allocation.}
+        procedure colour_registers;
+        {# Spills certain registers in the specified assembler list.}
+        procedure insert_regalloc_info(list:Taasmoutput;headertai:tai);
+        procedure generate_interference_graph(list:Taasmoutput;headertai:tai);
+        procedure translate_registers(list:Taasmoutput);
+        function  spill_registers(list:Taasmoutput;headertai:tai):boolean;
+        function  getnewreg(subreg:tsubregister):tsuperregister;
         procedure getregisterinline(list:Taasmoutput;position:Tai;subreg:Tsubregister;var result:Tregister);
         procedure ungetregisterinline(list:Taasmoutput;position:Tai;r:Tregister);
         procedure add_edges_used(u:Tsuperregister);
@@ -429,7 +412,7 @@ implementation
     end;
 
 
-    function trgobj.getnewreg:tsuperregister;
+    function trgobj.getnewreg(subreg:tsubregister):tsuperregister;
       var
         oldmaxreginfo : tsuperregister;
       begin
@@ -447,24 +430,16 @@ implementation
             { Do we really need it to clear it ? At least for 1.0.x (PFV) }
             fillchar(reginfo[oldmaxreginfo],(maxreginfo-oldmaxreginfo)*sizeof(treginfo),0);
           end;
+        reginfo[result].subreg:=subreg;
       end;
 
 
     function trgobj.getregister(list:Taasmoutput;subreg:Tsubregister):Tregister;
-      var
-        p : Tsuperregister;
-        r : Tregister;
       begin
-         p:=getnewreg;
-         live_registers.add(p);
          if defaultsub=R_SUBNONE then
-           r:=newreg(regtype,p,R_SUBNONE)
+           result:=newreg(regtype,getnewreg(R_SUBNONE),R_SUBNONE)
          else
-           r:=newreg(regtype,p,subreg);
-         list.concat(Tai_regalloc.alloc(r));
-         add_edges_used(p);
-         add_constraints(r);
-         result:=r;
+           result:=newreg(regtype,getnewreg(subreg),subreg);
       end;
 
 
@@ -475,29 +450,23 @@ implementation
 
 
     procedure trgobj.ungetregister(list:Taasmoutput;r:Tregister);
-
-    var supreg:Tsuperregister;
-
-    begin
-      supreg:=getsupreg(r);
-      if live_registers.delete(supreg) then
-        list.concat(Tai_regalloc.dealloc(r));
-    end;
+      begin
+        { Only explicit allocs insert regalloc info }
+        if getsupreg(r)<first_imaginary then
+          list.concat(Tai_regalloc.dealloc(r));
+      end;
 
 
     procedure trgobj.getexplicitregister(list:Taasmoutput;r:Tregister);
-
-    var supreg:Tsuperregister;
-
-    begin
-      supreg:=getsupreg(r);
-      live_registers.add(supreg);
-      if supreg<first_imaginary then
+      var
+        supreg:Tsuperregister;
+      begin
+        supreg:=getsupreg(r);
+        if supreg>=first_imaginary then
+          internalerror(2003121503);
         include(used_in_proc,supreg);
-      list.concat(Tai_regalloc.alloc(r));
-      add_edges_used(supreg);
-      add_constraints(r);
-    end;
+        list.concat(Tai_regalloc.alloc(r));
+      end;
 
 
     procedure trgobj.allocexplicitregisters(list:Taasmoutput;r:Tcpuregisterset);
@@ -507,7 +476,7 @@ implementation
     begin
       for i:=0 to first_imaginary-1 do
         if i in r then
-          getexplicitregister(list,i);
+          getexplicitregister(list,newreg(regtype,i,defaultsub));
     end;
 
 
@@ -518,7 +487,7 @@ implementation
     begin
       for i:=0 to first_imaginary-1 do
         if i in r then
-          ungetregister(list,i);
+          ungetregister(list,newreg(regtype,i,defaultsub));
     end;
 
 
@@ -527,6 +496,12 @@ implementation
         spillingcounter:byte;
         endspill:boolean;
       begin
+        { Insert regalloc info for imaginary registers }
+        insert_regalloc_info(list,headertai);
+        generate_interference_graph(list,headertai);
+        { Don't do the real allocation when -sr is passed }
+        if (cs_no_regalloc in aktglobalswitches) then
+          exit;
         {Do register allocation.}
         spillingcounter:=0;
         repeat
@@ -542,6 +517,7 @@ implementation
               endspill:=not spill_registers(list,headertai);
             end;
         until endspill;
+        translate_registers(list);
       end;
 
 
@@ -588,8 +564,9 @@ implementation
     var i:word;
 
     begin
-      for i:=0 to live_registers.length-1 do
-        add_edge(u,live_registers.buf[i]);
+      if live_registers.length>0 then
+        for i:=0 to live_registers.length-1 do
+          add_edge(u,live_registers.buf[i]);
     end;
 
 {$ifdef EXTDEBUG}
@@ -644,6 +621,21 @@ implementation
       inc(reginfo[u].movelist^.count);
     end;
 
+
+    procedure trgobj.add_reg_instruction(instr:Tai;r:tregister);
+      var
+        supreg : tsuperregister;
+      begin
+        supreg:=getsupreg(r);
+        if supreg>=first_imaginary then
+          begin
+            if not assigned(reginfo[supreg].live_start) then
+              reginfo[supreg].live_start:=instr;
+            reginfo[supreg].live_end:=instr;
+          end;
+      end;
+
+
     procedure trgobj.add_move_instruction(instr:Taicpu);
 
     {This procedure notifies a certain as a move instruction so the
@@ -827,8 +819,8 @@ implementation
     procedure trgobj.simplify;
 
     var adj : Psuperregisterworklist;
-        p,n : Tsuperregister;
-        min,i:word;
+        n : Tsuperregister;
+        i : word;
     begin
       {We take the element with the least interferences out of the
        simplifyworklist. Since the simplifyworklist is now sorted, we
@@ -1367,7 +1359,7 @@ implementation
     var p:Tsuperregister;
         r:Tregister;
     begin
-       p:=getnewreg;
+       p:=getnewreg(subreg);
        live_registers.add(p);
        r:=newreg(regtype,p,subreg);
        if position=nil then
@@ -1395,6 +1387,105 @@ implementation
     end;
 
 
+    procedure trgobj.insert_regalloc_info(list:Taasmoutput;headertai:tai);
+      var
+        supreg : tsuperregister;
+        p : tai;
+        r : tregister;
+      begin
+        { Insert regallocs for all imaginary registers }
+        for supreg:=first_imaginary to maxreg-1 do
+          begin
+            r:=newreg(regtype,supreg,reginfo[supreg].subreg);
+            if assigned(reginfo[supreg].live_start) then
+              begin
+{$ifdef EXTDEBUG}
+                if reginfo[supreg].live_start=reginfo[supreg].live_end then
+                  Comment(V_Warning,'Register '+std_regname(r)+' is only used once');
+{$endif EXTDEBUG}
+                list.insertbefore(Tai_regalloc.alloc(r),reginfo[supreg].live_start);
+                { Insert live end deallocation before reg allocations
+                  to reduce conflicts }
+                p:=reginfo[supreg].live_end;
+                while assigned(p) and
+                      assigned(p.previous) and
+                      (tai(p.previous).typ=ait_regalloc) and
+                      tai_regalloc(p.previous).allocation do
+                  p:=tai(p.previous);
+                list.insertbefore(Tai_regalloc.dealloc(r),p);
+              end
+{$ifdef EXTDEBUG}
+            else
+              Comment(V_Warning,'Register '+std_regname(r)+' not used');
+{$endif EXTDEBUG}
+          end;
+      end;
+
+
+    procedure trgobj.generate_interference_graph(list:Taasmoutput;headertai:tai);
+      var
+        p : tai;
+        i : integer;
+        supreg : tsuperregister;
+      begin
+        { All allocations are available. Now we can generate the
+          interference graph. Walk through all instructions, we can
+          start with the headertai, because before the header tai is
+          only symbols. }
+        live_registers.clear;
+        p:=headertai;
+        while assigned(p) do
+          begin
+            case p.typ of
+              ait_regalloc:
+                begin
+                  if (getregtype(Tai_regalloc(p).reg)=regtype) then
+                    begin
+                      supreg:=getsupreg(Tai_regalloc(p).reg);
+                      if Tai_regalloc(p).allocation then
+                        live_registers.add(supreg)
+                      else
+                        live_registers.delete(supreg);
+                      add_edges_used(supreg);
+                      add_constraints(Tai_regalloc(p).reg);
+                    end;
+                end;
+{              ait_instruction:
+                begin
+                  aktfilepos:=Taicpu_abstract(p).fileinfo;
+                  for i:=0 to Taicpu_abstract(p).ops-1 do
+                    with Taicpu_abstract(p).oper[i]^ do
+                      begin
+                        case typ of
+                          top_reg :
+                            begin
+                              add_edges_used(getsupreg(reg));
+                              add_constraints(reg);
+                            end;
+                          top_ref :
+                            begin
+                              add_edges_used(getsupreg(ref^.base));
+                              add_constraints(ref^.base);
+                              add_edges_used(getsupreg(ref^.index));
+                              add_constraints(ref^.index);
+                            end;
+                        end;
+                      end;
+                end; }
+            end;
+            p:=Tai(p.next);
+          end;
+
+{$ifdef EXTDEBUG}
+        if live_registers.length>0 then
+          begin
+            for i:=0 to live_registers.length-1 do
+              Comment(V_Warning,'Register '+std_regname(newreg(R_INTREGISTER,live_registers.buf[i],defaultsub))+' not released');
+          end;
+{$endif}
+      end;
+
+
     function trgobj.spill_registers(list:Taasmoutput;headertai:tai):boolean;
 
     {Returns true if any help registers have been used.}
@@ -1473,8 +1564,7 @@ implementation
                                                       live_registers,
                                                       spill_temps^) then
                   spill_registers:=true;
-
-                if Taicpu_abstract(p).is_move then
+                if Taicpu_abstract(p).is_reg_move then
                   add_move_instruction(Taicpu(p));
               end;
           end;
@@ -1579,15 +1669,16 @@ implementation
     end;
 
 
-    procedure Trgobj.check_unreleasedregs;
-      begin
-      end;
-
-
 end.
 {
   $Log$
-  Revision 1.102  2003-12-15 16:37:47  daniel
+  Revision 1.103  2003-12-15 21:25:49  peter
+    * reg allocations for imaginary register are now inserted just
+      before reg allocation
+    * tregister changed to enum to allow compile time check
+    * fixed several tregister-tsuperregister errors
+
+  Revision 1.102  2003/12/15 16:37:47  daniel
     * More microoptimizations
 
   Revision 1.101  2003/12/15 15:58:58  peter

+ 10 - 3
compiler/utils/mkx86reg.pp

@@ -13,6 +13,7 @@
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
  **********************************************************************}
+{$mode objfpc}
 {$i+}
 program mkx86reg;
 
@@ -383,8 +384,8 @@ begin
         end
       else
         first:=false;
-      writeln(confile,names[i],' = ',numbers[i],';');
-      write(numfile,numbers[i]);
+      writeln(confile,names[i],' = ','tregister(',numbers[i],')',';');
+      write(numfile,'tregister(',numbers[i],')');
       write(stdfile,'''',stdnames[i],'''');
       write(attfile,'''',attnames[i],'''');
       if not(x86_64) then
@@ -457,7 +458,13 @@ begin
 end.
 {
   $Log$
-  Revision 1.3  2003-09-24 17:11:33  florian
+  Revision 1.4  2003-12-15 21:25:49  peter
+    * reg allocations for imaginary register are now inserted just
+      before reg allocation
+    * tregister changed to enum to allow compile time check
+    * fixed several tregister-tsuperregister errors
+
+  Revision 1.3  2003/09/24 17:11:33  florian
     * x86_64 support; turn on by passing x86_64
 
   Revision 1.2  2003/09/03 15:55:02  peter

+ 10 - 4
compiler/x86/aasmcpu.pas

@@ -201,7 +201,7 @@ interface
          procedure Pass2(sec:TAsmObjectdata);virtual;
          procedure SetOperandOrder(order:TOperandOrder);
          function is_nop:boolean;override;
-         function is_move:boolean;override;
+         function is_reg_move:boolean;override;
          function spill_registers(list:Taasmoutput;
                                   rgget:Trggetproc;
                                   rgunget:Trgungetproc;
@@ -1904,7 +1904,7 @@ implementation
               (opcode=A_XCHG) and (oper[0]^.typ=top_reg) and (oper[1]^.typ=top_reg) and (oper[0]^.reg=oper[1]^.reg);
     end;
 
-    function Taicpu.is_move:boolean;
+    function Taicpu.is_reg_move:boolean;
 
     begin
       {We do not check the number of operands; we assume that nobody constructs
@@ -1912,7 +1912,7 @@ implementation
        a move between a reference and a register is not a move that is of
        interrest to the register allocation, therefore we only return true
        for a move between two registers. (DM)}
-      is_move:=((opcode=A_MOV) or (opcode=A_MOVZX) or (opcode=A_MOVSX)) and
+      result:=((opcode=A_MOV) or (opcode=A_MOVZX) or (opcode=A_MOVSX)) and
         ((oper[0]^.typ=top_reg) and (oper[1]^.typ=top_reg));
     end;
 
@@ -2344,7 +2344,13 @@ implementation
 end.
 {
   $Log$
-  Revision 1.39  2003-12-14 20:24:28  daniel
+  Revision 1.40  2003-12-15 21:25:49  peter
+    * reg allocations for imaginary register are now inserted just
+      before reg allocation
+    * tregister changed to enum to allow compile time check
+    * fixed several tregister-tsuperregister errors
+
+  Revision 1.39  2003/12/14 20:24:28  daniel
     * Register allocator speed optimizations
       - Worklist no longer a ringbuffer
       - No find operations are left

+ 24 - 20
compiler/x86/cgx86.pas

@@ -43,10 +43,10 @@ unit cgx86;
         function  getfpuregister(list:Taasmoutput;size:Tcgsize):Tregister;override;
         procedure getexplicitregister(list:Taasmoutput;r:Tregister);override;
         procedure ungetregister(list:Taasmoutput;r:Tregister);override;
-        procedure ungetreference(list:Taasmoutput;const r:Treference);override;
         procedure allocexplicitregisters(list:Taasmoutput;rt:Tregistertype;r:Tcpuregisterset);override;
         procedure deallocexplicitregisters(list:Taasmoutput;rt:Tregistertype;r:Tcpuregisterset);override;
         function  uses_registers(rt:Tregistertype):boolean;override;
+        procedure add_reg_instruction(instr:Tai;r:tregister);override;
         procedure dec_fpu_stack;
         procedure inc_fpu_stack;
 
@@ -211,15 +211,6 @@ unit cgx86;
       end;
 
 
-    procedure tcgx86.ungetreference(list:Taasmoutput;const r:Treference);
-      begin
-        if r.base<>NR_NO then
-          ungetregister(list,r.base);
-        if r.index<>NR_NO then
-          ungetregister(list,r.index);
-      end;
-
-
     procedure Tcgx86.allocexplicitregisters(list:Taasmoutput;rt:Tregistertype;r:Tcpuregisterset);
       begin
         if rt<>R_FPUREGISTER then
@@ -243,6 +234,13 @@ unit cgx86;
       end;
 
 
+    procedure tcgx86.add_reg_instruction(instr:Tai;r:tregister);
+      begin
+        if getregtype(r)<>R_FPUREGISTER then
+          inherited add_reg_instruction(instr,r);
+      end;
+
+
     procedure tcgx86.dec_fpu_stack;
       begin
         dec(rgfpu.fpuvaroffset);
@@ -1426,18 +1424,18 @@ unit cgx86;
            system_i386_win32,
         {$endif}
            system_i386_freebsd,
-	   system_i386_netbsd,
-//	   system_i386_openbsd,
+           system_i386_netbsd,
+//         system_i386_openbsd,
            system_i386_wdosx,
            system_i386_linux:
              begin
-		Case target_info.system Of
-		 system_i386_freebsd : mcountprefix:='.';
-		 system_i386_netbsd : mcountprefix:='__';
-//		 system_i386_openbsd : mcountprefix:='.';
-		else
-  		 mcountPrefix:='';
-		end;
+                Case target_info.system Of
+                 system_i386_freebsd : mcountprefix:='.';
+                 system_i386_netbsd : mcountprefix:='__';
+//               system_i386_openbsd : mcountprefix:='.';
+                else
+                 mcountPrefix:='';
+                end;
                 objectlibrary.getaddrlabel(pl);
                 list.concat(Tai_section.Create(sec_data));
                 list.concat(Tai_align.Create(4));
@@ -1684,7 +1682,13 @@ unit cgx86;
 end.
 {
   $Log$
-  Revision 1.90  2003-12-12 17:16:18  peter
+  Revision 1.91  2003-12-15 21:25:49  peter
+    * reg allocations for imaginary register are now inserted just
+      before reg allocation
+    * tregister changed to enum to allow compile time check
+    * fixed several tregister-tsuperregister errors
+
+  Revision 1.90  2003/12/12 17:16:18  peter
     * rg[tregistertype] added in tcg
 
   Revision 1.89  2003/12/06 01:15:23  florian

+ 8 - 2
compiler/x86/cpubase.pas

@@ -176,7 +176,7 @@ uses
 {$endif x86_64}
       );
 
-      regstabs_table : array[tregisterindex] of tregister = (
+      regstabs_table : array[tregisterindex] of shortint = (
 {$ifdef x86_64}
         {$i r8664stab.inc}
 {$else x86_64}
@@ -526,7 +526,13 @@ implementation
 end.
 {
   $Log$
-  Revision 1.30  2003-10-31 09:22:55  mazen
+  Revision 1.31  2003-12-15 21:25:49  peter
+    * reg allocations for imaginary register are now inserted just
+      before reg allocation
+    * tregister changed to enum to allow compile time check
+    * fixed several tregister-tsuperregister errors
+
+  Revision 1.30  2003/10/31 09:22:55  mazen
   * using findreg_by_<name|number>_table directly to decrease heap overheading
 
   Revision 1.29  2003/10/30 17:13:18  peter