Jelajahi Sumber

* Code generator converted to new register notation
- Horribily outdated todo.txt removed

daniel 22 tahun lalu
induk
melakukan
86bcea6ef5
68 mengubah file dengan 2933 tambahan dan 1694 penghapusan
  1. 10 2
      compiler/aasmtai.pas
  2. 20 16
      compiler/cg64f32.pas
  3. 58 57
      compiler/cgobj.pas
  4. 106 50
      compiler/i386/aasmcpu.pas
  5. 82 1
      compiler/i386/ag386att.pas
  6. 81 2
      compiler/i386/ag386int.pas
  7. 7 2
      compiler/i386/cga.pas
  8. 120 49
      compiler/i386/cpubase.pas
  9. 21 7
      compiler/i386/csopt386.pas
  10. 15 5
      compiler/i386/daopt386.pas
  11. 40 39
      compiler/i386/n386add.pas
  12. 87 51
      compiler/i386/n386cal.pas
  13. 16 11
      compiler/i386/n386cnv.pas
  14. 9 3
      compiler/i386/n386inl.pas
  15. 74 64
      compiler/i386/n386mat.pas
  16. 11 3
      compiler/i386/n386mem.pas
  17. 22 16
      compiler/i386/n386opt.pas
  18. 28 20
      compiler/i386/n386set.pas
  19. 10 2
      compiler/i386/popt386.pas
  20. 16 16
      compiler/i386/ra386.pas
  21. 32 19
      compiler/i386/ra386att.pas
  22. 51 31
      compiler/i386/ra386int.pas
  23. 266 184
      compiler/i386/rgcpu.pas
  24. 9 3
      compiler/i386/rropt386.pas
  25. 15 11
      compiler/m68k/aasmcpu.pas
  26. 9 5
      compiler/m68k/agcpugas.pas
  27. 98 87
      compiler/m68k/cgcpu.pas
  28. 99 12
      compiler/m68k/cpubase.pas
  29. 9 5
      compiler/m68k/n68kcnv.pas
  30. 11 7
      compiler/m68k/n68kmat.pas
  31. 7 3
      compiler/m68k/ncpuadd.pas
  32. 114 49
      compiler/m68k/rasm.pas
  33. 95 76
      compiler/m68k/rgcpu.pas
  34. 9 3
      compiler/ncal.pas
  35. 22 15
      compiler/ncgadd.pas
  36. 63 24
      compiler/ncgcal.pas
  37. 6 2
      compiler/ncgcnv.pas
  38. 35 18
      compiler/ncgflw.pas
  39. 10 5
      compiler/ncginl.pas
  40. 33 17
      compiler/ncgld.pas
  41. 10 6
      compiler/ncgmat.pas
  42. 32 28
      compiler/ncgmem.pas
  43. 20 17
      compiler/ncgset.pas
  44. 77 56
      compiler/ncgutil.pas
  45. 7 2
      compiler/pmodules.pas
  46. 21 17
      compiler/powerpc/cgcpu.pas
  47. 57 7
      compiler/powerpc/cpubase.pas
  48. 26 22
      compiler/powerpc/nppcadd.pas
  49. 11 7
      compiler/powerpc/nppccnv.pas
  50. 19 13
      compiler/powerpc/nppcmat.pas
  51. 6 2
      compiler/powerpc/nppcset.pas
  52. 10 5
      compiler/powerpc/rgcpu.pas
  53. 9 3
      compiler/pstatmnt.pas
  54. 9 3
      compiler/psub.pas
  55. 13 3
      compiler/rautils.pas
  56. 17 3
      compiler/regvars.pas
  57. 337 161
      compiler/rgobj.pas
  58. 12 8
      compiler/sparc/cgcpu.pas
  59. 110 41
      compiler/sparc/cpubase.pas
  60. 20 16
      compiler/sparc/ncpuadd.pas
  61. 11 7
      compiler/sparc/ncpucnv.pas
  62. 16 12
      compiler/sparc/ncpumat.pas
  63. 19 8
      compiler/sparc/rgcpu.pas
  64. 15 6
      compiler/symdef.pas
  65. 15 11
      compiler/tgobj.pas
  66. 0 106
      compiler/todo.txt
  67. 56 4
      compiler/vis/cpubase.pas
  68. 152 128
      compiler/x86/cgx86.pas

+ 10 - 2
compiler/aasmtai.pas

@@ -1744,7 +1744,11 @@ uses
               begin
                 for i:=0 to Taicpu_abstract(p).ops-1 do
                   if Taicpu_abstract(p).oper[i].typ=Top_reg then
-                    convert_register_to_enum(Taicpu_abstract(p).oper[i].reg)
+                    begin
+                      if Taicpu_abstract(p).oper[i].reg.enum=R_NO then
+                        internalerror(200302052);
+                      convert_register_to_enum(Taicpu_abstract(p).oper[i].reg)
+                    end
                   else if Taicpu_abstract(p).oper[i].typ=Top_ref then
                     begin
                       r:=Taicpu_abstract(p).oper[i].ref;
@@ -1766,7 +1770,11 @@ uses
 end.
 {
   $Log$
-  Revision 1.20  2003-01-30 21:46:20  peter
+  Revision 1.21  2003-02-19 22:00:14  daniel
+    * Code generator converted to new register notation
+    - Horribily outdated todo.txt removed
+
+  Revision 1.20  2003/01/30 21:46:20  peter
     * tai_const_symbol.createdataname added
 
   Revision 1.19  2003/01/21 08:48:08  daniel

+ 20 - 16
compiler/cg64f32.pas

@@ -164,13 +164,13 @@ unit cg64f32;
           end;
         got_scratch:=false;
         tmpref := ref;
-        if tmpref.base.enum>lastreg then
-          internalerror(200301081);
-        if reg.reglo.enum>lastreg then
-          internalerror(200301081);
-        if (tmpref.base.enum=reg.reglo.enum) then
+        if tmpref.base.enum<>R_INTREGISTER then
+          internalerror(200302035);
+        if reg.reglo.enum<>R_INTREGISTER then
+          internalerror(200302035);
+        if (tmpref.base.number=reg.reglo.number) then
          begin
-           tmpreg := cg.get_scratch_reg_int(list);
+           tmpreg := cg.get_scratch_reg_address(list);
            got_scratch:=true;
            cg.a_load_reg_reg(list,OS_ADDR,OS_ADDR,tmpref.base,tmpreg);
            tmpref.base:=tmpreg;
@@ -179,9 +179,9 @@ unit cg64f32;
          { this works only for the i386, thus the i386 needs to override  }
          { this method and this method must be replaced by a more generic }
          { implementation FK                                              }
-         if (tmpref.index.enum=reg.reglo.enum) then
+         if (tmpref.index.number=reg.reglo.number) then
           begin
-            tmpreg:=cg.get_scratch_reg_int(list);
+            tmpreg:=cg.get_scratch_reg_address(list);
             got_scratch:=true;
             cg.a_load_reg_reg(list,OS_ADDR,OS_ADDR,tmpref.index,tmpreg);
             tmpref.index:=tmpreg;
@@ -399,8 +399,8 @@ unit cg64f32;
       var
         tempreg: tregister64;
       begin
-        tempreg.reghi := cg.get_scratch_reg_int(list);
-        tempreg.reglo := cg.get_scratch_reg_int(list);
+        tempreg.reghi := cg.get_scratch_reg_int(list,OS_INT);
+        tempreg.reglo := cg.get_scratch_reg_int(list,OS_INT);
         a_load64_ref_reg(list,ref,tempreg);
         a_op64_reg_reg(list,op,tempreg,reg);
         cg.free_scratch_reg(list,tempreg.reglo);
@@ -412,8 +412,8 @@ unit cg64f32;
       var
         tempreg: tregister64;
       begin
-        tempreg.reghi := cg.get_scratch_reg_int(list);
-        tempreg.reglo := cg.get_scratch_reg_int(list);
+        tempreg.reghi := cg.get_scratch_reg_int(list,OS_INT);
+        tempreg.reglo := cg.get_scratch_reg_int(list,OS_INT);
         a_load64_ref_reg(list,ref,tempreg);
         a_op64_const_reg(list,op,value,tempreg);
         a_load64_reg_ref(list,tempreg,ref);
@@ -525,7 +525,7 @@ unit cg64f32;
                end
              else
                begin
-                 hreg := cg.get_scratch_reg_int(list);
+                 hreg := cg.get_scratch_reg_int(list,OS_INT);
                  got_scratch := true;
                  a_load64high_ref_reg(list,p.location.reference,hreg);
                end;
@@ -573,7 +573,7 @@ unit cg64f32;
                    end
                  else
                    begin
-                     hreg := cg.get_scratch_reg_int(list);
+                     hreg := cg.get_scratch_reg_int(list,OS_INT);
                      got_scratch := true;
                      a_load64low_ref_reg(list,p.location.reference,hreg);
                    end;
@@ -627,7 +627,7 @@ unit cg64f32;
                  end
                else
                  begin
-                   hreg := cg.get_scratch_reg_int(list);
+                   hreg := cg.get_scratch_reg_int(list,OS_INT);
                    got_scratch := true;
 
                    opsize := def_cgsize(p.resulttype.def);
@@ -752,7 +752,11 @@ begin
 end.
 {
   $Log$
-  Revision 1.34  2003-01-08 18:43:56  daniel
+  Revision 1.35  2003-02-19 22:00:14  daniel
+    * Code generator converted to new register notation
+    - Horribily outdated todo.txt removed
+
+  Revision 1.34  2003/01/08 18:43:56  daniel
    * Tregister changed into a record
 
   Revision 1.33  2003/01/05 13:36:53  florian

+ 58 - 57
compiler/cgobj.pas

@@ -61,7 +61,7 @@ unit cgobj;
        tcg = class
           scratch_register_array_pointer : aword;
           {# List of currently unused scratch registers }
-          unusedscratchregisters : tregisterset;
+          unusedscratchregisters:Tsupregset;
 
           alignment : talignment;
           {************************************************}
@@ -86,7 +86,7 @@ unit cgobj;
              should be freed by calling @link(free_scratch_reg) as
              soon as it is no longer required.
           }
-          function get_scratch_reg_int(list : taasmoutput) : tregister;virtual;
+          function get_scratch_reg_int(list : taasmoutput;size:Tcgsize) : tregister;virtual;
           {# @abstract(Returns an address register for use as scratch register)
              This routine returns a register which can be used by
              the code generator as a pointer scratch register.
@@ -160,7 +160,7 @@ unit cgobj;
 
           { Copies a whole memory block to the stack, the locpara must be a memory location }
           procedure a_param_copy_ref(list : taasmoutput;size : qword;const r : treference;const locpara : tparalocation);
-          (* Remarks:
+          { Remarks:
             * If a method specifies a size you have only to take care
               of that number of bits, i.e. load_const_reg with OP_8 must
               only load the lower 8 bit of the specified register
@@ -175,7 +175,7 @@ unit cgobj;
             * the procedures without fpu/mm are only for integer usage
             * normally the first location is the source and the
               second the destination
-          *)
+          }
 
           {# Emits instruction to call the method specified by symbol name.
              This routine must be overriden for each new target cpu.
@@ -416,14 +416,14 @@ unit cgobj;
 
              @param(usedinproc Registers which are used in the code of this routine)
           }
-          procedure g_save_standard_registers(list : taasmoutput; usedinproc : tregisterset);virtual;abstract;
+          procedure g_save_standard_registers(list:Taasmoutput;usedinproc:Tsupregset);virtual;abstract;
           {# This routine is called when generating the code for the exit point
              of a routine. It should restore all registers which were previously
              saved in @var(g_save_standard_registers).
 
              @param(usedinproc Registers which are used in the code of this routine)
           }
-          procedure g_restore_standard_registers(list : taasmoutput; usedinproc : tregisterset);virtual;abstract;
+          procedure g_restore_standard_registers(list:Taasmoutput;usedinproc:Tsupregset);virtual;abstract;
           procedure g_save_all_registers(list : taasmoutput);virtual;abstract;
           procedure g_restore_all_registers(list : taasmoutput;selfused,accused,acchiused:boolean);virtual;abstract;
        end;
@@ -539,7 +539,7 @@ unit cgobj;
          list.concat(tai_label.create(l));
       end;
 
-    function tcg.get_scratch_reg_int(list : taasmoutput) : tregister;
+    function tcg.get_scratch_reg_int(list:taasmoutput;size:Tcgsize):tregister;
 
       var
          r : tregister;
@@ -553,10 +553,11 @@ unit cgobj;
                 (scratch_register_array_pointer+max_scratch_regs-1) do
            if scratch_regs[(i mod max_scratch_regs)+1] in unusedscratchregisters then
              begin
-                r.enum:=scratch_regs[(i mod max_scratch_regs)+1];
+                r.enum:=R_INTREGISTER;
+                r.number:=scratch_regs[(i mod max_scratch_regs)+1] shl 8 or cgsize2subreg(size);
                 break;
              end;
-         exclude(unusedscratchregisters,r.enum);
+         exclude(unusedscratchregisters,r.number shr 8);
          inc(scratch_register_array_pointer);
          if scratch_register_array_pointer>max_scratch_regs then
            scratch_register_array_pointer:=1;
@@ -567,14 +568,16 @@ unit cgobj;
     { the default behavior simply returns a general purpose register }
     function tcg.get_scratch_reg_address(list : taasmoutput) : tregister;
      begin
-       get_scratch_reg_address := get_scratch_reg_int(list);
+       get_scratch_reg_address := get_scratch_reg_int(list,OS_ADDR);
      end;
 
 
     procedure tcg.free_scratch_reg(list : taasmoutput;r : tregister);
 
       begin
-         include(unusedscratchregisters,rg.makeregsize(r,OS_INT).enum);
+         if r.enum<>R_INTREGISTER then 
+           internalerror(200302058);
+         include(unusedscratchregisters,r.number shr 8);
          a_reg_dealloc(list,r);
       end;
 
@@ -615,7 +618,7 @@ unit cgobj;
          hr : tregister;
 
       begin
-         hr:=get_scratch_reg_int(list);
+         hr:=get_scratch_reg_int(list,size);
          a_load_const_reg(list,size,a,hr);
          a_param_reg(list,size,hr,locpara);
          free_scratch_reg(list,hr);
@@ -625,7 +628,7 @@ unit cgobj;
       var
          hr : tregister;
       begin
-         hr:=get_scratch_reg_int(list);
+         hr:=get_scratch_reg_int(list,size);
          a_load_ref_reg(list,size,r,hr);
          a_param_reg(list,size,hr,locpara);
          free_scratch_reg(list,hr);
@@ -696,39 +699,42 @@ unit cgobj;
         { the following is done with defines to avoid a speed penalty,  }
         { since all this is only necessary for the 80x86 (because EDI   }
         { doesn't have an 8bit component which is directly addressable) }
-        pushed_reg.enum := R_NO;
+        pushed_reg.enum:=R_INTREGISTER;
+        pushed_reg.number:=NR_NO;
         if size in [OS_8,OS_S8] then
           if (rg.countunusedregsint = 0) then
             begin
-              if dref.base.enum>lastreg then
-                internalerror(200301081);
-              if dref.index.enum>lastreg then
-                internalerror(200301081);
-              if (dref.base.enum <> R_EBX) and
-                 (dref.index.enum <> R_EBX) then
-                pushed_reg.enum := R_EBX
-              else if (dref.base.enum <> R_EAX) and
-                      (dref.index.enum <> R_EAX) then
-                pushed_reg.enum := R_EAX
-              else pushed_reg.enum := R_ECX;
-              tmpreg := rg.makeregsize(pushed_reg,OS_8);
+              if dref.base.enum<>R_INTREGISTER then
+                internalerror(200302037);
+              if dref.index.enum<>R_INTREGISTER then
+                internalerror(200302037);
+                
+              if (dref.base.number shr 8<>RS_EBX) and
+                 (dref.index.number shr 8<>RS_EBX) then
+                pushed_reg.number:=NR_EBX
+              else if (dref.base.number<>RS_EAX) and
+                      (dref.index.number<>RS_EAX) then
+                pushed_reg.number:=NR_EAX
+              else
+                pushed_reg.number:=NR_ECX;
+              tmpreg.enum:=R_INTREGISTER;
+              tmpreg.number:=(pushed_reg.number and not $ff) or R_SUBL;
               list.concat(taicpu.op_reg(A_PUSH,S_L,pushed_reg));
             end
           else
-            tmpreg := rg.getregisterint(list)
+            tmpreg := rg.getregisterint(list,size)
         else
 {$endif i386}
-        tmpreg := get_scratch_reg_int(list);
-        tmpreg:=rg.makeregsize(tmpreg,size);
+        tmpreg := get_scratch_reg_int(list,size);
         a_load_ref_reg(list,size,sref,tmpreg);
         a_load_reg_ref(list,size,tmpreg,dref);
 {$ifdef i386}
         if size in [OS_8,OS_S8] then
           begin
-            if (pushed_reg.enum <> R_NO) then
+            if (pushed_reg.number<>NR_NO) then
               list.concat(taicpu.op_reg(A_POP,S_L,pushed_reg))
             else
-              rg.ungetregister(list,tmpreg)
+              rg.ungetregisterint(list,tmpreg)
           end
         else
 {$endif i386}
@@ -742,7 +748,7 @@ unit cgobj;
         tmpreg: tregister;
 
       begin
-        tmpreg := get_scratch_reg_int(list);
+        tmpreg := get_scratch_reg_int(list,size);
         a_load_const_reg(list,size,a,tmpreg);
         a_load_reg_ref(list,size,tmpreg,ref);
         free_scratch_reg(list,tmpreg);
@@ -780,20 +786,11 @@ unit cgobj;
     var r:Tregister;
 
       begin
-      {$ifdef i386}
-        {For safety convert location register to enum for now...}
-        convert_register_to_enum(reg);
-      {$endif}
         case loc.loc of
           LOC_REFERENCE,LOC_CREFERENCE:
             a_load_ref_reg(list,loc.size,loc.reference,reg);
           LOC_REGISTER,LOC_CREGISTER:
-            begin
-              {For safety convert location register to enum for now...}
-              r:=loc.register;
-              convert_register_to_enum(r);
-              a_load_reg_reg(list,loc.size,loc.size,r,reg);
-            end;
+            a_load_reg_reg(list,loc.size,loc.size,loc.register,reg);
           LOC_CONSTANT:
             a_load_const_reg(list,loc.size,loc.value,reg);
           else
@@ -946,7 +943,7 @@ unit cgobj;
         tmpreg: tregister;
 
       begin
-        tmpreg := get_scratch_reg_int(list);
+        tmpreg := get_scratch_reg_int(list,size);
         a_load_ref_reg(list,size,ref,tmpreg);
         a_op_const_reg(list,op,a,tmpreg);
         a_load_reg_ref(list,size,tmpreg,ref);
@@ -974,7 +971,7 @@ unit cgobj;
         tmpreg: tregister;
 
       begin
-        tmpreg := get_scratch_reg_int(list);
+        tmpreg := get_scratch_reg_int(list,size);
         a_load_ref_reg(list,size,ref,tmpreg);
         a_op_reg_reg(list,op,size,reg,tmpreg);
         a_load_reg_ref(list,size,tmpreg,ref);
@@ -997,7 +994,7 @@ unit cgobj;
             end;
           else
             begin
-              tmpreg := get_scratch_reg_int(list);
+              tmpreg := get_scratch_reg_int(list,size);
               a_load_ref_reg(list,size,ref,tmpreg);
               a_op_reg_reg(list,op,size,tmpreg,reg);
               free_scratch_reg(list,tmpreg);
@@ -1031,8 +1028,7 @@ unit cgobj;
             a_op_ref_reg(list,op,loc.size,ref,loc.register);
           LOC_REFERENCE,LOC_CREFERENCE:
             begin
-              tmpreg := get_scratch_reg_int(list);
-              tmpreg:=rg.makeregsize(tmpreg,loc.size);
+              tmpreg := get_scratch_reg_int(list,loc.size);
               a_load_ref_reg(list,loc.size,ref,tmpreg);
               a_op_reg_ref(list,op,loc.size,tmpreg,loc.reference);
               free_scratch_reg(list,tmpreg);
@@ -1065,7 +1061,7 @@ unit cgobj;
         tmpreg: tregister;
 
       begin
-        tmpreg := get_scratch_reg_int(list);
+        tmpreg := get_scratch_reg_int(list,size);
         a_load_ref_reg(list,size,ref,tmpreg);
         a_cmp_const_reg_label(list,size,cmp_op,a,tmpreg,l);
         free_scratch_reg(list,tmpreg);
@@ -1091,7 +1087,7 @@ unit cgobj;
         tmpreg: tregister;
 
       begin
-        tmpreg := get_scratch_reg_int(list);
+        tmpreg := get_scratch_reg_int(list,size);
         a_load_ref_reg(list,size,ref,tmpreg);
         a_cmp_reg_reg_label(list,size,cmp_op,tmpreg,reg,l);
         free_scratch_reg(list,tmpreg);
@@ -1131,16 +1127,16 @@ unit cgobj;
               { since all this is only necessary for the 80x86 (because EDI   }
               { doesn't have an 8bit component which is directly addressable) }
               if size in [OS_8,OS_S8] then
-                tmpreg := rg.getregisterint(list)
+                tmpreg := rg.getregisterint(list,size)
               else
 {$endif i386}
-              tmpreg := get_scratch_reg_int(list);
-              tmpreg := rg.makeregsize(tmpreg,size);
+                tmpreg := get_scratch_reg_int(list,size);
+              {tmpreg := rg.makeregsize(tmpreg,size);}
               a_load_ref_reg(list,size,loc.reference,tmpreg);
               a_cmp_ref_reg_label(list,size,cmp_op,ref,tmpreg,l);
 {$ifdef i386}
               if size in [OS_8,OS_S8] then
-                rg.ungetregister(list,tmpreg)
+                rg.ungetregisterint(list,tmpreg)
               else
 {$endif i386}
               free_scratch_reg(list,tmpreg);
@@ -1392,7 +1388,7 @@ unit cgobj;
                 lto := 0;
             end;
 
-        hreg := get_scratch_reg_int(list);
+        hreg := get_scratch_reg_int(list,OS_INT);
         if (p.location.loc in [LOC_REGISTER,LOC_CREGISTER]) then
           a_op_const_reg_reg(list,OP_SUB,def_cgsize(p.resulttype.def),
            aword(lto),p.location.register,hreg)
@@ -1424,7 +1420,7 @@ unit cgobj;
       var
         tmpreg : tregister;
       begin
-        tmpreg := get_scratch_reg_int(list);
+        tmpreg := get_scratch_reg_int(list,size);
         g_flags2reg(list,size,f,tmpreg);
         a_load_reg_ref(list,size,tmpreg,ref);
         free_scratch_reg(list,tmpreg);
@@ -1438,7 +1434,8 @@ unit cgobj;
          i : longint;
          spr : Tregister;
       begin
-         spr.enum:=SELF_POINTER_REG;
+         spr.enum:=R_INTREGISTER;
+         spr.number:=NR_SELF_POINTER_REG;
          if assigned(procinfo._class) then
            begin
               list.concat(tai_regalloc.Alloc(spr));
@@ -1724,7 +1721,11 @@ finalization
 end.
 {
   $Log$
-  Revision 1.76  2003-01-31 22:47:48  peter
+  Revision 1.77  2003-02-19 22:00:14  daniel
+    * Code generator converted to new register notation
+    - Horribily outdated todo.txt removed
+
+  Revision 1.76  2003/01/31 22:47:48  peter
     * maybe_testself now really uses the passed register
 
   Revision 1.75  2003/01/30 21:46:35  peter

+ 106 - 50
compiler/i386/aasmcpu.pas

@@ -291,21 +291,25 @@ implementation
           OT_BITS32,OT_BITS64,OT_BITS80,OT_BITS64,OT_BITS64,OT_BITS64,OT_NONE,
           OT_NEAR,OT_FAR,OT_SHORT
          )
-       );
-
-       { Convert reg to operand type }
-       reg2type : array[firstreg..lastreg] of longint = (OT_NONE,
-         OT_REG_EAX,OT_REG_ECX,OT_REG32,OT_REG32,OT_REG32,OT_REG32,OT_REG32,OT_REG32,
-         OT_REG_AX,OT_REG_CX,OT_REG_DX,OT_REG16,OT_REG16,OT_REG16,OT_REG16,OT_REG16,
-         OT_REG_AL,OT_REG_CL,OT_REG8,OT_REG8,OT_REG8,OT_REG8,OT_REG8,OT_REG8,
-         OT_REG_CS,OT_REG_DESS,OT_REG_DESS,OT_REG_DESS,OT_REG_FSGS,OT_REG_FSGS,
-         OT_FPU0,OT_FPU0,OT_FPUREG,OT_FPUREG,OT_FPUREG,OT_FPUREG,OT_FPUREG,OT_FPUREG,OT_FPUREG,
-         OT_REG_DREG,OT_REG_DREG,OT_REG_DREG,OT_REG_DREG,OT_REG_DREG,OT_REG_DREG,
-         OT_REG_CREG,OT_REG_CREG,OT_REG_CREG,OT_REG_CR4,
-         OT_REG_TREG,OT_REG_TREG,OT_REG_TREG,OT_REG_TREG,OT_REG_TREG,
-         OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,
-         OT_XMMREG,OT_XMMREG,OT_XMMREG,OT_XMMREG,OT_XMMREG,OT_XMMREG,OT_XMMREG,OT_XMMREG
-       );
+      );
+
+      subreg2type:array[R_SUBL..R_SUBD] of longint = (
+        OT_REG8,OT_REG8,OT_REG16,OT_REG32
+      );
+
+      { Convert reg to operand type }
+      reg2type : array[firstreg..lastreg] of longint = (OT_NONE,
+        OT_REG_EAX,OT_REG_ECX,OT_REG32,OT_REG32,OT_REG32,OT_REG32,OT_REG32,OT_REG32,
+        OT_REG_AX,OT_REG_CX,OT_REG_DX,OT_REG16,OT_REG16,OT_REG16,OT_REG16,OT_REG16,
+        OT_REG_AL,OT_REG_CL,OT_REG8,OT_REG8,OT_REG8,OT_REG8,OT_REG8,OT_REG8,
+        OT_REG_CS,OT_REG_DESS,OT_REG_DESS,OT_REG_DESS,OT_REG_FSGS,OT_REG_FSGS,
+        OT_FPU0,OT_FPU0,OT_FPUREG,OT_FPUREG,OT_FPUREG,OT_FPUREG,OT_FPUREG,OT_FPUREG,OT_FPUREG,
+        OT_REG_DREG,OT_REG_DREG,OT_REG_DREG,OT_REG_DREG,OT_REG_DREG,OT_REG_DREG,
+        OT_REG_CREG,OT_REG_CREG,OT_REG_CREG,OT_REG_CR4,
+        OT_REG_TREG,OT_REG_TREG,OT_REG_TREG,OT_REG_TREG,OT_REG_TREG,
+        OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,
+        OT_XMMREG,OT_XMMREG,OT_XMMREG,OT_XMMREG,OT_XMMREG,OT_XMMREG,OT_XMMREG,OT_XMMREG
+      );
 
 
 {****************************************************************************
@@ -393,7 +397,6 @@ implementation
     constructor taicpu.op_reg(op : tasmop;_size : topsize;_op1 : tregister);
       begin
          inherited create(op);
-         init(_size);
          ops:=1;
          loadreg(0,_op1);
       end;
@@ -831,6 +834,7 @@ implementation
       }
       var
         i,l,relsize : longint;
+        nb,ni:boolean;
       begin
         if ops=0 then
          exit;
@@ -841,25 +845,57 @@ implementation
             case typ of
               top_reg :
                 begin
-                  if reg.enum>lastreg then
-                    internalerror(200301081);
-                  ot:=reg2type[reg.enum];
+                  if reg.enum=R_INTREGISTER then
+                    case reg.number of
+                      NR_AL:
+                        ot:=OT_REG_AL;
+                      NR_AX:
+                        ot:=OT_REG_AX;
+                      NR_EAX:
+                        ot:=OT_REG_EAX;
+                      NR_CL:
+                        ot:=OT_REG_CL;
+                      NR_CX:
+                        ot:=OT_REG_CX;
+                      NR_ECX:
+                        ot:=OT_REG_ECX;
+                      NR_DX:
+                        ot:=OT_REG_DX;
+                      NR_CS:
+                        ot:=OT_REG_CS;
+                      NR_DS,NR_ES,NR_SS:
+                        ot:=OT_REG_DESS;
+                      NR_FS,NR_GS:
+                        ot:=OT_REG_FSGS;
+                      NR_DR0..NR_DR7:
+                        ot:=OT_REG_DREG;
+                      NR_CR0..NR_CR3:
+                        ot:=OT_REG_CREG;
+                      NR_CR4:
+                        ot:=OT_REG_CR4;
+                      NR_TR3..NR_TR7:
+                        ot:=OT_REG_TREG;
+                      else
+                        ot:=subreg2type[reg.number and $ff];
+                    end
+                  else
+                    ot:=reg2type[reg.enum];
                 end;
               top_ref :
                 begin
-                  if ref^.base.enum>lastreg then
-                    internalerror(200301081);
-                  if ref^.index.enum>lastreg then
-                    internalerror(200301081);
+                  nb:=(ref^.base.enum=R_NO) or
+                     ((ref^.base.enum=R_INTREGISTER) and (ref^.base.number=NR_NO));
+                  ni:=(ref^.index.enum=R_NO) or
+                     ((ref^.index.enum=R_INTREGISTER) and (ref^.index.number=NR_NO));
                 { create ot field }
                   if (ot and OT_SIZE_MASK)=0 then
                     ot:=OT_MEMORY or opsize_2_type[i,opsize]
                   else
                     ot:=OT_MEMORY or (ot and OT_SIZE_MASK);
-                  if (ref^.base.enum=R_NO) and (ref^.index.enum=R_NO) then
+                  if nb and ni then
                     ot:=ot or OT_MEM_OFFS;
                 { fix scalefactor }
-                  if (ref^.index.enum=R_NO) then
+                  if ni then
                    ref^.scalefactor:=0
                   else
                    if (ref^.scalefactor=0) then
@@ -1087,9 +1123,7 @@ implementation
            if m=100 then
             begin
               InsSize:=calcsize(insentry);
-              if segprefix.enum>lastreg then
-                internalerror(200301081);
-              if (segprefix.enum<>R_NO) then
+              if not((segprefix.enum=R_NO) or ((segprefix.enum=R_INTREGISTER) and (segprefix.number=NR_NO))) then
                inc(InsSize);
               { For opsize if size if forced }
               if (insentry^.flags and (IF_SB or IF_SW or IF_SD))<>0 then
@@ -1197,25 +1231,35 @@ implementation
       end;
 
 
-    function taicpu.NeedAddrPrefix(opidx:byte):boolean;
-      var
-        i,b : Toldregister;
-      begin
-        if (OT_MEMORY and (not oper[opidx].ot))=0 then
-         begin
-           i:=oper[opidx].ref^.index.enum;
-           b:=oper[opidx].ref^.base.enum;
-           if (i>lastreg) or (b>lastreg) then
-              internalerror(200201081);
-           if not(i in [R_NO,R_EAX,R_EBX,R_ECX,R_EDX,R_EBP,R_ESP,R_ESI,R_EDI]) or
-              not(b in [R_NO,R_EAX,R_EBX,R_ECX,R_EDX,R_EBP,R_ESP,R_ESI,R_EDI]) then
+    function taicpu.needaddrprefix(opidx:byte):boolean;
+
+    var i,b:Tnewregister;
+        ia,ba:boolean;
+
+    begin
+      needaddrprefix:=false;
+      if (OT_MEMORY and (not oper[opidx].ot))=0 then
+        begin
+          if oper[opidx].ref^.index.enum=R_INTREGISTER then
             begin
-              NeedAddrPrefix:=true;
-              exit;
-            end;
-         end;
-        NeedAddrPrefix:=false;
-      end;
+              i:=oper[opidx].ref^.index.number;
+              ia:=(i<>NR_NO) and (i and $ff<>R_SUBD);
+            end
+          else
+            ia:=not(oper[opidx].ref^.index.enum in [R_NO,R_EAX,R_EBX,R_ECX,R_EDX,R_EBP,R_ESP,R_ESI,R_EDI]);
+          if oper[opidx].ref^.base.enum=R_INTREGISTER then
+            begin
+              b:=oper[opidx].ref^.base.number;
+              ba:=(b<>NR_NO) and (b and $ff<>R_SUBD);
+            end
+          else
+            ba:=not(oper[opidx].ref^.base.enum in [R_NO,R_EAX,R_EBX,R_ECX,R_EDX,R_EBP,R_ESP,R_ESI,R_EDI]);
+          b:=oper[opidx].ref^.base.number;
+          i:=oper[opidx].ref^.index.number;
+          if ia or ba then
+            needaddrprefix:=true;
+        end;
+    end;
 
 
     function regval(r:tregister):byte;
@@ -1265,15 +1309,19 @@ implementation
         md,s  : byte;
         base,index,scalefactor,
         o     : longint;
+        ireg  : Tregister;
+        ir,br : Tregister;
       begin
         process_ea:=false;
       { register ? }
         if (input.typ=top_reg) then
          begin
+           ireg:=input.reg;
+           convert_register_to_enum(ireg);
            j:=0;
            while (j<=high(regs)) do
             begin
-              if input.reg.enum=regs[j] then
+              if ireg.enum=regs[j] then
                break;
               inc(j);
             end;
@@ -1288,8 +1336,12 @@ implementation
            exit;
          end;
       { memory reference }
-        i:=input.ref^.index.enum;
-        b:=input.ref^.base.enum;
+        ir:=input.ref^.index;
+        br:=input.ref^.base;
+        convert_register_to_enum(ir);
+        convert_register_to_enum(br);
+        i:=ir.enum;
+        b:=br.enum;
         if (i>lastreg) or (b>lastreg) then
           internalerror(200301081);
         s:=input.ref^.scalefactor;
@@ -1896,7 +1948,11 @@ implementation
 end.
 {
   $Log$
-  Revision 1.11  2003-01-09 20:40:59  daniel
+  Revision 1.12  2003-02-19 22:00:15  daniel
+    * Code generator converted to new register notation
+    - Horribily outdated todo.txt removed
+
+  Revision 1.11  2003/01/09 20:40:59  daniel
     * Converted some code in cgx86.pas to new register numbering
 
   Revision 1.10  2003/01/08 18:43:57  daniel

+ 82 - 1
compiler/i386/ag386att.pas

@@ -61,6 +61,57 @@ interface
         '%mm0','%mm1','%mm2','%mm3','%mm4','%mm5','%mm6','%mm7',
         '%xmm0','%xmm1','%xmm2','%xmm3','%xmm4','%xmm5','%xmm6','%xmm7'
        );
+       
+     regname_count=45;
+     regname_count_bsstart=32;
+     
+     gas_regname2regnum:array[0..regname_count-1] of regname2regnumrec=(
+        (name:'%ah';     number:NR_AH),
+        (name:'%al';     number:NR_AL),
+        (name:'%ax';     number:NR_AX),
+        (name:'%bh';     number:NR_BH),
+        (name:'%bl';     number:NR_BL),
+        (name:'%bp';     number:NR_BP),
+        (name:'%bx';     number:NR_BX),
+        (name:'%ch';     number:NR_CH),
+        (name:'%cl';     number:NR_CL),
+        (name:'%cs';     number:NR_CS),
+        (name:'%cr0';    number:NR_CR0),
+        (name:'%cr2';    number:NR_CR2),
+        (name:'%cr3';    number:NR_CR3),
+        (name:'%cr4';    number:NR_CR4),
+        (name:'%cx';     number:NR_CX),
+        (name:'%dh';     number:NR_DH),
+        (name:'%dl';     number:NR_DL),
+        (name:'%di';     number:NR_DI),
+        (name:'%dr0';    number:NR_DR0),
+        (name:'%dr1';    number:NR_DR1),
+        (name:'%dr2';    number:NR_DR2),
+        (name:'%dr3';    number:NR_DR3),
+        (name:'%dr6';    number:NR_DR6),
+        (name:'%dr7';    number:NR_DR7),
+        (name:'%ds';     number:NR_DS),
+        (name:'%dx';     number:NR_DX),
+        (name:'%eax';    number:NR_EAX),
+        (name:'%ebp';    number:NR_EBP),
+        (name:'%ebx';    number:NR_EBX),
+        (name:'%ecx';    number:NR_ECX),
+        (name:'%edi';    number:NR_EDI),
+        (name:'%edx';    number:NR_EDX),
+        (name:'%es';     number:NR_ES),
+        (name:'%esi';    number:NR_ESI),
+        (name:'%esp';    number:NR_ESP),
+        (name:'%fs';     number:NR_FS),
+        (name:'%gs';     number:NR_GS),
+        (name:'%si';     number:NR_SI),
+        (name:'%sp';     number:NR_SP),
+        (name:'%ss';     number:NR_SS),
+        (name:'%tr3';    number:NR_DR0),
+        (name:'%tr4';    number:NR_DR1),
+        (name:'%tr5';    number:NR_DR2),
+        (name:'%tr6';    number:NR_DR6),
+        (name:'%tr7';    number:NR_DR7)
+     );
 
      gas_opsize2str : array[topsize] of string[2] = ('',
        'b','w','l','bw','bl','wl',
@@ -69,6 +120,9 @@ interface
        '','',''
      );
 
+     function gas_regnum_search(const s:string):Tnewregister;
+       
+
   implementation
 
     uses
@@ -251,6 +305,29 @@ interface
       end;
 
 
+     function gas_regnum_search(const s:string):Tnewregister;
+     
+     {Searches the register number that belongs to the register in s.
+      s must be in uppercase!.}
+     
+     var i,p:byte;
+     
+     begin
+        {Binary search.}
+        p:=0;
+        i:=regname_count_bsstart;
+        while i<>0 do
+          begin
+            if (p+i<regname_count) and (upper(gas_regname2regnum[p+i].name)<=s) then
+              p:=p+i;
+            i:=i shr 1;
+          end;
+        if upper(gas_regname2regnum[p].name)=s then
+          gas_regnum_search:=gas_regname2regnum[p].number
+        else
+          gas_regnum_search:=NR_NO;
+     end;
+
 {*****************************************************************************
                                   Initialize
 *****************************************************************************}
@@ -321,7 +398,11 @@ initialization
 end.
 {
   $Log$
-  Revision 1.29  2003-01-08 18:43:57  daniel
+  Revision 1.30  2003-02-19 22:00:15  daniel
+    * Code generator converted to new register notation
+    - Horribily outdated todo.txt removed
+
+  Revision 1.29  2003/01/08 18:43:57  daniel
    * Tregister changed into a record
 
   Revision 1.28  2003/01/05 13:36:53  florian

+ 81 - 2
compiler/i386/ag386int.pas

@@ -46,7 +46,59 @@ interface
         procedure WriteExternals;
       end;
 
-
+    const
+      regname_count=45;
+      regname_count_bsstart=32;
+     
+      intel_regname2regnum:array[0..regname_count-1] of regname2regnumrec=(
+        (name:'ah';     number:NR_AH),
+        (name:'al';     number:NR_AL),
+        (name:'ax';     number:NR_AX),
+        (name:'bh';     number:NR_BH),
+        (name:'bl';     number:NR_BL),
+        (name:'bp';     number:NR_BP),
+        (name:'bx';     number:NR_BX),
+        (name:'ch';     number:NR_CH),
+        (name:'cl';     number:NR_CL),
+        (name:'cs';     number:NR_CS),
+        (name:'cr0';    number:NR_CR0),
+        (name:'cr2';    number:NR_CR2),
+        (name:'cr3';    number:NR_CR3),
+        (name:'cr4';    number:NR_CR4),
+        (name:'cx';     number:NR_CX),
+        (name:'dh';     number:NR_DH),
+        (name:'dl';     number:NR_DL),
+        (name:'di';     number:NR_DI),
+        (name:'dr0';    number:NR_DR0),
+        (name:'dr1';    number:NR_DR1),
+        (name:'dr2';    number:NR_DR2),
+        (name:'dr3';    number:NR_DR3),
+        (name:'dr6';    number:NR_DR6),
+        (name:'dr7';    number:NR_DR7),
+        (name:'ds';     number:NR_DS),
+        (name:'dx';     number:NR_DX),
+        (name:'eax';    number:NR_EAX),
+        (name:'ebp';    number:NR_EBP),
+        (name:'ebx';    number:NR_EBX),
+        (name:'ecx';    number:NR_ECX),
+        (name:'edi';    number:NR_EDI),
+        (name:'edx';    number:NR_EDX),
+        (name:'es';     number:NR_ES),
+        (name:'esi';    number:NR_ESI),
+        (name:'esp';    number:NR_ESP),
+        (name:'fs';     number:NR_FS),
+        (name:'gs';     number:NR_GS),
+        (name:'si';     number:NR_SI),
+        (name:'sp';     number:NR_SP),
+        (name:'ss';     number:NR_SS),
+        (name:'tr3';    number:NR_DR0),
+        (name:'tr4';    number:NR_DR1),
+        (name:'tr5';    number:NR_DR2),
+        (name:'tr6';    number:NR_DR6),
+        (name:'tr7';    number:NR_DR7)
+      );
+
+     function intel_regnum_search(const s:string):Tnewregister;
 
 
   implementation
@@ -808,6 +860,29 @@ ait_stab_function_name : ;
 {$endif EXTDEBUG}
    end;
 
+     function intel_regnum_search(const s:string):Tnewregister;
+     
+     {Searches the register number that belongs to the register in s.
+      s must be in uppercase!.}
+     
+     var i,p:byte;
+     
+     begin
+        {Binary search.}
+        p:=0;
+        i:=regname_count_bsstart;
+        while i<>0 do
+          begin
+            if (p+i<regname_count) and (upper(intel_regname2regnum[p+i].name)<=s) then
+              p:=p+i;
+            i:=i shr 1;
+          end;
+        if upper(intel_regname2regnum[p].name)=s then
+          intel_regnum_search:=intel_regname2regnum[p].number
+        else
+          intel_regnum_search:=NR_NO;
+     end;
+
 {*****************************************************************************
                                   Initialize
 *****************************************************************************}
@@ -857,7 +932,11 @@ initialization
 end.
 {
   $Log$
-  Revision 1.32  2003-01-08 18:43:57  daniel
+  Revision 1.33  2003-02-19 22:00:15  daniel
+    * Code generator converted to new register notation
+    - Horribily outdated todo.txt removed
+
+  Revision 1.32  2003/01/08 18:43:57  daniel
    * Tregister changed into a record
 
   Revision 1.31  2002/12/24 18:10:34  peter

+ 7 - 2
compiler/i386/cga.pas

@@ -86,7 +86,8 @@ implementation
 
     function def_getreg(p1:tdef):tregister;
       begin
-        def_getreg:=rg.makeregsize(rg.getregisterint(exprasmlist),int_cgsize(p1.size));
+{        def_getreg:=rg.makeregsize(rg.getregisterint(exprasmlist),int_cgsize(p1.size));}
+        def_getreg:=rg.getregisterint(exprasmlist,int_cgsize(p1.size));
       end;
 
 
@@ -176,7 +177,11 @@ implementation
 end.
 {
   $Log$
-  Revision 1.35  2003-01-13 14:54:34  daniel
+  Revision 1.36  2003-02-19 22:00:15  daniel
+    * Code generator converted to new register notation
+    - Horribily outdated todo.txt removed
+
+  Revision 1.35  2003/01/13 14:54:34  daniel
     * Further work to convert codegenerator register convention;
       internalerror bug fixed.
 

+ 120 - 49
compiler/i386/cpubase.pas

@@ -95,27 +95,42 @@ uses
        $0103      EAX
        $0104      RAX
        $0201      BL
-       $0203      EBX
-
-       Register numbers:
-
-       $00        Special register
-       $01        EAX
-       $02        EBX
-       $03        ECX
-       $04        EDX
-       $05        ESI
-       $06        EDI
-       $07        EBP
-       $08        ESP
-       $09        R08
-       $0a        R09
-       $0b        R10
-       $0c        R11
-       $0d        R12
-       $0e        R13
-       $0f        R14
-       $10        R15}
+       $0203      EBX}
+
+      {Super register numbers:}
+      const       RS_SPECIAL    = $00;      {Special register}
+                  RS_EAX        = $01;      {EAX}
+                  RS_EBX        = $02;      {EBX}
+                  RS_ECX        = $03;      {ECX}
+                  RS_EDX        = $04;      {EDX}
+                  RS_ESI        = $05;      {ESI}
+                  RS_EDI        = $06;      {EDI}
+                  RS_EBP        = $07;      {EBP}
+                  RS_ESP        = $08;      {ESP}
+                  RS_R8         = $09;      {R8}
+                  RS_R9         = $0a;      {R9}
+                  RS_R10        = $0b;      {R10}
+                  RS_R11        = $0c;      {R11}
+                  RS_R12        = $0d;      {R12}
+                  RS_R13        = $0e;      {R13}
+                  RS_R14        = $0f;      {R14}
+                  RS_R15        = $10;      {R15}
+
+
+                  {Number of first and last superregister.}
+                  first_supreg    = $01;
+                  last_supreg     = $10;
+                  
+     {Sub register numbers:}
+                  R_SUBL        = $00;      {Like AL}
+                  R_SUBH        = $01;      {Like AH}
+                  R_SUBW        = $02;      {Like AX}
+                  R_SUBD        = $03;      {Like EAX}
+                  R_SUBQ        = $04;      {Like RAX}
+                  
+     {The subregister that specifies the entire register.}
+                  R_SUBWHOLE    = R_SUBD;  {i386}
+                  {R_SUBWHOLE    = R_SUBQ;} {Hammer}
 
      {Special registers:}
      const        NR_NO    = $0000;      {Invalid register}
@@ -133,14 +148,15 @@ uses
                   NR_DR6   = $0016;      {DR6}
                   NR_DR7   = $0017;      {DR7}
                   NR_CR0   = $0020;      {CR0}
-                  NR_CR1   = $0021;      {CR1}
-                  NR_CR2   = $0022;      {CR2}
-                  NR_CR3   = $0023;      {CR3}
+                  NR_CR2   = $0021;      {CR1}
+                  NR_CR3   = $0022;      {CR2}
+                  NR_CR4   = $0023;      {CR3}
                   NR_TR3   = $0030;      {R_TR3}
                   NR_TR4   = $0031;      {R_TR4}
                   NR_TR5   = $0032;      {R_TR5}
                   NR_TR6   = $0033;      {R_TR6}
                   NR_TR7   = $0034;      {R_TR7}
+
       {Normal registers.}
       const       NR_AL    = $0100;      {AL}
                   NR_AH    = $0101;      {AH}
@@ -226,14 +242,6 @@ uses
         R_INTREGISTER,R_FLOATREGISTER,R_MMXREGISTER,R_KNIREGISTER
       );
       
-
-      {Constants for subregisters.}
-      const   RS_L8   = 0;    {Like AL}
-              RS_H8   = 1;    {Like AH}
-              RS_16   = 2;    {Like AX}
-              RS_32   = 3;    {Like EAX}
-              RS_64   = 4;    {Like RAX}
-
       type  Tnewregister=word;
 
             Tregister = packed record
@@ -241,6 +249,9 @@ uses
               number:Tnewregister;  {This is a word for now, change to cardinal
                                      when the old register coding is away.}
             end;
+            
+            Tsuperregister=byte;
+            Tsubregister=byte;
       {$packenum normal}
 
       { A type to store register locations for 64 Bit values. }
@@ -253,7 +264,7 @@ uses
 
       {# Set type definition for registers }
       tregisterset = set of Toldregister;
-      Tsupregset = set of byte;
+      Tsupregset = set of Tsuperregister;
 
 
     const
@@ -265,6 +276,9 @@ uses
       firstsreg = R_CS;
       lastsreg  = R_GS;
 
+      nfirstsreg = NR_CS;
+      nlastsreg  = NR_GS;
+
       regset8bit  : tregisterset = [R_AL..R_DH];
       regset16bit : tregisterset = [R_AX..R_DI,R_CS..R_SS];
       regset32bit : tregisterset = [R_EAX..R_EDI];
@@ -285,6 +299,8 @@ uses
       
       {Converts subregister number to opsize}
       subreg2opsize:array[0..4] of Topsize = (S_B,S_B,S_W,S_L,S_D);
+      {Converts subregister number to cgsize}
+{      subreg2cgsize:array[0..4] of Tcgsize = (OS_8,OS_8,OS_16,OS_32);}
 
       {# Standard opcode string table (for each tasmop enumeration). The
          opcode strings should conform to the names as defined by the
@@ -295,6 +311,10 @@ uses
     type
       {# Type definition for the array of string of register names }
          reg2strtable = array[firstreg..lastreg] of string[6];
+         regname2regnumrec = record
+           name:string[6];
+           number:Tnewregister;
+         end;
 
     const
       {# Standard register table (for each tregister enumeration). The
@@ -313,7 +333,7 @@ uses
         'mm0','mm1','mm2','mm3','mm4','mm5','mm6','mm7',
         'xmm0','xmm1','xmm2','xmm3','xmm4','xmm5','xmm6','xmm7'
       );
-
+      
 {*****************************************************************************
                                 Conditions
 *****************************************************************************}
@@ -481,8 +501,10 @@ uses
 
       {# Constant defining possibly all registers which might require saving }
       ALL_REGISTERS = [firstreg..lastreg];
+      ALL_INTREGISTERS = [1..255];
 
       general_registers = [R_EAX,R_EBX,R_ECX,R_EDX];
+      general_superregisters = [RS_EAX,RS_EBX,RS_ECX,RS_EDX];
 
       {# low and high of the available maximum width integer general purpose }
       { registers                                                            }
@@ -508,7 +530,7 @@ uses
 
       maxintregs = 4;
       intregs = [R_EAX..R_BL];
-      usableregsint = [R_EAX,R_EBX,R_ECX,R_EDX];
+      usableregsint = [RS_EAX,RS_EBX,RS_ECX,RS_EDX];
       c_countusableregsint = 4;
 
       maxfpuregs = 8;
@@ -526,8 +548,8 @@ uses
       c_countusableregsaddr = 0;
       
 
-      firstsaveintreg = R_EAX;
-      lastsaveintreg  = R_EBX;
+      firstsaveintreg = RS_EAX;
+      lastsaveintreg  = RS_EDX;
       firstsavefpureg = R_NO;
       lastsavefpureg  = R_NO;
       firstsavemmreg  = R_MM0;
@@ -543,7 +565,7 @@ uses
          routine calls or in assembler blocks.
       }
       max_scratch_regs = 1;
-      scratch_regs : array[1..max_scratch_regs] of Toldregister = (R_EDI);
+      scratch_regs : array[1..max_scratch_regs] of Tsuperregister = (RS_EDI);
 
 
 {*****************************************************************************
@@ -590,11 +612,15 @@ uses
 
       {# Stack pointer register }
       stack_pointer_reg = R_ESP;
+      NR_STACK_POINTER_REG = NR_ESP;
       {# Frame pointer register }
       frame_pointer_reg = R_EBP;
+      NR_FRAME_POINTER_REG = NR_EBP;
       {# Self pointer register : contains the instance address of an
          object or class. }
       self_pointer_reg  = R_ESI;
+      RS_SELF_POINTER_REG  = RS_ESI;
+      NR_SELF_POINTER_REG  = NR_ESI;
       {# Register for addressing absolute data in a position independant way,
          such as in PIC code. The exact meaning is ABI specific. For
          further information look at GCC source : PIC_OFFSET_TABLE_REGNUM
@@ -602,16 +628,22 @@ uses
       pic_offset_reg = R_EBX;
       {# Results are returned in this register (32-bit values) }
       accumulator   = R_EAX;
-  {the return_result_reg, is used inside the called function to store its return
-  value when that is a scalar value otherwise a pointer to the address of the
-  result is placed inside it}
-  return_result_reg   = accumulator;
-
-  {the function_result_reg contains the function result after a call to a scalar
-  function othewise it contains a pointer to the returned result}
-  function_result_reg = accumulator;
+      RS_ACCUMULATOR   = RS_EAX;
+      NR_ACCUMULATOR   = NR_EAX;
+      {the return_result_reg, is used inside the called function to store its return
+      value when that is a scalar value otherwise a pointer to the address of the
+      result is placed inside it}
+    	return_result_reg		=	accumulator;
+      RS_RETURN_RESULT_REG = RS_ACCUMULATOR;
+      NR_RETURN_RESULT_REG = NR_ACCUMULATOR;
+
+      {the function_result_reg contains the function result after a call to a scalar
+      function othewise it contains a pointer to the returned result}
+    	function_result_reg	=	accumulator;
       {# Hi-Results are returned in this register (64-bit value high register) }
       accumulatorhigh = R_EDX;
+      RS_ACCUMULATORHIGH  = RS_EDX;
+      NR_ACCUMULATORHIGH  = NR_EDX;
       { WARNING: don't change to R_ST0!! See comments above implementation of }
       { a_loadfpu* methods in rgcpu (JM)                                      }
       fpu_result_reg = R_ST;
@@ -648,9 +680,8 @@ uses
 *****************************************************************************}
 
     procedure convert_register_to_enum(var r:Tregister);
-
+    function cgsize2subreg(s:Tcgsize):Tsubregister;
     function is_calljmp(o:tasmop):boolean;
-
     function flags_to_cond(const f: TResFlags) : TAsmCond;
 
 
@@ -687,6 +718,42 @@ implementation
           internalerror(200301082);
         end;
     end;
+    
+    function cgsize2subreg(s:Tcgsize):Tsubregister;
+    
+    begin
+      case s of
+        OS_8,OS_S8:
+          cgsize2subreg:=R_SUBL;
+        OS_16,OS_S16:
+          cgsize2subreg:=R_SUBW;
+        OS_32,OS_S32:
+          cgsize2subreg:=R_SUBD;
+        OS_64,OS_S64:
+          cgsize2subreg:=R_SUBQ;
+        else
+          internalerror(200301231);
+      end;
+    end;
+    
+    function supreg_name(r:Tsuperregister):string;
+    
+    var s:string[4];
+    
+    const supreg_names:array[0..last_supreg] of string[4]=
+          ('INV',
+           'eax','ebx','ecx','edx','esi','edi','ebp','esp',
+           'r8' ,'r9', 'r10','r11','r12','r13','r14','r15');
+    
+    begin
+      if r in [0..last_supreg] then
+        supreg_name:=supreg_names[r]
+      else
+        begin
+          str(r,s);
+          supreg_name:='reg'+s;
+        end;
+    end;
 
     function is_calljmp(o:tasmop):boolean;
       begin
@@ -720,7 +787,11 @@ implementation
 end.
 {
   $Log$
-  Revision 1.41  2003-02-02 19:25:54  carl
+  Revision 1.42  2003-02-19 22:00:15  daniel
+    * Code generator converted to new register notation
+    - Horribily outdated todo.txt removed
+
+  Revision 1.41  2003/02/02 19:25:54  carl
     * Several bugfixes for m68k target (register alloc., opcode emission)
     + VIS target
     + Generic add more complete (still not verified)

+ 21 - 7
compiler/i386/csopt386.pas

@@ -188,9 +188,12 @@ end;
 
 function isSimpleMemLoc(const ref: treference): boolean;
 begin
+{  isSimpleMemLoc :=
+    (ref.index.enum = R_NO) and
+    not(ref.base.enum in (rg.usableregsint+[R_EDI]));}
   isSimpleMemLoc :=
     (ref.index.enum = R_NO) and
-    not(ref.base.enum in (rg.usableregsint+[R_EDI]));
+    not(ref.base.enum in [R_ESI,R_EDI]);
 end;
 
 {checks whether the current instruction sequence (starting with p) and the
@@ -271,7 +274,10 @@ var
        (Taicpu(currentPrev).is_jmp));
     passedFlagsModifyingInstr := instrWritesFlags(currentPrev);
 
-    if (passedJump and not(reg.enum in (rg.usableregsint+[R_EDI]))) or
+{    if (passedJump and not(reg.enum in (rg.usableregsint+[R_EDI]))) or
+       not getLastInstruction(currentPrev,hp) then
+      exit;}
+    if (passedJump and not(reg.enum in [R_ESI,R_EDI])) or
        not getLastInstruction(currentPrev,hp) then
       exit;
 
@@ -298,7 +304,8 @@ var
         if { do not load the self pointer or a regvar before a (conditional)  }
            { jump with a new value, since if the jump is taken, the old value }
            { is (probably) still necessary                                    }
-           (passedJump and not(reg.enum in (rg.usableregsint+[R_EDI]))) or
+{           (passedJump and not(reg.enum in (rg.usableregsint+[R_EDI]))) or}
+           (passedJump and not(reg.enum in [R_ESI,R_EDI])) or
            not getLastInstruction(hp,hp) then
           break;
       end;
@@ -1321,7 +1328,8 @@ begin
          (rState = pTaiprop(startmod.optInfo)^.regs[reg.enum].rState) and
          (not(check) or
           (not(regInInstruction(reg.enum,p)) and
-           (not(reg.enum in rg.usableregsint) and
+           (not(reg.enum in [R_ESI,R_EDI]) and
+{           (not(reg.enum in rg.usableregsint) and}
             (startmod.typ = ait_instruction) and
             ((Taicpu(startmod).opcode = A_MOV) or
              (Taicpu(startmod).opcode = A_MOVZX) or
@@ -1580,7 +1588,8 @@ Begin
                                            Begin
                                              getLastInstruction(p,hp3);
                                              If (hp4 <> prevSeq) or
-                                                not(regCounter.enum in rg.usableregsint + [R_EDI,R_ESI]) or
+                                                {not(regCounter.enum in rg.usableregsint + [R_EDI,R_ESI]) or}
+                                                not(regCounter.enum in [R_EDI,R_ESI]) or
                                                 not ReplaceReg(asmL,RegInfo.New2OldReg[RegCounter.enum],
                                                       regCounter,hp3,
                                                       PTaiProp(PrevSeq.optInfo)^.Regs[regCounter.enum],true,hp5) then
@@ -1686,7 +1695,8 @@ Begin
                         if (Taicpu(p).oper[0].typ = top_reg) and
                            (Taicpu(p).oper[1].typ = top_reg) and
                            { only remove if we're not storing something in a regvar }
-                           (Taicpu(p).oper[1].reg.enum in (rg.usableregsint+[R_EDI])) and
+                           (Taicpu(p).oper[1].reg.enum in [R_ESI,R_EDI]) and
+{                           (Taicpu(p).oper[1].reg.enum in (rg.usableregsint+[R_EDI])) and}
                            (Taicpu(p).opcode = A_MOV) and
                            getLastInstruction(p,hp4) and
                           { we only have to start replacing from the instruction after the mov, }
@@ -1989,7 +1999,11 @@ End.
 
 {
   $Log$
-  Revision 1.39  2003-01-08 18:43:57  daniel
+  Revision 1.40  2003-02-19 22:00:15  daniel
+    * Code generator converted to new register notation
+    - Horribily outdated todo.txt removed
+
+  Revision 1.39  2003/01/08 18:43:57  daniel
    * Tregister changed into a record
 
   Revision 1.38  2002/08/18 20:06:29  peter

+ 15 - 5
compiler/i386/daopt386.pas

@@ -434,7 +434,7 @@ begin
           end;
     end;
   for regCounter := R_EAX to R_EBX do
-    if not(regCounter in rg.usableregsint) then
+{    if not(regCounter in rg.usableregsint) then}
       include(regs,regCounter);
 end;
 
@@ -443,12 +443,16 @@ var hp1: Tai;
     funcResRegs: TRegset;
     funcResReg: boolean;
 begin
+
   if reg.enum>lastreg then
     internalerror(200301081);
-  if not(reg.enum in rg.usableregsint) then
+{ if not(reg.enum in rg.usableregsint) then
+    exit;}
+ if not(reg.enum in [R_ESI,R_EDI]) then
     exit;
   getNoDeallocRegs(funcResRegs);
-  funcResRegs := funcResRegs - rg.usableregsint;
+{  funcResRegs := funcResRegs - rg.usableregsint;}
+  funcResRegs := funcResRegs - [R_ESI,R_EDI];
   funcResReg := reg.enum in funcResRegs;
   hp1 := p;
   while not(funcResReg and
@@ -1197,7 +1201,9 @@ var
 Begin
   if reg.enum>lastreg then
     internalerror(200301081);
-  If not(reg.enum in rg.usableregsint+[R_EDI,R_ESI]) or
+{ If not(reg.enum in rg.usableregsint+[R_EDI,R_ESI]) or
+     not(assigned(p1)) then}
+ If not(reg.enum in [R_EDI,R_ESI]) or
      not(assigned(p1)) then
     { this happens with registers which are loaded implicitely, outside the }
     { current block (e.g. esi with self)                                    }
@@ -2664,7 +2670,11 @@ End.
 
 {
   $Log$
-  Revision 1.45  2003-01-08 18:43:57  daniel
+  Revision 1.46  2003-02-19 22:00:15  daniel
+    * Code generator converted to new register notation
+    - Horribily outdated todo.txt removed
+
+  Revision 1.45  2003/01/08 18:43:57  daniel
    * Tregister changed into a record
 
   Revision 1.44  2002/11/17 16:31:59  carl

+ 40 - 39
compiler/i386/n386add.pas

@@ -195,6 +195,7 @@ interface
         power : longint;
         hl4   : tasmlabel;
         r:Tregister;
+        nr:Tnewregister;
       begin
         { at this point, left.location.loc should be LOC_REGISTER }
         if right.location.loc=LOC_REGISTER then
@@ -224,13 +225,12 @@ interface
             begin
               if extra_not then
                 emit_reg(A_NOT,opsize,left.location.register);
-              rg.getexplicitregisterint(exprasmlist,R_EDI);
               r.enum:=R_INTREGISTER;
               r.number:=NR_EDI;
+              rg.getexplicitregisterint(exprasmlist,NR_EDI);
               cg.a_load_loc_reg(exprasmlist,right.location,r);
               emit_reg_reg(op,opsize,left.location.register,r);
               emit_reg_reg(A_MOV,opsize,r,left.location.register);
-              r.enum:=R_EDI;
               rg.ungetregisterint(exprasmlist,r);
             end
            else
@@ -271,13 +271,12 @@ interface
                  begin
                    if extra_not then
                      begin
-                        rg.getexplicitregisterint(exprasmlist,R_EDI);
+                        rg.getexplicitregisterint(exprasmlist,NR_EDI);
                         r.enum:=R_INTREGISTER;
                         r.number:=NR_EDI;
                         cg.a_load_loc_reg(exprasmlist,right.location,r);
                         emit_reg(A_NOT,S_L,r);
                         emit_reg_reg(A_AND,S_L,r,left.location.register);
-                        r.enum:=R_EDI;
                         rg.ungetregisterint(exprasmlist,r);
                      end
                    else
@@ -346,8 +345,8 @@ interface
       var
         href       : treference;
         cmpop      : boolean;
-        pushed     : tpushedsaved;
-        regstopush : tregisterset;
+        pushed     : Tpushedsavedint;
+        regstopush : Tsupregset;
       begin
         { string operations are not commutative }
         if nf_swaped in flags then
@@ -385,9 +384,9 @@ interface
                         { push them (so the release is in the right place, }
                         { because emitpushreferenceaddr doesn't need extra }
                         { registers) (JM)                                  }
-                        regstopush := all_registers;
+                        regstopush := all_intregisters;
                         remove_non_regvars_from_loc(right.location,regstopush);
-                        rg.saveusedregisters(exprasmlist,pushed,regstopush);
+                        rg.saveusedintregisters(exprasmlist,pushed,regstopush);
                         { push the maximum possible length of the result }
                         cg.a_paramaddr_ref(exprasmlist,left.location.reference,paramanager.getintparaloc(2));
                         { the optimizer can more easily put the          }
@@ -396,27 +395,27 @@ interface
                         { the pushref needs a "lea (..),edi; push edi")  }
                         location_release(exprasmlist,right.location);
                         cg.a_paramaddr_ref(exprasmlist,right.location.reference,paramanager.getintparaloc(1));
-                        rg.saveregvars(exprasmlist,regstopush);
+                        rg.saveintregvars(exprasmlist,regstopush);
                         cg.a_call_name(exprasmlist,'FPC_SHORTSTR_CONCAT');
                         tg.ungetiftemp(exprasmlist,right.location.reference);
                         cg.g_maybe_loadself(exprasmlist);
-                        rg.restoreusedregisters(exprasmlist,pushed);
+                        rg.restoreusedintregisters(exprasmlist,pushed);
                         location_copy(location,left.location);
                      end;
                    ltn,lten,gtn,gten,equaln,unequaln :
                      begin
                        cmpop := true;
-                       rg.saveusedregisters(exprasmlist,pushed,all_registers);
+                       rg.saveusedintregisters(exprasmlist,pushed,all_intregisters);
                        secondpass(left);
                        location_release(exprasmlist,left.location);
                        cg.a_paramaddr_ref(exprasmlist,left.location.reference,paramanager.getintparaloc(2));
                        secondpass(right);
                        location_release(exprasmlist,right.location);
                        cg.a_paramaddr_ref(exprasmlist,right.location.reference,paramanager.getintparaloc(1));
-                       rg.saveregvars(exprasmlist,all_registers);
+                       rg.saveintregvars(exprasmlist,all_intregisters);
                        cg.a_call_name(exprasmlist,'FPC_SHORTSTR_COMPARE');
                        cg.g_maybe_loadself(exprasmlist);
-                       rg.restoreusedregisters(exprasmlist,pushed);
+                       rg.restoreusedintregisters(exprasmlist,pushed);
                        location_freetemp(exprasmlist,left.location);
                        location_freetemp(exprasmlist,right.location);
                      end;
@@ -672,9 +671,9 @@ interface
         { on comparison load flags }
         if cmpop then
          begin
-           if not(R_EAX in rg.unusedregsint) then
+           if not(RS_EAX in rg.unusedregsint) then
              begin
-               rg.getexplicitregisterint(exprasmlist,R_EDI);
+               rg.getexplicitregisterint(exprasmlist,NR_EDI);
                r.enum:=R_EAX;
                r2.enum:=R_EDI;
                emit_reg_reg(A_MOV,S_L,r,r2);
@@ -682,7 +681,7 @@ interface
            r.enum:=R_AX;
            emit_reg(A_FNSTSW,S_NO,r);
            emit_none(A_SAHF,S_NO);
-           if not(R_EAX in rg.unusedregsint) then
+           if not(RS_EAX in rg.unusedregsint) then
              begin
                r.enum:=R_EAX;
                r2.enum:=R_EDI;
@@ -982,8 +981,8 @@ interface
                     location_freetemp(exprasmlist,left.location);
                     location_release(exprasmlist,left.location);
                   end;
-                 hregister:=rg.getregisterint(exprasmlist);
-                 hregister2:=rg.getregisterint(exprasmlist);
+                 hregister:=rg.getregisterint(exprasmlist,OS_INT);
+                 hregister2:=rg.getregisterint(exprasmlist,OS_INT);
                  cg64.a_load64_loc_reg(exprasmlist,left.location,joinreg64(hregister,hregister2));
                  location_reset(left.location,LOC_REGISTER,OS_64);
                  left.location.registerlow:=hregister;
@@ -1029,7 +1028,7 @@ interface
            { right.location<>LOC_REGISTER }
            if (nodetype=subn) and (nf_swaped in flags) then
             begin
-              rg.getexplicitregisterint(exprasmlist,R_EDI);
+              rg.getexplicitregisterint(exprasmlist,NR_EDI);
               r.enum:=R_INTREGISTER;
               r.number:=NR_EDI;
               cg64.a_load64low_loc_reg(exprasmlist,right.location,r);
@@ -1039,7 +1038,6 @@ interface
               { the carry flag is still ok }
               emit_reg_reg(op2,opsize,left.location.registerhigh,r);
               emit_reg_reg(A_MOV,opsize,r,left.location.registerhigh);
-              r.enum:=R_EDI;
               rg.ungetregisterint(exprasmlist,r);
               if right.location.loc<>LOC_CREGISTER then
                begin
@@ -1337,7 +1335,7 @@ interface
          { true, if for sets subtractions the extra not should generated }
          extra_not : boolean;
 
-         regstopush: tregisterset;
+         regstopush:Tsupregset;
          r:Tregister;
 
       begin
@@ -1467,7 +1465,7 @@ interface
                { the location.register will be filled in later (JM) }
                location_reset(location,LOC_REGISTER,OS_INT);
 
-               regstopush := all_registers;
+               regstopush := all_intregisters;
                remove_non_regvars_from_loc(right.location,regstopush);
                remove_non_regvars_from_loc(left.location,regstopush);
                { now, regstopush does NOT contain EAX and/or EDX if they are }
@@ -1475,53 +1473,52 @@ interface
                {they are regvars. It DOES contain them if they are used in   }
                { another location (JM)                                       }
                r.enum:=R_INTREGISTER;
-               if not(R_EAX in rg.unusedregsint) and
-                  (R_EAX in regstopush) then
+               if not(RS_EAX in rg.unusedregsint) and
+                  (RS_EAX in regstopush) then
                  begin
                    r.number:=NR_EAX;
                    emit_reg(A_PUSH,S_L,r);
                    popeax:=true;
                  end;
-               if not(R_EDX in rg.unusedregsint) and
-                   (R_EDX in regstopush) then
+               if not(RS_EDX in rg.unusedregsint) and
+                   (RS_EDX in regstopush) then
                  begin
                    r.number:=NR_EDX;
                    emit_reg(A_PUSH,S_L,r);
                    popedx:=true;
                  end;
                { left.location can be R_EAX !!! }
-               rg.getexplicitregisterint(exprasmlist,R_EDI);
+               rg.getexplicitregisterint(exprasmlist,NR_EDI);
                { load the left value }
                r.number:=NR_EDI;
                cg.a_load_loc_reg(exprasmlist,left.location,r);
                location_release(exprasmlist,left.location);
                { allocate EAX }
                r.number:=NR_EAX;
-               if R_EAX in rg.unusedregsint then
+               if RS_EAX in rg.unusedregsint then
                  exprasmList.concat(tai_regalloc.Alloc(r));
                { load he right value }
                cg.a_load_loc_reg(exprasmlist,right.location,r);
                location_release(exprasmlist,right.location);
                { allocate EAX if it isn't yet allocated (JM) }
-               if (R_EAX in rg.unusedregsint) then
-                 exprasmList.concat(tai_regalloc.Alloc(r));
+               if (RS_EAX in rg.unusedregsint) then
+                 exprasmlist.concat(tai_regalloc.Alloc(r));
                { also allocate EDX, since it is also modified by }
                { a mul (JM)                                      }
                r.number:=NR_EDX;
-               if R_EDX in rg.unusedregsint then
-                 exprasmList.concat(tai_regalloc.Alloc(r));
+               if RS_EDX in rg.unusedregsint then
+                 exprasmlist.concat(tai_regalloc.Alloc(r));
                r.number:=NR_EDI;
                emit_reg(A_MUL,S_L,r);
-               r.enum:=R_EDI;
                rg.ungetregisterint(exprasmlist,r);
                r.enum:=R_INTREGISTER;
                r.number:=NR_EDX;
-               if R_EDX in rg.unusedregsint then
-                 exprasmList.concat(tai_regalloc.DeAlloc(r));
+               if RS_EDX in rg.unusedregsint then
+                 exprasmlist.concat(tai_regalloc.DeAlloc(r));
                r.number:=NR_EAX;
-               if R_EAX in rg.unusedregsint then
-                 exprasmList.concat(tai_regalloc.DeAlloc(r));
-               location.register:=rg.getregisterint(exprasmlist);
+               if RS_EAX in rg.unusedregsint then
+                 exprasmlist.concat(tai_regalloc.DeAlloc(r));
+               location.register:=rg.getregisterint(exprasmlist,OS_INT);
                r.number:=NR_EAX;
                emit_reg_reg(A_MOV,S_L,r,location.register);
                r.number:=NR_EDX;
@@ -1589,7 +1586,11 @@ begin
 end.
 {
   $Log$
-  Revision 1.54  2003-01-13 18:37:44  daniel
+  Revision 1.55  2003-02-19 22:00:15  daniel
+    * Code generator converted to new register notation
+    - Horribily outdated todo.txt removed
+
+  Revision 1.54  2003/01/13 18:37:44  daniel
     * Work on register conversion
 
   Revision 1.53  2003/01/08 18:43:57  daniel

+ 87 - 51
compiler/i386/n386cal.pas

@@ -288,9 +288,11 @@ implementation
 
     procedure ti386callnode.pass_2;
       var
-         regs_to_push : tregisterset;
+         regs_to_push_int : Tsupregset;
+         regs_to_push_other : tregisterset;
          unusedstate: pointer;
          pushed : tpushedsaved;
+         pushed_int : tpushedsavedint;
          tmpreg : tregister;
          hregister : tregister;
          oldpushedparasize : longint;
@@ -420,23 +422,29 @@ implementation
 
               { save all used registers and possible registers
                 used for the return value }
-              regs_to_push := tprocdef(procdefinition).usedregisters;
+              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
                begin
-                 include(regs_to_push,accumulator);
+                 include(regs_to_push_int,RS_ACCUMULATOR);
                  if resulttype.def.size>sizeof(aword) then
-                   include(regs_to_push,accumulatorhigh);
+                   include(regs_to_push_int,RS_ACCUMULATORHIGH);
                end;
-              rg.saveusedregisters(exprasmlist,pushed,regs_to_push);
+              rg.saveusedintregisters(exprasmlist,pushed_int,regs_to_push_int);
+              rg.saveusedotherregisters(exprasmlist,pushed,regs_to_push_other);
 
               { give used registers through }
-              rg.usedinproc:=rg.usedinproc + tprocdef(procdefinition).usedregisters;
+              rg.usedintinproc:=rg.usedintinproc + tprocdef(procdefinition).usedintregisters;
+              rg.usedinproc:=rg.usedinproc + tprocdef(procdefinition).usedotherregisters;
            end
          else
            begin
-              regs_to_push := all_registers;
-              rg.saveusedregisters(exprasmlist,pushed,regs_to_push);
+              regs_to_push_int := all_intregisters;
+              regs_to_push_other:=all_registers;
+              rg.saveusedintregisters(exprasmlist,pushed_int,regs_to_push_int);
+              rg.saveusedotherregisters(exprasmlist,pushed,regs_to_push_other);
+              rg.usedintinproc:=all_intregisters;
               rg.usedinproc:=all_registers;
               { no IO check for methods and procedure variables }
               iolabel:=nil;
@@ -595,8 +603,9 @@ implementation
                    { dirty trick to avoid the secondcall below }
                    methodpointer:=ccallparanode.create(nil,nil);
                    location_reset(methodpointer.location,LOC_REGISTER,OS_ADDR);
-                   rg.getexplicitregisterint(exprasmlist,R_ESI);
-                   methodpointer.location.register.enum:=R_ESI;
+                   rg.getexplicitregisterint(exprasmlist,NR_ESI);
+                   methodpointer.location.register.enum:=R_INTREGISTER;
+                   methodpointer.location.register.number:=NR_SELF_POINTER_REG;
                    { ARGHHH this is wrong !!!
                      if we can init from base class for a child
                      class that the wrong VMT will be
@@ -605,7 +614,8 @@ implementation
                      twithnode(twithsymtable(symtableproc).withnode).left.resulttype;
                    { make a reference }
                    href:=twithnode(twithsymtable(symtableproc).withnode).withreference;
-                   r.enum:=self_pointer_reg;
+                   r.enum:=R_INTREGISTER;
+                   r.number:=NR_SELF_POINTER_REG;
                    if ((not(nf_islocal in twithnode(twithsymtable(symtableproc).withnode).flags)) and
                        (not twithsymtable(symtableproc).direct_with)) or
                       is_class_or_interface(methodpointer.resulttype.def) then
@@ -650,8 +660,9 @@ implementation
                                          { way to accept virtual static functions (PM)     }
                                          loadesi:=true;
                                          { if no VMT just use $0 bug0214 PM }
-                                         rg.getexplicitregisterint(exprasmlist,R_ESI);
-                                         r.enum:=self_pointer_reg;
+                                         rg.getexplicitregisterint(exprasmlist,NR_ESI);
+                                         r.enum:=R_INTREGISTER;
+                                         r.number:=NR_SELF_POINTER_REG;
                                          if not(oo_has_vmt in tobjectdef(methodpointer.resulttype.def).objectoptions) then
                                            cg.a_load_const_reg(exprasmlist,OS_ADDR,0,r)
                                          else
@@ -667,7 +678,8 @@ implementation
                                       loadesi:=false;
 
                                     { a class destructor needs a flag }
-                                    r.enum:=self_pointer_reg;
+                                    r.enum:=R_INTREGISTER;
+                                    r.number:=NR_SELF_POINTER_REG;
                                     if is_class(tobjectdef(methodpointer.resulttype.def)) and
                                        (procdefinition.proctypeoption=potype_destructor) then
                                       begin
@@ -675,7 +687,8 @@ implementation
                                         cg.a_param_reg(exprasmlist,OS_ADDR,r,paramanager.getintparaloc(1));
                                       end;
 
-                                    r.enum:=self_pointer_reg;
+                                    r.enum:=R_INTREGISTER;
+                                    r.number:=NR_SELF_POINTER_REG;
                                     if not(is_con_or_destructor and
                                            is_class(methodpointer.resulttype.def) and
                                            (procdefinition.proctypeoption in [potype_constructor,potype_destructor])
@@ -711,8 +724,9 @@ implementation
                                  begin
                                     { extended syntax of new }
                                     { ESI must be zero }
-                                    r.enum:=self_pointer_reg;
-                                    rg.getexplicitregisterint(exprasmlist,r.enum);
+                                    r.enum:=R_INTREGISTER;
+                                    r.number:=NR_SELF_POINTER_REG;
+                                    rg.getexplicitregisterint(exprasmlist,NR_ESI);
                                     cg.a_load_const_reg(exprasmlist,OS_ADDR,0,r);
                                     cg.a_param_reg(exprasmlist,OS_ADDR,r,paramanager.getintparaloc(2));
                                     { insert the vmt }
@@ -726,8 +740,9 @@ implementation
 
                                     { destructor with extended syntax called from dispose }
                                     { hdisposen always deliver LOC_REFERENCE          }
-                                    r.enum:=R_ESI;
-                                    rg.getexplicitregisterint(exprasmlist,R_ESI);
+                                    r.enum:=R_INTREGISTER;
+                                    r.number:=NR_SELF_POINTER_REG;
+                                    rg.getexplicitregisterint(exprasmlist,NR_ESI);
                                     emit_ref_reg(A_LEA,S_L,methodpointer.location.reference,r);
                                     reference_release(exprasmlist,methodpointer.location.reference);
                                     cg.a_param_reg(exprasmlist,OS_ADDR,r,paramanager.getintparaloc(2));
@@ -739,9 +754,10 @@ implementation
                                     { call to an instance member }
                                     if (symtableproc.symtabletype<>withsymtable) then
                                       begin
-                                         r.enum:=R_ESI;
+                                         r.enum:=R_INTREGISTER;
+                                         r.number:=NR_SELF_POINTER_REG;
                                          secondpass(methodpointer);
-                                         rg.getexplicitregisterint(exprasmlist,R_ESI);
+                                         rg.getexplicitregisterint(exprasmlist,NR_ESI);
                                          case methodpointer.location.loc of
                                             LOC_CREGISTER,
                                             LOC_REGISTER:
@@ -768,8 +784,9 @@ implementation
                                            ((po_classmethod in procdefinition.procoptions) and
                                             not(methodpointer.resulttype.def.deftype=classrefdef)) then
                                           begin
-                                            r.enum:=self_pointer_reg;
-                                            rg.getexplicitregisterint(exprasmlist,r.enum);
+                                            r.enum:=R_INTREGISTER;
+                                            r.number:=NR_SELF_POINTER_REG;
+                                            rg.getexplicitregisterint(exprasmlist,NR_ESI);
                                             if not(oo_has_vmt in tprocdef(procdefinition)._class.objectoptions) then
                                               cg.a_load_const_reg(exprasmlist,OS_ADDR,0,r)
                                             else
@@ -841,8 +858,9 @@ implementation
                                  (po_staticmethod in aktprocdef.procoptions))
                            ) then
                           begin
-                            r.enum:=self_pointer_reg;
-                            rg.getexplicitregisterint(exprasmlist,r.enum);
+                            r.enum:=R_INTREGISTER;
+                            r.number:=NR_SELF_POINTER_REG;
+                            rg.getexplicitregisterint(exprasmlist,NR_ESI);
                             if not(oo_has_vmt in tprocdef(procdefinition)._class.objectoptions) then
                              cg.a_load_const_reg(exprasmlist,OS_ADDR,0,r)
                             else
@@ -862,7 +880,8 @@ implementation
                         { direct call to destructor: don't remove data! }
                         if is_class(procinfo._class) then
                           begin
-                             r.enum:=R_ESI;
+                             r.enum:=R_INTREGISTER;
+                             r.number:=NR_SELF_POINTER_REG;
                              if (procdefinition.proctypeoption=potype_destructor) then
                                begin
                                   cg.a_param_const(exprasmlist,OS_INT,0,paramanager.getintparaloc(2));
@@ -878,7 +897,8 @@ implementation
                           end
                         else if is_object(procinfo._class) then
                           begin
-                             r.enum:=R_ESI;
+                             r.enum:=R_INTREGISTER;
+                             r.number:=NR_SELF_POINTER_REG;
                              cg.a_param_reg(exprasmlist,OS_ADDR,r,paramanager.getintparaloc(1));
                              if is_con_or_destructor then
                                begin
@@ -911,7 +931,8 @@ implementation
                    (inlined or
                    (right=nil)) then
                   begin
-                     r.enum:=self_pointer_reg;
+                     r.enum:=R_INTREGISTER;
+                     r.number:=NR_SELF_POINTER_REG;
                      cg.a_param_reg(exprasmlist,OS_ADDR,r,paramanager.getintparaloc(1));
                      reference_reset_base(href,r,0);
                      tmpreg:=cg.get_scratch_reg_address(exprasmlist);
@@ -952,7 +973,7 @@ implementation
                        end
                      else if (lexlevel>(tprocdef(procdefinition).parast.symtablelevel)) then
                        begin
-                          hregister:=rg.getregisterint(exprasmlist);
+                          hregister:=rg.getregisterint(exprasmlist,OS_ADDR);
                           reference_reset_base(href,procinfo.framepointer,procinfo.framepointer_offset);
                           cg.a_load_ref_reg(exprasmlist,OS_ADDR,href,hregister);
                           for i:=(tprocdef(procdefinition).parast.symtablelevel) to lexlevel-1 do
@@ -969,7 +990,7 @@ implementation
                        internalerror(25000);
                   end;
 
-              rg.saveregvars(exprasmlist,regs_to_push);
+              rg.saveintregvars(exprasmlist,regs_to_push_int);
 
               if (po_virtualmethod in procdefinition.procoptions) and
                  not(no_virtual_call) then
@@ -979,8 +1000,9 @@ implementation
                    { Here it is quite tricky because it also depends }
                    { on the methodpointer                        PM }
                    release_tmpreg:=false;
-                   rg.getexplicitregisterint(exprasmlist,R_ESI);
-                   r.enum:=R_ESI;
+                   rg.getexplicitregisterint(exprasmlist,NR_ESI);
+                   r.enum:=R_INTREGISTER;
+                   r.number:=NR_SELF_POINTER_REG;
                    if assigned(aktprocdef) then
                      begin
                        if (((sp_static in aktprocdef.procsym.symoptions) or
@@ -1032,7 +1054,8 @@ implementation
                   if (po_interrupt in procdefinition.procoptions) then
                     begin
                         emit_none(A_PUSHF,S_L);
-                        r.enum:=R_CS;
+                        r.enum:=R_INTREGISTER;
+                        r.number:=NR_CS;
                         emit_reg(A_PUSH,S_L,r);
                     end;
                   cg.a_call_name(exprasmlist,tprocdef(procdefinition).mangledname);
@@ -1054,20 +1077,22 @@ implementation
               if (po_interrupt in procdefinition.procoptions) then
                 begin
                     emit_none(A_PUSHF,S_L);
-                    r.enum:=R_CS;
+                    r.enum:=R_INTREGISTER;
+                    r.number:=NR_CS;
                     emit_reg(A_PUSH,S_L,r);
                 end;
               { procedure of object? }
               if (po_methodpointer in procdefinition.procoptions) then
                 begin
                    { method pointer can't be in a register }
-                   hregister.enum:=R_NO;
+                   hregister.enum:=R_INTREGISTER;
+                   hregister.number:=NR_NO;
 
                    { do some hacking if we call a method pointer }
                    { which is a class member                 }
                    { else ESI is overwritten !             }
-                   if (right.location.reference.base.enum=R_ESI) or
-                      (right.location.reference.index.enum=R_ESI) then
+                   if (right.location.reference.base.number=NR_ESI) or
+                      (right.location.reference.index.number=NR_ESI) then
                      begin
                         reference_release(exprasmlist,right.location.reference);
                         hregister:=cg.get_scratch_reg_address(exprasmlist);
@@ -1080,27 +1105,30 @@ implementation
                        { load ESI }
                        href:=right.location.reference;
                        inc(href.offset,4);
-                       r.enum:=self_pointer_reg;
-                       rg.getexplicitregisterint(exprasmlist,R_ESI);
+                       r.enum:=R_INTREGISTER;
+                       r.number:=NR_SELF_POINTER_REG;
+                       rg.getexplicitregisterint(exprasmlist,NR_ESI);
                        cg.a_load_ref_reg(exprasmlist,OS_ADDR,href,r);
                        { push self pointer }
                        cg.a_param_reg(exprasmlist,OS_ADDR,r,paralocdummy);
                      end;
 
-                   rg.saveregvars(exprasmlist,ALL_REGISTERS);
-                   if hregister.enum<>R_NO then
+                   rg.saveintregvars(exprasmlist,ALL_INTREGISTERS);
+                   rg.saveotherregvars(exprasmlist,ALL_REGISTERS);
+                   if hregister.number<>NR_NO then
                      cg.a_call_reg(exprasmlist,hregister)
                    else
                      cg.a_call_ref(exprasmlist,right.location.reference);
 
-                   if hregister.enum<>R_NO then
+                   if hregister.number<>NR_NO then
                      cg.free_scratch_reg(exprasmlist,hregister);
                    reference_release(exprasmlist,right.location.reference);
                    tg.Ungetiftemp(exprasmlist,right.location.reference);
                 end
               else
                 begin
-                   rg.saveregvars(exprasmlist,ALL_REGISTERS);
+                   rg.saveintregvars(exprasmlist,ALL_INTREGISTERS);
+                   rg.saveotherregvars(exprasmlist,ALL_REGISTERS);
                    cg.a_call_loc(exprasmlist,right.location);
                    location_release(exprasmlist,right.location);
                    location_freetemp(exprasmlist,right.location);
@@ -1117,8 +1145,9 @@ implementation
                 { better than an add on all processors }
                 if pushedparasize=4 then
                   begin
-                    r.enum:=R_EDI;
-                    rg.getexplicitregisterint(exprasmlist,R_EDI);
+                    r.enum:=R_INTREGISTER;
+                    r.number:=NR_EDI;
+                    rg.getexplicitregisterint(exprasmlist,NR_EDI);
                     emit_reg(A_POP,S_L,r);
                     rg.ungetregisterint(exprasmlist,r);
                   end
@@ -1129,12 +1158,12 @@ implementation
                   (aktoptprocessor=ClassP5) and
                   (procinfo._class=nil) then
                     begin
-                       rg.getexplicitregisterint(exprasmlist,R_EDI);
+                       rg.getexplicitregisterint(exprasmlist,NR_EDI);
                        r.enum:=R_INTREGISTER;
                        r.number:=NR_EDI;
                        emit_reg(A_POP,S_L,r);
                        rg.ungetregisterint(exprasmlist,r);
-                       r.enum:=R_ESI;
+                       r.number:=NR_ESI;
                        exprasmList.concat(tai_regalloc.Alloc(r));
                        emit_reg(A_POP,S_L,r);
                        exprasmList.concat(tai_regalloc.DeAlloc(r));
@@ -1180,8 +1209,10 @@ implementation
            assigned(methodpointer) and
            (methodpointer.nodetype<>typen) then
            begin
-              r.enum:=accumulator;
-              r2.enum:=self_pointer_reg;
+              r.enum:=R_INTREGISTER;
+              r.number:=NR_ACCUMULATOR;
+              r2.enum:=R_INTREGISTER;
+              r2.number:=NR_SELF_POINTER_REG;
               objectlibrary.getlabel(constructorfailed);
               emitjmp(C_Z,constructorfailed);
               cg.a_param_reg(exprasmlist,OS_ADDR,r2,paramanager.getintparaloc(1));
@@ -1211,7 +1242,8 @@ implementation
            emit_const_reg(A_ADD,S_L,pop_size,rsp);
 
          { restore registers }
-         rg.restoreusedregisters(exprasmlist,pushed);
+         rg.restoreusedotherregisters(exprasmlist,pushed);
+         rg.restoreusedintregisters(exprasmlist,pushed_int);
 
          { at last, restore instance pointer (SELF) }
          if loadesi then
@@ -1282,7 +1314,11 @@ begin
 end.
 {
   $Log$
-  Revision 1.81  2003-01-30 21:46:57  peter
+  Revision 1.82  2003-02-19 22:00:15  daniel
+    * Code generator converted to new register notation
+    - Horribily outdated todo.txt removed
+
+  Revision 1.81  2003/01/30 21:46:57  peter
     * self fixes for static methods (merged)
 
   Revision 1.80  2003/01/13 18:37:44  daniel

+ 16 - 11
compiler/i386/n386cnv.pas

@@ -117,7 +117,7 @@ implementation
                    hregister:=left.location.register;
                  else
                    begin
-                     hregister:=cg.get_scratch_reg_int(exprasmlist);
+                     hregister:=cg.get_scratch_reg_int(exprasmlist,OS_32);
                      freereg:=true;
                      cg.a_load_reg_reg(exprasmlist,left.location.size,OS_32,left.location.register,hregister);
                    end;
@@ -126,7 +126,7 @@ implementation
            LOC_REFERENCE,
            LOC_CREFERENCE :
              begin
-               hregister:=cg.get_scratch_reg_int(exprasmlist);
+               hregister:=cg.get_scratch_reg_int(exprasmlist,OS_INT);
                freereg:=true;
                if left.location.size in [OS_64,OS_S64] then
                 begin
@@ -170,14 +170,16 @@ implementation
                 { we load bits 0..62 and then check bit 63:  }
                 { if it is 1 then we add $80000000 000000000 }
                 { as double                                  }
-                r.enum:=R_EDI;
+                r.enum:=R_INTREGISTER;
+                r.number:=NR_EDI;
                 inc(href.offset,4);
-                rg.getexplicitregisterint(exprasmlist,R_EDI);
+                rg.getexplicitregisterint(exprasmlist,NR_EDI);
                 emit_ref_reg(A_MOV,S_L,href,r);
                 r.enum:=R_ESP;
                 reference_reset_base(href,r,4);
                 emit_const_ref(A_AND,S_L,$7fffffff,href);
-                r.enum:=R_EDI;
+                r.enum:=R_INTREGISTER;
+                r.number:=NR_EDI;
                 emit_const_reg(A_TEST,S_L,longint($80000000),r);
                 rg.ungetregisterint(exprasmlist,r);
                 r.enum:=R_ESP;
@@ -198,11 +200,10 @@ implementation
            else
              begin
                 emit_ref(A_FILD,S_IL,href);
-                rg.getexplicitregisterint(exprasmlist,R_EDI);
+                rg.getexplicitregisterint(exprasmlist,NR_EDI);
                 r.enum:=R_INTREGISTER;
                 r.number:=NR_EDI;
                 emit_reg(A_POP,S_L,r);
-                r.enum:=R_EDI;
                 rg.ungetregisterint(exprasmlist,r);
              end;
          end;
@@ -246,7 +247,7 @@ implementation
               begin
                 if left.location.size in [OS_64,OS_S64] then
                  begin
-                   hregister:=rg.getregisterint(exprasmlist);
+                   hregister:=rg.getregisterint(exprasmlist,OS_INT);
                    emit_ref_reg(A_MOV,S_L,left.location.reference,hregister);
                    pref:=left.location.reference;
                    inc(pref.offset,4);
@@ -266,7 +267,7 @@ implementation
               begin
                 if left.location.size in [OS_64,OS_S64] then
                  begin
-                   hregister:=cg.get_scratch_reg_int(exprasmlist);
+                   hregister:=cg.get_scratch_reg_int(exprasmlist,OS_32);
                    cg.a_load_reg_reg(exprasmlist,OS_32,OS_32,left.location.registerlow,hregister);
                    cg.a_op_reg_reg(exprasmlist,OP_OR,OS_32,left.location.registerhigh,hregister);
                    cg.free_scratch_reg(exprasmlist,hregister);
@@ -276,7 +277,7 @@ implementation
               end;
             LOC_JUMP :
               begin
-                hregister:=rg.getregisterint(exprasmlist);
+                hregister:=rg.getregisterint(exprasmlist,OS_INT);
                 objectlibrary.getlabel(hlabel);
                 cg.a_label(exprasmlist,truelabel);
                 cg.a_load_const_reg(exprasmlist,OS_INT,1,hregister);
@@ -430,7 +431,11 @@ begin
 end.
 {
   $Log$
-  Revision 1.55  2003-01-13 18:37:44  daniel
+  Revision 1.56  2003-02-19 22:00:15  daniel
+    * Code generator converted to new register notation
+    - Horribily outdated todo.txt removed
+
+  Revision 1.55  2003/01/13 18:37:44  daniel
     * Work on register conversion
 
   Revision 1.54  2003/01/08 18:43:57  daniel

+ 9 - 3
compiler/i386/n386inl.pas

@@ -309,12 +309,14 @@ implementation
                 { type cast code which does range checking if necessary (FK) }
                 begin
                   scratch_reg := FALSE;
-                  hregister := rg.makeregsize(tcallparanode(tcallparanode(left).right).left.location.register,OS_INT);
+                  hregister.enum:=R_INTREGISTER;
+                  hregister.number:=(Tcallparanode(Tcallparanode(left).right).left.location.register.number and not $ff)
+                    or R_SUBWHOLE;
                 end
               else
                 begin
                   scratch_reg := TRUE;
-                  hregister:=cg.get_scratch_reg_int(exprasmlist);
+                  hregister:=cg.get_scratch_reg_int(exprasmlist,OS_INT);
                 end;
               cg.a_load_loc_reg(exprasmlist,tcallparanode(tcallparanode(left).right).left.location,hregister);
               if (tcallparanode(left).left.location.loc=LOC_REFERENCE) then
@@ -332,7 +334,11 @@ begin
 end.
 {
   $Log$
-  Revision 1.55  2003-01-08 18:43:57  daniel
+  Revision 1.56  2003-02-19 22:00:15  daniel
+    * Code generator converted to new register notation
+    - Horribily outdated todo.txt removed
+
+  Revision 1.55  2003/01/08 18:43:57  daniel
    * Tregister changed into a record
 
   Revision 1.54  2002/11/25 17:43:26  peter

+ 74 - 64
compiler/i386/n386mat.pas

@@ -95,32 +95,33 @@ implementation
               { put numerator in register }
               location_force_reg(exprasmlist,left.location,OS_INT,false);
               hreg1:=left.location.register;
+              if hreg1.enum<>R_INTREGISTER then
+                internalerror(200302042);
 
-              if (nodetype=divn) and
-                 (right.nodetype=ordconstn) and
+              if (nodetype=divn) and (right.nodetype=ordconstn) and
                  ispowerof2(tordconstnode(right).value,power) then
-                Begin
+                begin
                   shrdiv := true;
                   { for signed numbers, the numerator must be adjusted before the
                     shift instruction, but not wih unsigned numbers! Otherwise,
                     "Cardinal($ffffffff) div 16" overflows! (JM) }
-                  If is_signed(left.resulttype.def) Then
-                    Begin
-                      If (aktOptProcessor <> class386) and
+                  if is_signed(left.resulttype.def) Then
+                    begin
+                      if (aktOptProcessor <> class386) and
                          not(CS_LittleSize in aktglobalswitches) then
                          { use a sequence without jumps, saw this in
                            comp.compilers (JM) }
                         begin
                           { no jumps, but more operations }
-                          if (hreg1.enum = R_EAX) and
-                             (R_EDX in rg.unusedregsint) then
+                          if (hreg1.number = NR_EAX) and
+                             (RS_EDX in rg.unusedregsint) then
                             begin
-                              hreg2 := rg.getexplicitregisterint(exprasmlist,R_EDX);
+                              hreg2 := rg.getexplicitregisterint(exprasmlist,NR_EDX);
                               emit_none(A_CDQ,S_NO);
                             end
                           else
                             begin
-                              rg.getexplicitregisterint(exprasmlist,R_EDI);
+                              rg.getexplicitregisterint(exprasmlist,NR_EDI);
                               hreg2.enum := R_INTREGISTER;
                               hreg2.number := NR_EDI;
                               emit_reg_reg(A_MOV,S_L,hreg1,hreg2);
@@ -134,8 +135,6 @@ implementation
                           emit_reg_reg(A_ADD,S_L,hreg2,hreg1);
                           { release EDX if we used it }
                           { also releas EDI }
-                          if (hreg2.enum=R_INTREGISTER) and (hreg2.number=NR_EDI) then
-                            hreg2.enum:=R_EDI;
                           rg.ungetregisterint(exprasmlist,hreg2);
                           { do the shift }
                           emit_const_reg(A_SAR,S_L,power,hreg1);
@@ -153,17 +152,17 @@ implementation
                           cg.a_label(exprasmlist,hl);
                           emit_const_reg(A_SAR,S_L,power,hreg1);
                         end
-                    End
-                  Else
+                    end
+                  else
                     emit_const_reg(A_SHR,S_L,power,hreg1);
-                End
+                end
               else
                 begin
                   { bring denominator to EDI }
                   { EDI is always free, it's }
                   { only used for temporary  }
                   { purposes              }
-                  rg.getexplicitregisterint(exprasmlist,R_EDI);
+                  rg.getexplicitregisterint(exprasmlist,NR_EDI);
                   if right.location.loc<>LOC_CREGISTER then
                    location_release(exprasmlist,right.location);
                   r.enum:=R_INTREGISTER;
@@ -174,35 +173,35 @@ implementation
                   r.number:=NR_EAX;
                   r2.enum:=R_INTREGISTER;
                   r2.number:=NR_EDX;
-                  if hreg1.enum=R_EDX then
+                  if hreg1.number=NR_EDX then
                     begin
-                      if not(R_EAX in rg.unusedregsint) then
+                      if not(RS_EAX in rg.unusedregsint) then
                          begin
                             emit_reg(A_PUSH,S_L,r);
                             popeax:=true;
                          end
                        else
-                         rg.getexplicitregisterint(exprasmlist,R_EAX);
+                         rg.getexplicitregisterint(exprasmlist,NR_EAX);
                       emit_reg_reg(A_MOV,S_L,r2,r);
                     end
                   else
                     begin
-                       if not(R_EDX in rg.unusedregsint) then
+                       if not(RS_EDX in rg.unusedregsint) then
                          begin
                             emit_reg(A_PUSH,S_L,r2);
                             popedx:=true;
                          end
                        else
-                         rg.getexplicitregisterint(exprasmlist,R_EDX);
-                       if hreg1.enum<>R_EAX then
+                         rg.getexplicitregisterint(exprasmlist,NR_EDX);
+                       if hreg1.number<>NR_EAX then
                          begin
-                            if not(R_EAX in rg.unusedregsint) then
+                            if not(RS_EAX in rg.unusedregsint) then
                               begin
                                  emit_reg(A_PUSH,S_L,r);
                                  popeax:=true;
                               end
                             else
-                              rg.getexplicitregisterint(exprasmlist,R_EAX);
+                              rg.getexplicitregisterint(exprasmlist,NR_EAX);
                             emit_reg_reg(A_MOV,S_L,hreg1,r);
                          end;
                     end;
@@ -219,39 +218,39 @@ implementation
                     emit_reg(A_DIV,S_L,r)
                   else
                     emit_reg(A_IDIV,S_L,r);
-                  r.enum:=R_EDI;
                   rg.ungetregisterint(exprasmlist,r);
                   r.enum:=R_INTREGISTER;
                   r.number:=NR_EAX;
                   if nodetype=divn then
                     begin
-                       if not popedx and (hreg1.enum <> R_EDX) then
+                       if not popedx and (hreg1.number <> NR_EDX) then
                         begin
-                           r2.enum:=R_EDX;
-                           rg.ungetregister(exprasmlist,r2);
+                           r2.enum:=R_INTREGISTER;
+                           r2.number:=NR_EDX;
+                           rg.ungetregisterint(exprasmlist,r2);
                         end;
                        { if result register is busy then copy }
                        if popeax then
                          begin
-                            if hreg1.enum=R_EAX then
+                            if hreg1.number=NR_EAX then
                               internalerror(112);
                             emit_reg_reg(A_MOV,S_L,r,hreg1)
                          end
                        else
-                         if hreg1.enum<>R_EAX then
-                           Begin
+                         if hreg1.number<>NR_EAX then
+                           begin
                              rg.ungetregisterint(exprasmlist,hreg1);
                              { no need to allocate eax, that's already done before }
                              { the div (JM)                                        }
-                             hreg1.enum := R_EAX;
+                             hreg1.number:=NR_EAX;
                            end;
                     end
                   else
                     begin
-                      if not popeax and (hreg1.enum <> R_EAX)then
+                      if not popeax and (hreg1.number <> NR_EAX)then
                         begin
-                          r.enum:=R_EAX;
-                          rg.ungetregister(exprasmlist,r);
+                          r.number:=NR_EAX;
+                          rg.ungetregisterint(exprasmlist,r);
                         end;
                       if popedx then
                        {the mod was done by an (i)div (so the result is now in
@@ -259,11 +258,11 @@ implementation
                         move the result into a safe place (JM)}
                         emit_reg_reg(A_MOV,S_L,r2,hreg1)
                       else
-                        Begin
-                          if hreg1.enum <> R_EDX then
+                        begin
+                          if hreg1.number <> NR_EDX then
                             rg.ungetregisterint(exprasmlist,hreg1);
-                          hreg1.enum := R_EDX
-                        End;
+                          hreg1.number:=NR_EDX
+                        end;
                     end;
                   if popeax then
                     emit_reg(A_POP,S_L,r);
@@ -274,10 +273,10 @@ implementation
                { shrdiv only use hreg1 (which is already in usedinproc,   }
                { since it was acquired with getregister), the others also }
                { use both EAX and EDX (JM)                                }
-                Begin
-                  include(rg.usedinproc,R_EAX);
-                  include(rg.usedinproc,R_EDX);
-                End;
+                begin
+                  include(rg.usedintinproc,RS_EAX);
+                  include(rg.usedintinproc,RS_EDX);
+                end;
               location_reset(location,LOC_REGISTER,OS_INT);
               location.register:=hreg1;
            end;
@@ -325,6 +324,10 @@ implementation
               location_force_reg(exprasmlist,left.location,OS_64,false);
               hregisterhigh:=left.location.registerhigh;
               hregisterlow:=left.location.registerlow;
+              if hregisterhigh.enum<>R_INTREGISTER then
+                internalerror(200302056);
+              if hregisterlow.enum<>R_INTREGISTER then
+                internalerror(200302056);
 
               { shifting by a constant directly coded: }
               if (right.nodetype=ordconstn) then
@@ -378,7 +381,7 @@ implementation
                      begin
                        if right.location.loc<>LOC_CREGISTER then
                         location_release(exprasmlist,right.location);
-                       hregister2:=rg.getexplicitregisterint(exprasmlist,R_ECX);
+                       hregister2:=rg.getexplicitregisterint(exprasmlist,NR_ECX);
                        cg.a_load_loc_reg(exprasmlist,right.location,hregister2);
                      end
                    else
@@ -387,9 +390,11 @@ implementation
                    { left operator is already in a register }
                    { hence are both in a register }
                    { is it in the case ECX ? }
-                   r.enum:=R_ECX;
-                   r2.enum:=R_CL;
-                   if (hregisterlow.enum=R_ECX) then
+                   r.enum:=R_INTREGISTER;
+                   r.number:=NR_ECX;
+                   r2.enum:=R_INTREGISTER;
+                   r2.number:=NR_CL;
+                   if (hregisterlow.number=NR_ECX) then
                      begin
                         { then only swap }
                         emit_reg_reg(A_XCHG,S_L,hregisterlow,hregister2);
@@ -397,7 +402,7 @@ implementation
                         hregisterlow:=hregister2;
                         hregister2:=hregister3;
                      end
-                   else if (hregisterhigh.enum=R_ECX) then
+                   else if (hregisterhigh.number=NR_ECX) then
                      begin
                         { then only swap }
                         emit_reg_reg(A_XCHG,S_L,hregisterhigh,hregister2);
@@ -407,20 +412,20 @@ implementation
                      end
 
                    { if second operator not in ECX ? }
-                   else if (hregister2.enum<>R_ECX) then
+                   else if (hregister2.number<>NR_ECX) then
                      begin
                         { ECX occupied then push it }
-                        if not (R_ECX in rg.unusedregsint) then
+                        if not (RS_ECX in rg.unusedregsint) then
                          begin
                            popecx:=true;
                            emit_reg(A_PUSH,S_L,r);
                          end
                         else
-                          rg.getexplicitregisterint(exprasmlist,R_ECX);
+                          rg.getexplicitregisterint(exprasmlist,NR_ECX);
                         emit_reg_reg(A_MOV,S_L,hregister2,r);
                      end;
 
-                   if hregister2.enum <> R_ECX then
+                   if hregister2.number <> NR_ECX then
                      rg.ungetregisterint(exprasmlist,hregister2);
 
                    { the damned shift instructions work only til a count of 32 }
@@ -495,8 +500,10 @@ implementation
               location_copy(location,left.location);
               location_force_reg(exprasmlist,location,OS_INT,false);
               
-              r.enum:=R_ECX;
-              r2.enum:=R_CL;
+              r.enum:=R_INTREGISTER;
+              r.number:=NR_ECX;
+              r2.enum:=R_INTREGISTER;
+              r2.number:=NR_CL;
 
               { shifting by a constant directly coded: }
               if (right.nodetype=ordconstn) then
@@ -519,7 +526,7 @@ implementation
                      begin
                        if right.location.loc<>LOC_CREGISTER then
                         location_release(exprasmlist,right.location);
-                       hregister2:=rg.getexplicitregisterint(exprasmlist,R_ECX);
+                       hregister2:=rg.getexplicitregisterint(exprasmlist,NR_ECX);
                        cg.a_load_loc_reg(exprasmlist,right.location,hregister2);
                      end
                    else
@@ -528,7 +535,7 @@ implementation
                    { left operator is already in a register }
                    { hence are both in a register }
                    { is it in the case ECX ? }
-                   if (location.register.enum=R_ECX) then
+                   if (location.register.number=NR_ECX) then
                      begin
                         { then only swap }
                         emit_reg_reg(A_XCHG,S_L,location.register,hregister2);
@@ -537,16 +544,16 @@ implementation
                         hregister2:=hregister3;
                      end
                    { if second operator not in ECX ? }
-                   else if (hregister2.enum<>R_ECX) then
+                   else if (hregister2.number<>NR_ECX) then
                      begin
                         { ECX occupied then push it }
-                        if not (R_ECX in rg.unusedregsint) then
+                        if not (RS_ECX in rg.unusedregsint) then
                          begin
                            popecx:=true;
                            emit_reg(A_PUSH,S_L,r);
                          end
                         else
-                          rg.getexplicitregisterint(exprasmlist,R_ECX);
+                          rg.getexplicitregisterint(exprasmlist,NR_ECX);
                         emit_reg_reg(A_MOV,S_L,hregister2,r);
                      end;
                    rg.ungetregisterint(exprasmlist,hregister2);
@@ -673,7 +680,7 @@ implementation
                    end;
                  LOC_CREGISTER:
                    begin
-                      location.register:=rg.getregisterint(exprasmlist);
+                      location.register:=rg.getregisterint(exprasmlist,OS_INT);
                       emit_reg_reg(A_MOV,S_L,left.location.register,
                         location.register);
                       emit_reg(A_NEG,S_L,location.register);
@@ -721,7 +728,7 @@ implementation
 {$endif SUPPORT_MMX}
                       else
                         begin
-                           location.register:=rg.getregisterint(exprasmlist);
+                           location.register:=rg.getregisterint(exprasmlist,OS_INT);
                            emit_ref_reg(A_MOV,S_L,left.location.reference,location.register);
                            emit_reg(A_NEG,S_L,location.register);
                         end;
@@ -817,7 +824,7 @@ implementation
              r.enum:=R_INTREGISTER;
              r.number:=NR_EDI;
              r2.enum:=R_MM7;
-             rg.getexplicitregisterint(exprasmlist,R_EDI);
+             rg.getexplicitregisterint(exprasmlist,NR_EDI);
              emit_const_reg(A_MOV,S_L,longint($ffffffff),r);
              { load operand }
              case left.location.loc of
@@ -838,7 +845,6 @@ implementation
              end;
              { load mask }
              emit_reg_reg(A_MOVD,S_NO,r,r2);
-             r.enum:=R_EDI;
              rg.ungetregisterint(exprasmlist,r);
              { lower 32 bit }
              emit_reg_reg(A_PXOR,S_D,r2,location.register);
@@ -877,7 +883,11 @@ begin
 end.
 {
   $Log$
-  Revision 1.44  2003-01-13 18:37:44  daniel
+  Revision 1.45  2003-02-19 22:00:15  daniel
+    * Code generator converted to new register notation
+    - Horribily outdated todo.txt removed
+
+  Revision 1.44  2003/01/13 18:37:44  daniel
     * Work on register conversion
 
   Revision 1.43  2003/01/13 14:54:34  daniel

+ 11 - 3
compiler/i386/n386mem.pas

@@ -97,12 +97,16 @@ implementation
        var
          l2 : integer;
        begin
+         if location.reference.base.enum<>R_INTREGISTER then
+          internalerror(200302055);
+         if location.reference.index.enum<>R_INTREGISTER then
+          internalerror(200302055);
          { Optimized for x86 to use the index register and scalefactor }
-         if location.reference.index.enum=R_NO then
+         if location.reference.index.number=NR_NO then
           begin
             { no preparations needed }
           end
-         else if location.reference.base.enum=R_NO then
+         else if location.reference.base.number=NR_NO then
           begin
             case location.reference.scalefactor of
              2 : cg.a_op_const_reg(exprasmlist,OP_SHL,1,location.reference.index);
@@ -152,7 +156,11 @@ begin
 end.
 {
   $Log$
-  Revision 1.49  2003-01-13 18:37:44  daniel
+  Revision 1.50  2003-02-19 22:00:15  daniel
+    * Code generator converted to new register notation
+    - Horribily outdated todo.txt removed
+
+  Revision 1.49  2003/01/13 18:37:44  daniel
     * Work on register conversion
 
   Revision 1.48  2003/01/08 18:43:57  daniel

+ 22 - 16
compiler/i386/n386opt.pas

@@ -110,7 +110,8 @@ begin
     end;
   secondpass(right);
   { special case for string := string + char (JM) }
-  hreg.enum := R_NO;
+  hreg.enum:=R_INTREGISTER;
+  hreg.number:=NR_NO;
 
   { we have to load the char before checking the length, because we }
   { may need registers from the reference                           }
@@ -123,7 +124,7 @@ begin
         { free the registers of right }
         reference_release(exprasmlist,right.location.reference);
         { get register for the char }
-        hreg := rg.makeregsize(rg.getregisterint(exprasmlist),OS_8);
+        hreg := rg.getregisterint(exprasmlist,OS_8);
         cg.a_load_ref_reg(exprasmlist,OS_8,right.location.reference,hreg);
         { I don't think a temp char exists, but it won't hurt (JM) }
         tg.ungetiftemp(exprasmlist,right.location.reference);
@@ -131,7 +132,7 @@ begin
     else hreg := right.location.register;
 
   { load the current string length }
-  lengthreg := rg.getregisterint(exprasmlist);
+  lengthreg := rg.getregisterint(exprasmlist,OS_INT);
   cg.a_load_ref_reg(exprasmlist,OS_8,left.location.reference,lengthreg);
 
   { do we have to check the length ? }
@@ -156,8 +157,8 @@ begin
   { we need a new reference to store the character }
   { at the end of the string. Check if the base or }
   { index register is still free                   }
-  if (href2.base.enum <> R_NO) and
-     (href2.index.enum <> R_NO) then
+  if (href2.base.number <> NR_NO) and
+     (href2.index.number <> NR_NO) then
     begin
       { they're not free, so add the base reg to       }
       { the string length (since the index can         }
@@ -167,7 +168,7 @@ begin
     end
   else
     { at least one is still free, so put EDI there }
-    if href2.base.enum = R_NO then
+    if href2.base.number = NR_NO then
       href2.base := lengthreg
     else
       begin
@@ -182,13 +183,14 @@ begin
       { no new_reference(href2) because it's only }
       { used once (JM)                            }
       cg.a_load_reg_ref(exprasmlist,OS_8,hreg,href2);
-      rg.ungetregister(exprasmlist,hreg);
+      rg.ungetregisterint(exprasmlist,hreg);
     end
   else
     cg.a_load_const_ref(exprasmlist,OS_8,tordconstnode(right).value,href2);
+  lengthreg.number:=(lengthreg.number and not $ff) or R_SUBL;
   { increase the string length }
-  cg.a_op_const_reg(exprasmlist,OP_ADD,1,rg.makeregsize(lengthreg,OS_8));
-  cg.a_load_reg_ref(exprasmlist,OS_8,rg.makeregsize(lengthreg,OS_8),left.location.reference);
+  cg.a_op_const_reg(exprasmlist,OP_ADD,1,lengthreg);
+  cg.a_load_reg_ref(exprasmlist,OS_8,lengthreg,left.location.reference);
   rg.ungetregisterint(exprasmlist,lengthreg);
   if checklength then
     cg.a_label(exprasmlist,l);
@@ -198,8 +200,8 @@ end;
 procedure ti386addsstringcsstringoptnode.pass_2;
 var
   href: treference;
-  pushedregs: tpushedsaved;
-  regstopush: tregisterset;
+  pushedregs: tpushedsavedint;
+  regstopush: tsupregset;
 begin
   { first, we have to more or less replicate some code from }
   { ti386addnode.pass_2                                     }
@@ -222,9 +224,9 @@ begin
   { push them (so the release is in the right place, }
   { because emitpushreferenceaddr doesn't need extra }
   { registers) (JM)                                  }
-  regstopush := all_registers;
+  regstopush := all_intregisters;
   remove_non_regvars_from_loc(right.location,regstopush);
-  rg.saveusedregisters(exprasmlist,pushedregs,regstopush);
+  rg.saveusedintregisters(exprasmlist,pushedregs,regstopush);
   { push the maximum possible length of the result }
   cg.a_paramaddr_ref(exprasmlist,left.location.reference,paramanager.getintparaloc(2));
   { the optimizer can more easily put the          }
@@ -233,11 +235,11 @@ begin
   { the pushref needs a "lea (..),edi; push edi")  }
   reference_release(exprasmlist,right.location.reference);
   cg.a_paramaddr_ref(exprasmlist,right.location.reference,paramanager.getintparaloc(1));
-  rg.saveregvars(exprasmlist,regstopush);
+  rg.saveintregvars(exprasmlist,regstopush);
   cg.a_call_name(exprasmlist,'FPC_SHORTSTR_CONCAT');
   tg.ungetiftemp(exprasmlist,right.location.reference);
   cg.g_maybe_loadself(exprasmlist);
-  rg.restoreusedregisters(exprasmlist,pushedregs);
+  rg.restoreusedintregisters(exprasmlist,pushedregs);
   location_copy(location,left.location);
 end;
 
@@ -248,7 +250,11 @@ end.
 
 {
   $Log$
-  Revision 1.27  2003-01-08 18:43:57  daniel
+  Revision 1.28  2003-02-19 22:00:15  daniel
+    * Code generator converted to new register notation
+    - Horribily outdated todo.txt removed
+
+  Revision 1.27  2003/01/08 18:43:57  daniel
    * Tregister changed into a record
 
   Revision 1.26  2002/11/25 17:43:27  peter

+ 28 - 20
compiler/i386/n386set.pas

@@ -223,9 +223,10 @@ implementation
              begin
                { for ranges we always need a 32bit register, because then we }
                { use the register as base in a reference (JM)                }
+               pleftreg.enum:=R_INTREGISTER;
                if ranges then
                  begin
-                   pleftreg:=rg.makeregsize(left.location.register,OS_INT);
+                   pleftreg.number:=(left.location.register.number and not $ff) or R_SUBWHOLE;
                    cg.a_load_reg_reg(exprasmlist,left.location.size,OS_INT,left.location.register,pleftreg);
                    if opsize <> S_L then
                      emit_const_reg(A_AND,S_L,255,pleftreg);
@@ -235,14 +236,14 @@ implementation
                  { otherwise simply use the lower 8 bits (no "and" }
                  { necessary this way) (JM)                        }
                  begin
-                   pleftreg:=rg.makeregsize(left.location.register,OS_8);
+                   pleftreg.number:=(left.location.register.number and not $ff) or R_SUBL;
                    opsize := S_B;
                  end;
              end
             else
              begin
                { load the value in a register }
-               pleftreg := rg.getexplicitregisterint(exprasmlist,R_EDI);
+               pleftreg := rg.getexplicitregisterint(exprasmlist,NR_EDI);
                opsize := S_L;
                emit_ref_reg(A_MOVZX,S_BL,left.location.reference,pleftreg);
              end;
@@ -282,7 +283,7 @@ implementation
                           r.enum:=R_INTREGISTER;
                           r.number:=NR_EDI;
                           rg.ungetregister(exprasmlist,pleftreg);
-                          rg.getexplicitregisterint(exprasmlist,R_EDI);
+                          rg.getexplicitregisterint(exprasmlist,NR_EDI);
                           reference_reset_base(href,pleftreg,-setparts[i].start);
                           emit_ref_reg(A_LEA,S_L,href,r);
                           { only now change pleftreg since previous value is }
@@ -346,12 +347,13 @@ implementation
              case left.location.loc of
                LOC_REGISTER,
                LOC_CREGISTER :
-                 rg.ungetregister(exprasmlist,pleftreg);
+                 rg.ungetregisterint(exprasmlist,pleftreg);
                else
                  begin
                    reference_release(exprasmlist,left.location.reference);
-                   r.enum:=R_EDI;
-                   rg.ungetregister(exprasmlist,r);
+                   r.enum:=R_INTREGISTER;
+                   r.number:=NR_EDI;
+                   rg.ungetregisterint(exprasmlist,r);
                  end;
              end;
           end
@@ -400,7 +402,7 @@ implementation
                       { but 8 bits are easier to load               }
                       r.enum:=R_INTREGISTER;
                       r.number:=NR_EDI;
-                      rg.getexplicitregisterint(exprasmlist,R_EDI);
+                      rg.getexplicitregisterint(exprasmlist,NR_EDI);
                       emit_ref_reg(A_MOVZX,S_BL,left.location.reference,r);
                       hr:=r;
                       location_release(exprasmlist,left.location);
@@ -419,7 +421,7 @@ implementation
                        begin
                        { We have to load the value into a register because
                          btl does not accept values only refs or regs (PFV) }
-                         hr2:=rg.getregisterint(exprasmlist);
+                         hr2:=rg.getregisterint(exprasmlist,OS_INT);
                          emit_const_reg(A_MOV,S_L,
                            right.location.value,hr2);
                          emit_reg_reg(A_BT,S_L,hr,hr2);
@@ -435,8 +437,6 @@ implementation
                        internalerror(2002032210);
                   end;
                   { simply to indicate EDI is deallocated here too (JM) }
-                  if (hr.enum=R_INTREGISTER) and (hr.number=NR_EDI) then
-                    hr.enum:=R_EDI;
                   rg.ungetregisterint(exprasmlist,hr);
                   location.loc:=LOC_FLAGS;
                   location.resflags:=F_C;
@@ -453,7 +453,7 @@ implementation
                   { Is this treated in firstpass ?? }
                   if left.nodetype=ordconstn then
                     begin
-                      hr:=rg.getregisterint(exprasmlist);
+                      hr:=rg.getregisterint(exprasmlist,OS_INT);
                       left.location.loc:=LOC_REGISTER;
                       left.location.register:=hr;
                       emit_const_reg(A_MOV,S_L,
@@ -473,7 +473,7 @@ implementation
                           cg.a_label(exprasmlist,l);
                         { We have to load the value into a register because
                           btl does not accept values only refs or regs (PFV) }
-                          hr2:=rg.getregisterint(exprasmlist);
+                          hr2:=rg.getregisterint(exprasmlist,OS_INT);
                           emit_const_reg(A_MOV,S_L,right.location.value,hr2);
                           emit_reg_reg(A_BT,S_L,hr,hr2);
                           rg.ungetregisterint(exprasmlist,hr2);
@@ -498,11 +498,11 @@ implementation
                        cg.a_jmp_always(exprasmlist,l2);
                        cg.a_label(exprasmlist,l);
                        location_release(exprasmlist,left.location);
-                       hr:=rg.getregisterint(exprasmlist);
+                       hr:=rg.getregisterint(exprasmlist,OS_INT);
                        emit_ref_reg(A_MOV,S_L,left.location.reference,hr);
                      { We have to load the value into a register because
                        btl does not accept values only refs or regs (PFV) }
-                       hr2:=rg.getregisterint(exprasmlist);
+                       hr2:=rg.getregisterint(exprasmlist,OS_INT);
                        emit_const_reg(A_MOV,S_L,
                          right.location.value,hr2);
                        emit_reg_reg(A_BT,S_L,hr,hr2);
@@ -523,21 +523,25 @@ implementation
                else
                 begin
                   if (left.location.loc in [LOC_REGISTER,LOC_CREGISTER]) then
-                    pleftreg:=rg.makeregsize(left.location.register,OS_INT)
+                    begin
+                      pleftreg.enum:=R_INTREGISTER;
+                      pleftreg.number:=(left.location.register.number and not $ff) or R_SUBWHOLE;
+                    end
                   else
-                    pleftreg:=rg.getexplicitregisterint(exprasmlist,R_EDI);
+                    pleftreg:=rg.getexplicitregisterint(exprasmlist,NR_EDI);
                   cg.a_load_loc_reg(exprasmlist,left.location,pleftreg);
                   location_freetemp(exprasmlist,left.location);
                   location_release(exprasmlist,left.location);
                   emit_reg_ref(A_BT,S_L,pleftreg,right.location.reference);
-                  rg.ungetregister(exprasmlist,pleftreg);
+                  rg.ungetregisterint(exprasmlist,pleftreg);
                   location_release(exprasmlist,right.location);
                   { tg.ungetiftemp(exprasmlist,right.location.reference) happens below }
                   location.resflags:=F_C;
                 end;
              end;
           end;
-          location_freetemp(exprasmlist,right.location);
+          if not genjumps then
+            location_freetemp(exprasmlist,right.location);
        end;
 
 
@@ -714,7 +718,11 @@ begin
 end.
 {
   $Log$
-  Revision 1.47  2003-01-13 14:54:34  daniel
+  Revision 1.48  2003-02-19 22:00:15  daniel
+    * Code generator converted to new register notation
+    - Horribily outdated todo.txt removed
+
+  Revision 1.47  2003/01/13 14:54:34  daniel
     * Further work to convert codegenerator register convention;
       internalerror bug fixed.
 

+ 10 - 2
compiler/i386/popt386.pas

@@ -1131,9 +1131,13 @@ Begin
                                           Taicpu(hp2).LoadRef(1,Taicpu(hp2).oper[0].ref^);
                                           Taicpu(hp2).LoadReg(0,Taicpu(p).oper[1].reg);
                                           allocRegBetween(asmL,Taicpu(p).oper[1].reg,p,hp2);
-                                          if (Taicpu(p).oper[0].ref^.base.enum in (rg.usableregsint+[R_EDI])) then
+{                                          if (Taicpu(p).oper[0].ref^.base.enum in (rg.usableregsint+[R_EDI])) then
                                             allocRegBetween(asmL,Taicpu(p).oper[0].ref^.base,p,hp2);
                                           if (Taicpu(p).oper[0].ref^.index.enum in (rg.usableregsint+[R_EDI])) then
+                                            allocRegBetween(asmL,Taicpu(p).oper[0].ref^.index,p,hp2);}
+                                          if (Taicpu(p).oper[0].ref^.base.enum in [R_ESI,R_EDI]) then
+                                            allocRegBetween(asmL,Taicpu(p).oper[0].ref^.base,p,hp2);
+                                          if (Taicpu(p).oper[0].ref^.index.enum in [R_ESI,R_EDI]) then
                                             allocRegBetween(asmL,Taicpu(p).oper[0].ref^.index,p,hp2);
                                         End
                                       Else
@@ -2050,7 +2054,11 @@ End.
 
 {
   $Log$
-  Revision 1.36  2003-01-08 18:43:57  daniel
+  Revision 1.37  2003-02-19 22:00:16  daniel
+    * Code generator converted to new register notation
+    - Horribily outdated todo.txt removed
+
+  Revision 1.36  2003/01/08 18:43:57  daniel
    * Tregister changed into a record
 
   Revision 1.35  2002/11/15 16:30:54  peter

+ 16 - 16
compiler/i386/ra386.pas

@@ -302,9 +302,6 @@ begin
    exit;
   if (OpOrder=op_intel) then
     SwapOperands;
-  if (operands[1].opr.typ=OPR_REGISTER) and
-      (operands[1].opr.reg.enum>lastreg) then
-    internalerror(200301081);
   case ops of
     0 : ;
     1 :
@@ -312,7 +309,10 @@ begin
       if ((opcode=A_PUSH) or
           (opcode=A_POP)) and
          (operands[1].opr.typ=OPR_REGISTER) and
-         (operands[1].opr.reg.enum in [firstsreg..lastsreg]) then
+         ((operands[1].opr.reg.enum in [firstsreg..lastsreg]) or
+          ((operands[1].opr.reg.enum=R_INTREGISTER) and
+           (operands[1].opr.reg.number>=nfirstsreg) and
+           (operands[1].opr.reg.number<=nlastsreg))) then
         opsize:=S_L
       else
         opsize:=operands[1].size;
@@ -368,15 +368,17 @@ begin
   end;
   { Handle the BW,BL,WL separatly }
   sizeerr:=false;
-  if (operands[1].opr.typ=OPR_REGISTER) and
-      (operands[1].opr.reg.enum>lastreg) then
-    internalerror(200301081);
   { special push/pop selector case }
   if ((opcode=A_PUSH) or
       (opcode=A_POP)) and
-     (operands[1].opr.typ=OPR_REGISTER) and
-     (operands[1].opr.reg.enum in [firstsreg..lastsreg]) then
+     (operands[1].opr.typ=OPR_REGISTER) then
+    begin
+      if (operands[1].opr.reg.enum in [firstsreg..lastsreg]) or
+         ((operands[1].opr.reg.enum=R_INTREGISTER) and
+          (operands[1].opr.reg.number>=nfirstsreg) and
+          (operands[1].opr.reg.number<=nlastsreg)) then
      exit;
+    end;
   if opsize in [S_BW,S_BL,S_WL] then
    begin
      if ops<>2 then
@@ -422,12 +424,6 @@ procedure T386Instruction.CheckNonCommutativeOpcodes;
 begin
   if (OpOrder=op_intel) then
     SwapOperands;
-  if (operands[1].opr.typ=OPR_REGISTER) and
-      (operands[1].opr.reg.enum>lastreg) then
-    internalerror(200301081);
-  if (operands[2].opr.typ=OPR_REGISTER) and
-      (operands[2].opr.reg.enum>lastreg) then
-    internalerror(200301081);
   if ((ops=2) and
      (operands[1].opr.typ=OPR_REGISTER) and
      (operands[2].opr.typ=OPR_REGISTER) and
@@ -684,7 +680,11 @@ end;
 end.
 {
   $Log$
-  Revision 1.28  2003-02-03 22:47:14  daniel
+  Revision 1.29  2003-02-19 22:00:16  daniel
+    * Code generator converted to new register notation
+    - Horribily outdated todo.txt removed
+
+  Revision 1.28  2003/02/03 22:47:14  daniel
     - Removed reg_2_opsize array
 
   Revision 1.27  2003/01/08 18:43:57  daniel

+ 32 - 19
compiler/i386/ra386att.pas

@@ -233,20 +233,30 @@ Begin
 end;
 
 
-Function is_register(const s: string):boolean;
-Var
-  i : Toldregister;
-Begin
-  actasmregister.enum:=R_NO;
-  for i:=firstreg to lastreg do
-   if s=iasmregs^[i] then
+function is_register(const s:string):boolean;
+
+var i:Toldregister;
+
+begin
+  actasmregister.enum:=R_INTREGISTER;
+  actasmregister.number:=gas_regnum_search(s);
+  if actasmregister.number=NR_NO then
+    begin
+      for i:=firstreg to lastreg do
+       if s=iasmregs^[i] then
+        begin
+          actasmtoken:=AS_REGISTER;
+          actasmregister.enum:=i;
+          is_register:=true;
+          exit;
+        end;
+      is_register:=false;
+    end
+  else
     begin
-      actasmtoken:=AS_REGISTER;
-      actasmregister.enum:=i;
       is_register:=true;
-      exit;
+      actasmtoken:=AS_REGISTER;
     end;
-  is_register:=false;
 end;
 
 
@@ -1168,10 +1178,9 @@ Begin
       Begin
         { Check if there is already a base (mostly ebp,esp) than this is
           not allowed,becuase it will give crashing code }
-        if opr.ref.base.enum>lastreg then
-          internalerror(200301081);
-        if opr.ref.base.enum<>R_NO then
-         Message(asmr_e_cannot_index_relative_var);
+        if not((opr.ref.base.enum=R_NO) or 
+               ((opr.ref.base.enum=R_INTREGISTER) and (opr.ref.base.number=NR_NO))) then
+          message(asmr_e_cannot_index_relative_var);
         opr.ref.base:=actasmregister;
         Consume(AS_REGISTER);
         { can either be a register or a right parenthesis }
@@ -1431,9 +1440,9 @@ Begin
          begin
            opr.typ:=OPR_REGISTER;
            opr.reg:=actasmregister;
-           if opr.reg.enum>lastreg then
-             internalerror(200301081);
-           size:=reg2opsize[actasmregister.enum];
+           if opr.reg.enum<>R_INTREGISTER then
+             internalerror(200302023);
+           size:=subreg2opsize[actasmregister.number and $ff];
            Consume(AS_REGISTER);
          end
         else
@@ -2126,7 +2135,11 @@ finalization
 end.
 {
   $Log$
-  Revision 1.37  2003-02-03 22:47:14  daniel
+  Revision 1.38  2003-02-19 22:00:16  daniel
+    * Code generator converted to new register notation
+    - Horribily outdated todo.txt removed
+
+  Revision 1.37  2003/02/03 22:47:14  daniel
     - Removed reg_2_opsize array
 
   Revision 1.36  2003/01/08 18:43:57  daniel

+ 51 - 31
compiler/i386/ra386int.pas

@@ -48,7 +48,7 @@ Implementation
        nbas,
        { parser }
        scanner,
-       rautils,ra386,
+       rautils,ra386,ag386int,
        { codegen }
        cgbase
        ;
@@ -221,21 +221,30 @@ Begin
   is_asmdirective:=false;
 end;
 
+function is_register(const s:string):boolean;
 
-Function is_register(const s: string):boolean;
-Var
-  i : tregister;
-Begin
-  actasmregister.enum:=R_NO;
-  for i.enum:=firstreg to lastreg do
-   if s=iasmregs^[i.enum] then
+var i:Toldregister;
+
+begin
+  actasmregister.enum:=R_INTREGISTER;
+  actasmregister.number:=intel_regnum_search(s);
+  if actasmregister.number=NR_NO then
+    begin
+      for i:=firstreg to lastreg do
+       if s=iasmregs^[i] then
+        begin
+          actasmtoken:=AS_REGISTER;
+          actasmregister.enum:=i;
+          is_register:=true;
+          exit;
+        end;
+      is_register:=false;
+    end
+  else
     begin
-      actasmtoken:=AS_REGISTER;
-      actasmregister:=i;
       is_register:=true;
-      exit;
+      actasmtoken:=AS_REGISTER;
     end;
-  is_register:=false;
 end;
 
 
@@ -1071,7 +1080,8 @@ Begin
              if negative then
                Message(asmr_e_only_add_relocatable_symbol);
              oldbase:=opr.ref.base;
-             opr.ref.base.enum:=R_NO;
+             opr.ref.base.enum:=R_INTREGISTER;
+             opr.ref.base.number:=NR_NO;
              tempstr:=actasmpattern;
              Consume(AS_ID);
              { typecasting? }
@@ -1097,11 +1107,12 @@ Begin
               end;
              if GotOffset then
               begin
-                if procinfo.framepointer.enum>lastreg then
-                  internalerror(200301081);
+                if procinfo.framepointer.enum<>R_INTREGISTER then
+                  internalerror(200302121);
                 if hasvar and (opr.ref.base.enum=procinfo.framepointer.enum) then
                  begin
-                   opr.ref.base.enum:=R_NO;
+                   opr.ref.base.enum:=R_INTREGISTER;
+                   opr.ref.base.number:=NR_NO;
                    hasvar:=hadvar;
                  end
                 else
@@ -1111,19 +1122,19 @@ Begin
                    { should we allow ?? }
                  end;
               end;
-             if opr.ref.base.enum>lastreg then
-               internalerror(200301081);
-             if opr.ref.index.enum>lastreg then
-               internalerror(200301081);
+             if opr.ref.base.enum<>R_INTREGISTER then
+               internalerror(200302121);
+             if opr.ref.index.enum<>R_INTREGISTER then
+               internalerror(200302121);
              { is the base register loaded by the var ? }
-             if (opr.ref.base.enum<>R_NO) then
+             if (opr.ref.base.number<>NR_NO) then
               begin
                 { check if we can move the old base to the index register }
-                if (opr.ref.index.enum<>R_NO) then
+                if (opr.ref.index.number<>NR_NO) then
                  Message(asmr_e_wrong_base_index)
                 else if assigned(procinfo._class) and
-                  (oldbase.enum=SELF_POINTER_REG) and
-                  (opr.ref.base.enum=SELF_POINTER_REG) then
+                  (oldbase.number=NR_SELF_POINTER_REG) and
+                  (opr.ref.base.number=NR_SELF_POINTER_REG) then
                   begin
                     Message(asmr_w_possible_object_field_bug);
                     { warn but accept... who knows what people
@@ -1214,11 +1225,15 @@ Begin
              1. just read a *
              2. next token is a *
              3. base register is already used }
+          if opr.ref.base.enum<>R_INTREGISTER then
+            internalerror(200302123);
+          if opr.ref.index.enum<>R_INTREGISTER then
+            internalerror(200302123);
           if (GotStar) or
              (actasmtoken=AS_STAR) or
-             (opr.ref.base.enum<>R_NO) then
+             (opr.ref.base.number<>NR_NO) then
            begin
-             if (opr.ref.index.enum<>R_NO) then
+             if (opr.ref.index.number<>NR_NO) then
               Message(asmr_e_multiple_index);
              opr.ref.index:=hreg;
              if scale<>0 then
@@ -1548,7 +1563,7 @@ Begin
       end;
 
     AS_REGISTER : { Register, a variable reference or a constant reference }
-      Begin
+      begin
         { save the type of register used. }
         tempreg:=actasmregister;
         Consume(AS_REGISTER);
@@ -1566,9 +1581,10 @@ Begin
             Message(asmr_e_invalid_operand_type);
            opr.typ:=OPR_REGISTER;
            opr.reg:=tempreg;
-           if opr.reg.enum>lastreg then
-             internalerror(200301081);
-           size:=reg2opsize[opr.reg.enum];
+           if opr.reg.enum=R_INTREGISTER then
+              size:=subreg2opsize[opr.reg.number and $ff]
+           else
+              size:=reg2opsize[opr.reg.enum];
          end;
       end;
 
@@ -1964,7 +1980,11 @@ finalization
 end.
 {
   $Log$
-  Revision 1.39  2003-01-08 18:43:57  daniel
+  Revision 1.40  2003-02-19 22:00:16  daniel
+    * Code generator converted to new register notation
+    - Horribily outdated todo.txt removed
+
+  Revision 1.39  2003/01/08 18:43:57  daniel
    * Tregister changed into a record
 
   Revision 1.38  2002/12/14 15:02:03  carl

+ 266 - 184
compiler/i386/rgcpu.pas

@@ -36,12 +36,12 @@ unit rgcpu;
 
     type
        trgcpu = class(trgobj)
-         fpuvaroffset : byte;
+          fpuvaroffset : byte;
 
           { to keep the same allocation order as with the old routines }
-          function getregisterint(list: taasmoutput): tregister; override;
-          procedure ungetregisterint(list: taasmoutput; r : tregister); override;
-          function getexplicitregisterint(list: taasmoutput; r : Toldregister) : tregister; override;
+          function getregisterint(list:Taasmoutput;size:Tcgsize):Tregister;override;
+          procedure ungetregisterint(list:Taasmoutput;r:Tregister); override;
+          function getexplicitregisterint(list:Taasmoutput;r:Tnewregister):Tregister;override;
 
           function getregisterfpu(list: taasmoutput) : tregister; override;
           procedure ungetregisterfpu(list: taasmoutput; r : tregister); override;
@@ -56,15 +56,28 @@ unit rgcpu;
           function makeregsize(reg: tregister; size: tcgsize): tregister; override;
 
           { pushes and restores registers }
-          procedure pushusedregisters(list: taasmoutput;
-            var pushed : tpushedsaved;const s: tregisterset);
-          procedure popusedregisters(list: taasmoutput;
-            const pushed : tpushedsaved);
-
-          procedure saveusedregisters(list: taasmoutput;
-            var saved : tpushedsaved;const s: tregisterset);override;
-          procedure restoreusedregisters(list: taasmoutput;
-            const saved : tpushedsaved);override;
+          procedure pushusedintregisters(list:Taasmoutput;
+                                         var pushed:Tpushedsavedint;
+                                         const s:Tsupregset);
+          procedure pushusedotherregisters(list:Taasmoutput;
+                                           var pushed:Tpushedsaved;
+                                           const s:Tregisterset);
+
+          procedure popusedintregisters(list:Taasmoutput;
+                                        const pushed:Tpushedsavedint);
+          procedure popusedotherregisters(list:Taasmoutput;
+                                          const pushed:Tpushedsaved);
+
+          procedure saveusedintregisters(list:Taasmoutput;
+                                         var saved:Tpushedsavedint;
+                                         const s:Tsupregset);override;
+          procedure saveusedotherregisters(list:Taasmoutput;
+                                           var saved:Tpushedsaved;
+                                           const s:Tregisterset);override;
+          procedure restoreusedintregisters(list:Taasmoutput;
+                                            const saved:Tpushedsavedint);override;
+          procedure restoreusedotherregisters(list:Taasmoutput;
+                                              const saved:Tpushedsaved);override;
 
           procedure resetusableregisters;override;
 
@@ -147,98 +160,118 @@ unit rgcpu;
 {                               trgcpu                                   }
 {************************************************************************}
 
-    function trgcpu.getregisterint(list: taasmoutput): tregister;
+    function trgcpu.getregisterint(list:Taasmoutput;size:Tcgsize):Tregister;
 
-      begin
-         if countunusedregsint=0 then
-           internalerror(10);
+    var subreg:Tsubregister;
+
+    begin
+      case size of
+        OS_8,OS_S8:
+          subreg:=R_SUBL;
+        OS_16,OS_S16:
+          subreg:=R_SUBW;
+        OS_32,OS_S32:
+          subreg:=R_SUBD;
+        OS_64,OS_S64:
+          subreg:=R_SUBQ;
+        else
+          internalerror(200301102);
+      end;
+          
+      if countunusedregsint=0 then
+        internalerror(10);
+      getregisterint.enum:=R_INTREGISTER;
 {$ifdef TEMPREGDEBUG}
-         if curptree^.usableregsint-countunusedregsint>curptree^.registers32 then
-           internalerror(10);
+      if curptree^.usableregsint-countunusedregsint>curptree^.registers32 then
+        internalerror(10);
 {$endif TEMPREGDEBUG}
 {$ifdef EXTTEMPREGDEBUG}
-         if curptree^.usableregs-countunusedregistersint>curptree^^.reallyusedregs then
-           curptree^.reallyusedregs:=curptree^^.usableregs-countunusedregistersint;
+      if curptree^.usableregs-countunusedregistersint>curptree^^.reallyusedregs then
+        curptree^.reallyusedregs:=curptree^^.usableregs-countunusedregistersint;
 {$endif EXTTEMPREGDEBUG}
-         dec(countunusedregsint);
-         if R_EAX in unusedregsint then
-           begin
-              exclude(unusedregsint,R_EAX);
-              include(usedinproc,R_EAX);
-              getregisterint.enum:=R_EAX;
+      dec(countunusedregsint);
+      if RS_EAX in unusedregsint then
+        begin
+          exclude(unusedregsint,RS_EAX);
+          include(usedintinproc,RS_EAX);
+          getregisterint.number:=RS_EAX shl 8 or subreg;
 {$ifdef TEMPREGDEBUG}
-              reg_user[R_EAX]:=curptree^;
+          reg_user[R_EAX]:=curptree^;
 {$endif TEMPREGDEBUG}
-              exprasmlist.concat(tai_regalloc.alloc(getregisterint));
-           end
-         else if R_EDX in unusedregsint then
-           begin
-              exclude(unusedregsint,R_EDX);
-              include(usedinproc,R_EDX);
-              getregisterint.enum:=R_EDX;
+          exprasmlist.concat(tai_regalloc.alloc(getregisterint));
+        end
+      else if RS_EDX in unusedregsint then
+        begin
+          exclude(unusedregsint,RS_EDX);
+          include(usedintinproc,RS_EDX);
+          getregisterint.number:=RS_EDX shl 8 or subreg;
 {$ifdef TEMPREGDEBUG}
-              reg_user[R_EDX]:=curptree^;
+          reg_user[R_EDX]:=curptree^;
 {$endif TEMPREGDEBUG}
-              exprasmlist.concat(tai_regalloc.alloc(getregisterint));
-           end
-         else if R_EBX in unusedregsint then
-           begin
-              exclude(unusedregsint,R_EBX);
-              include(usedinproc,R_EBX);
-              getregisterint.enum:=R_EBX;
+          exprasmlist.concat(tai_regalloc.alloc(getregisterint));
+        end
+      else if RS_EBX in unusedregsint then
+        begin
+          exclude(unusedregsint,RS_EBX);
+          include(usedintinproc,RS_EBX);
+          getregisterint.number:=RS_EBX shl 8 or subreg;
 {$ifdef TEMPREGDEBUG}
-              reg_user[R_EBX]:=curptree^;
+          reg_user[R_EBX]:=curptree^;
 {$endif TEMPREGDEBUG}
-              exprasmlist.concat(tai_regalloc.alloc(getregisterint));
-           end
-         else if R_ECX in unusedregsint then
-           begin
-              exclude(unusedregsint,R_ECX);
-              include(usedinproc,R_ECX);
-              getregisterint.enum:=R_ECX;
+          exprasmlist.concat(tai_regalloc.alloc(getregisterint));
+        end
+      else if RS_ECX in unusedregsint then
+        begin
+          exclude(unusedregsint,RS_ECX);
+          include(usedintinproc,RS_ECX);
+          getregisterint.number:=RS_ECX shl 8 or subreg;
 {$ifdef TEMPREGDEBUG}
-              reg_user[R_ECX]:=curptree^;
+          reg_user[R_ECX]:=curptree^;
 {$endif TEMPREGDEBUG}
-              exprasmlist.concat(tai_regalloc.alloc(getregisterint));
-           end
-         else internalerror(10);
+          exprasmlist.concat(tai_regalloc.alloc(getregisterint));
+        end
+      else internalerror(10);
 {$ifdef TEMPREGDEBUG}
-         testregisters;
+      testregisters;
 {$endif TEMPREGDEBUG}
-      end;
+    end;
 
     procedure trgcpu.ungetregisterint(list: taasmoutput; r : tregister);
+    
+    var supreg:Tsuperregister;
+    
       begin
          if r.enum=R_NO then
           exit;
-         r := makeregsize(r,OS_INT);
-         if r.enum>lastreg then
-            internalerror(200301081);
-         if (r.enum = R_EDI) or
-            ((not assigned(procinfo._class)) and (r.enum = R_ESI)) then
+         if r.enum<>R_INTREGISTER then
+            internalerror(200301234);
+         supreg:=r.number shr 8;
+         if (supreg = RS_EDI) or
+            ((not assigned(procinfo._class)) and (supreg = RS_ESI)) then
            begin
              list.concat(tai_regalloc.DeAlloc(r));
              exit;
            end;
-         if not(r.enum in [R_EAX,R_EBX,R_ECX,R_EDX]) then
+         if not(supreg in [RS_EAX,RS_EBX,RS_ECX,RS_EDX]) then
            exit;
          inherited ungetregisterint(list,r);
       end;
 
 
-   function trgcpu.getexplicitregisterint(list: taasmoutput; r : Toldregister) : tregister;
+   function trgcpu.getexplicitregisterint(list:Taasmoutput;r:Tnewregister):Tregister;
 
    var r2:Tregister;
 
-     begin
-       if r in [R_ESI,R_EDI] then
-         begin
-           r2.enum:=r;
-           list.concat(tai_regalloc.Alloc(r2));
-           getexplicitregisterint := r2;
-           exit;
-         end;
-       result := inherited getexplicitregisterint(list,r);
+    begin
+      if (r shr 8) in [RS_ESI,RS_EDI] then
+        begin
+          r2.enum:=R_INTREGISTER;
+          r2.number:=r;
+          list.concat(Tai_regalloc.alloc(r2));
+          getexplicitregisterint:=r2;
+          exit;
+        end;
+      result:=inherited getexplicitregisterint(list,r);
     end;
 
 
@@ -267,134 +300,179 @@ unit rgcpu;
       end;
 
 
-    procedure trgcpu.pushusedregisters(list: taasmoutput;
-        var pushed : tpushedsaved; const s: tregisterset);
+    procedure trgcpu.pushusedintregisters(list:Taasmoutput;
+                                         var pushed:Tpushedsavedint;
+                                         const s:Tsupregset);
+
+    var r:Tsuperregister;
+        r2:Tregister;
+    
+    begin
+      usedintinproc:=usedintinproc+s;
+      for r:=RS_EAX to RS_EDX do
+        begin
+          r2.enum:=R_INTREGISTER;
+          r2.number:=r shl 8 or R_SUBWHOLE;
+          pushed[r].pushed:=false;
+          { if the register is used by the calling subroutine    }
+          if not(r in is_reg_var_int) and (r in s) and
+             { and is present in use }
+             not(r in unusedregsint) then
+            begin
+              { then save it }
+              list.concat(Taicpu.Op_reg(A_PUSH,S_L,r2));
+              include(unusedregsint,r);
+              inc(countunusedregsint);
+              pushed[r].pushed:=true;
+            end;
+        end;
+{$ifdef TEMPREGDEBUG}
+      testregisters;
+{$endif TEMPREGDEBUG}
+    end;
 
-      var
-        r: Toldregister;
-        r2: Tregister;
 {$ifdef SUPPORT_MMX}
-        hr : treference;
+    procedure trgcpu.pushusedotherregisters(list:Taasmoutput;
+                                            var pushed:Tpushedsaved;
+                                            const s:Tregisterset);
+
+    var r:Toldregister;
+        r2:Tregister;
+        hr:Treference;
+    
+    begin
+      usedinproc:=usedinproc+s;
+      for r:=R_MM0 to R_MM6 do
+        begin
+          pushed[r].pushed:=false;
+          { if the register is used by the calling subroutine    }
+          if not is_reg_var[r] and
+             (r in s) and
+             { and is present in use }
+             not(r in unusedregsmm) then
+            begin
+              r2.enum:=R_ESP;
+              list.concat(Taicpu.Op_const_reg(A_SUB,S_L,8,r2));
+              reference_reset_base(hr,r2,0);
+              r2.enum:=r;
+              list.concat(Taicpu.Op_reg_ref(A_MOVQ,S_NO,r2,hr));
+              include(unusedregsmm,r);
+              inc(countunusedregsmm);
+              pushed[r].pushed:=true;
+            end;
+        end;
+{$ifdef TEMPREGDEBUG}
+      testregisters;
+{$endif TEMPREGDEBUG}
+    end;
 {$endif SUPPORT_MMX}
-      begin
-        usedinproc:=usedinproc + s;
-        for r:=R_EAX to R_EBX do
+
+    procedure trgcpu.popusedintregisters(list:Taasmoutput;
+                                         const pushed:Tpushedsavedint);
+
+    var r:Tsuperregister;
+        r2:Tregister;
+    begin
+      { restore in reverse order: }
+      for r:=RS_EDX downto RS_EAX do
+        if pushed[r].pushed then
           begin
-            r2.enum:=r;
-            pushed[r].pushed:=false;
-            { if the register is used by the calling subroutine    }
-            if not is_reg_var[r] and
-               (r in s) and
-               { and is present in use }
-               not(r in unusedregsint) then
-              begin
-                { then save it }
-                list.concat(Taicpu.Op_reg(A_PUSH,S_L,r2));
-                include(unusedregsint,r);
-                inc(countunusedregsint);
-                pushed[r].pushed:=true;
-              end;
+            r2.enum:=R_INTREGISTER;
+            r2.number:=r shl 8 or R_SUBWHOLE;
+            list.concat(Taicpu.op_reg(A_POP,S_L,r2));
+            if not (r in unusedregsint) then
+              { internalerror(10)
+                in cg386cal we always restore regs
+                that appear as used
+                due to a unused tmep storage PM }
+            else
+              dec(countunusedregsint);
+            exclude(unusedregsint,r);
           end;
+{$ifdef TEMPREGDEBUG}
+      testregisters;
+{$endif TEMPREGDEBUG}
+    end;
+
 {$ifdef SUPPORT_MMX}
-        for r:=R_MM0 to R_MM6 do
+    procedure trgcpu.popusedotherregisters(list:Taasmoutput;
+                                           const pushed:Tpushedsaved);
+
+    var r:Toldregister;
+        r2,r3:Tregister;
+        hr:Treference;
+
+    begin
+      { restore in reverse order: }
+      for r:=R_MM6 downto R_MM0 do
+        if pushed[r].pushed then
           begin
-            pushed[r].pushed:=false;
-            { if the register is used by the calling subroutine    }
-            if not is_reg_var[r] and
-               (r in s) and
-               { and is present in use }
-               not(r in unusedregsmm) then
-              begin
-                r2.enum:=R_ESP;
-                list.concat(Taicpu.Op_const_reg(A_SUB,S_L,8,r2));
-                reference_reset_base(hr,r2,0);
-                r2.enum:=r;
-                list.concat(Taicpu.Op_reg_ref(A_MOVQ,S_NO,r2,hr));
-                include(unusedregsmm,r);
-                inc(countunusedregsmm);
-                pushed[r].pushed:=true;
-              end;
+            r2.enum:=R_ESP;
+            reference_reset_base(hr,r2,0);
+            r3.enum:=r;
+            list.concat(Taicpu.op_ref_reg(A_MOVQ,S_NO,hr,r3));
+            list.concat(Taicpu.op_const_reg(A_ADD,S_L,8,r2));
+            if not (r in unusedregsmm) then
+              { internalerror(10)
+                in cg386cal we always restore regs
+                that appear as used
+                due to a unused tmep storage PM }
+            else
+              dec(countunusedregsmm);
+            exclude(unusedregsmm,r);
           end;
-{$endif SUPPORT_MMX}
 {$ifdef TEMPREGDEBUG}
-        testregisters;
+      testregisters;
 {$endif TEMPREGDEBUG}
-      end;
+    end;
+{$endif SUPPORT_MMX}
 
+    procedure trgcpu.saveusedintregisters(list:Taasmoutput;
+                                          var saved:Tpushedsavedint;
+                                          const s:Tsupregset);
 
-    procedure trgcpu.popusedregisters(list: taasmoutput;
-        const pushed : tpushedsaved);
+    begin
+      if (aktoptprocessor in [class386,classP5]) or
+         (CS_LittleSize in aktglobalswitches) then
+        pushusedintregisters(list,saved,s)
+      else
+        inherited saveusedintregisters(list,saved,s);
+    end;
 
-      var
-        r : Toldregister;
-        r2,r3 : Tregister;
-{$ifdef SUPPORT_MMX}
-        hr : treference;
-{$endif SUPPORT_MMX}
-      begin
-        { restore in reverse order: }
-{$ifdef SUPPORT_MMX}
-        for r:=R_MM6 downto R_MM0 do
-          if pushed[r].pushed then
-            begin
-              r2.enum:=R_ESP;
-              reference_reset_base(hr,r2,0);
-              r3.enum:=r;
-              list.concat(Taicpu.Op_ref_reg(
-                A_MOVQ,S_NO,hr,r3));
-              list.concat(Taicpu.Op_const_reg(
-                A_ADD,S_L,8,r2));
-              if not (r in unusedregsmm) then
-                { internalerror(10)
-                  in cg386cal we always restore regs
-                  that appear as used
-                  due to a unused tmep storage PM }
-              else
-                dec(countunusedregsmm);
-              exclude(unusedregsmm,r);
-            end;
-{$endif SUPPORT_MMX}
-        for r:=R_EBX downto R_EAX do
-          if pushed[r].pushed then
-            begin
-              r2.enum:=r;
-              list.concat(Taicpu.Op_reg(A_POP,S_L,r2));
-              if not (r in unusedregsint) then
-                { internalerror(10)
-                  in cg386cal we always restore regs
-                  that appear as used
-                  due to a unused tmep storage PM }
-              else
-                dec(countunusedregsint);
-              exclude(unusedregsint,r);
-            end;
-{$ifdef TEMPREGDEBUG}
-        testregisters;
-{$endif TEMPREGDEBUG}
-      end;
 
-    procedure trgcpu.saveusedregisters(list: taasmoutput;var saved : tpushedsaved;
-      const s: tregisterset);
+    procedure trgcpu.saveusedotherregisters(list:Taasmoutput;var saved:Tpushedsaved;
+                                            const s:tregisterset);
 
-      begin
-        if (aktoptprocessor in [class386,classP5]) or
-           (CS_LittleSize in aktglobalswitches) then
-          pushusedregisters(list,saved,s)
-        else
-          inherited saveusedregisters(list,saved,s);
-      end;
+    begin
+      if (aktoptprocessor in [class386,classP5]) or
+         (CS_LittleSize in aktglobalswitches) then
+        pushusedotherregisters(list,saved,s)
+      else
+        inherited saveusedotherregisters(list,saved,s);
+    end;
 
 
-    procedure trgcpu.restoreusedregisters(list: taasmoutput;
-      const saved : tpushedsaved);
+    procedure trgcpu.restoreusedintregisters(list:Taasmoutput;
+                                             const saved:tpushedsavedint);
 
-      begin
-        if (aktoptprocessor in [class386,classP5]) or
-           (CS_LittleSize in aktglobalswitches) then
-          popusedregisters(list,saved)
-        else
-          inherited restoreusedregisters(list,saved);
-      end;
+    begin
+      if (aktoptprocessor in [class386,classP5]) or
+         (CS_LittleSize in aktglobalswitches) then
+        popusedintregisters(list,saved)
+      else
+        inherited restoreusedintregisters(list,saved);
+    end;
+
+    procedure trgcpu.restoreusedotherregisters(list:Taasmoutput;
+                                               const saved:tpushedsaved);
+
+    begin
+      if (aktoptprocessor in [class386,classP5]) or
+         (CS_LittleSize in aktglobalswitches) then
+        popusedotherregisters(list,saved)
+      else
+        inherited restoreusedotherregisters(list,saved);
+    end;
 
 
    procedure trgcpu.resetusableregisters;
@@ -444,7 +522,11 @@ end.
 
 {
   $Log$
-  Revision 1.11  2003-01-08 18:43:57  daniel
+  Revision 1.12  2003-02-19 22:00:16  daniel
+    * Code generator converted to new register notation
+    - Horribily outdated todo.txt removed
+
+  Revision 1.11  2003/01/08 18:43:57  daniel
    * Tregister changed into a record
 
   Revision 1.10  2002/10/05 12:43:29  carl

+ 9 - 3
compiler/i386/rropt386.pas

@@ -331,8 +331,10 @@ begin
                      (Taicpu(p).oper[0].typ = top_reg) and
                      (Taicpu(p).oper[1].typ = top_reg) and
                      (Taicpu(p).opsize = S_L) and
-                     (Taicpu(p).oper[0].reg.enum in (rg.usableregsint+[R_EDI])) and
-                     (Taicpu(p).oper[1].reg.enum in (rg.usableregsint+[R_EDI])) then
+{                     (Taicpu(p).oper[0].reg.enum in (rg.usableregsint+[R_EDI])) and
+                     (Taicpu(p).oper[1].reg.enum in (rg.usableregsint+[R_EDI])) then}
+                     (Taicpu(p).oper[0].reg.enum in ([R_ESI,R_EDI])) and
+                     (Taicpu(p).oper[1].reg.enum in ([R_ESI,R_EDI])) then
                     if switchRegs(asml,Taicpu(p).oper[0].reg,
                          Taicpu(p).oper[1].reg,p) then
                       begin
@@ -356,7 +358,11 @@ End.
 
 {
   $Log$
-  Revision 1.19  2003-01-08 18:43:57  daniel
+  Revision 1.20  2003-02-19 22:00:16  daniel
+    * Code generator converted to new register notation
+    - Horribily outdated todo.txt removed
+
+  Revision 1.19  2003/01/08 18:43:57  daniel
    * Tregister changed into a record
 
   Revision 1.18  2002/07/01 18:46:34  peter

+ 15 - 11
compiler/m68k/aasmcpu.pas

@@ -60,11 +60,11 @@ type
      constructor op_reg_reg_ref(op : tasmop;_size : topsize;_op1,_op2 : tregister; _op3 : treference);
      constructor op_const_reg_ref(op : tasmop;_size : topsize;_op1 : longint;_op2 : tregister;_op3 : treference);
 
-     constructor op_reg_reglist(op: tasmop; _size : topsize; _op1: tregister;_op2: tregisterlist);
-     constructor op_reglist_reg(op: tasmop; _size : topsize; _op1: tregisterlist; _op2: tregister);
+     constructor op_reg_reglist(op: tasmop; _size : topsize; _op1: tregister;_op2: Tsupregset);
+     constructor op_reglist_reg(op: tasmop; _size : topsize; _op1: Tsupregset; _op2: tregister);
 
-     constructor op_ref_reglist(op: tasmop; _size : topsize; _op1: treference;_op2: tregisterlist);
-     constructor op_reglist_ref(op: tasmop; _size : topsize; _op1: tregisterlist; _op2: treference);
+     constructor op_ref_reglist(op: tasmop; _size : topsize; _op1: treference;_op2: Tsupregset);
+     constructor op_reglist_ref(op: tasmop; _size : topsize; _op1: Tsupregset; _op2: treference);
 
      { this is for Jmp instructions }
      constructor op_cond_sym(op : tasmop;cond:TAsmCond;_size : topsize;_op1 : tasmsymbol);
@@ -78,7 +78,7 @@ type
      constructor op_sym_ofs_ref(op : tasmop;_size : topsize;_op1 : tasmsymbol;_op1ofs:longint;const _op2 : treference);
 
   private
-     procedure loadreglist(opidx:longint;r:tregisterlist);
+     procedure loadreglist(opidx:longint;r:Tsupregset);
      procedure init(_size : topsize); { this need to be called by all constructor }
   end;
 
@@ -100,7 +100,7 @@ implementation
 
 
 
-   procedure taicpu.loadreglist(opidx:longint;r:tregisterlist);
+   procedure taicpu.loadreglist(opidx:longint;r:Tsupregset);
       begin
         if opidx>=ops then
          ops:=opidx+1;
@@ -288,7 +288,7 @@ implementation
       end;
 
 
-   constructor taicpu.op_ref_reglist(op: tasmop; _size : topsize; _op1: treference;_op2: tregisterlist);
+   constructor taicpu.op_ref_reglist(op: tasmop; _size : topsize; _op1: treference;_op2: Tsupregset);
      Begin
         inherited create(op);;
         init(_size);
@@ -297,7 +297,7 @@ implementation
         loadreglist(1,_op2);
      end;
 
-   constructor taicpu.op_reglist_ref(op: tasmop; _size : topsize; _op1: tregisterlist; _op2: treference);
+   constructor taicpu.op_reglist_ref(op: tasmop; _size : topsize; _op1: Tsupregset; _op2: treference);
      Begin
         inherited create(op);;
         init(_size);
@@ -308,7 +308,7 @@ implementation
 
 
 
-   constructor taicpu.op_reg_reglist(op: tasmop; _size : topsize; _op1: tregister;_op2: tregisterlist);
+   constructor taicpu.op_reg_reglist(op: tasmop; _size : topsize; _op1: tregister;_op2: Tsupregset);
      Begin
         inherited create(op);;
         init(_size);
@@ -318,7 +318,7 @@ implementation
      end;
 
 
-   constructor taicpu.op_reglist_reg(op: tasmop; _size : topsize; _op1: tregisterlist; _op2: tregister);
+   constructor taicpu.op_reglist_reg(op: tasmop; _size : topsize; _op1: Tsupregset; _op2: tregister);
      Begin
         inherited create(op);;
         init(_size);
@@ -409,7 +409,11 @@ implementation
 end.
 {
   $Log$
-  Revision 1.7  2002-12-14 15:02:03  carl
+  Revision 1.8  2003-02-19 22:00:16  daniel
+    * Code generator converted to new register notation
+    - Horribily outdated todo.txt removed
+
+  Revision 1.7  2002/12/14 15:02:03  carl
     * maxoperands -> max_operands (for portability in rautils.pas)
     * fix some range-check errors with loadconst
     + add ncgadd unit to m68k

+ 9 - 5
compiler/m68k/agcpugas.pas

@@ -178,17 +178,17 @@ interface
     function getopstr(const o:toper) : string;
     var
       hs : string;
-      i : tregister;
+      i:Tsuperregister;
     begin
       case o.typ of
             top_reg : getopstr:=gas_reg2str[o.reg.enum];
             top_ref : getopstr:=getreferencestring(o.ref^);
         top_reglist : begin
                       hs:='';
-                      for i.enum:=R_NO to R_FPSR do
+                      for i:=first_supreg to last_supreg do
                       begin
-                        if i.enum in o.registerlist then
-                         hs:=hs+gas_reg2str[i.enum]+'/';
+                        if i in o.registerlist then
+                         hs:=hs+supreg_name(i)+'/';
                       end;
                       delete(hs,length(hs),1);
                       getopstr := hs;
@@ -417,7 +417,11 @@ initialization
 end.
 {
   $Log$
-  Revision 1.6  2003-02-15 22:19:40  carl
+  Revision 1.7  2003-02-19 22:00:16  daniel
+    * Code generator converted to new register notation
+    - Horribily outdated todo.txt removed
+
+  Revision 1.6  2003/02/15 22:19:40  carl
    * bugfix of emissions of jmp instructions
 
   Revision 1.5  2003/01/08 18:43:57  daniel

+ 98 - 87
compiler/m68k/cgcpu.pas

@@ -65,13 +65,13 @@ unit cgcpu;
           procedure g_stackframe_entry(list : taasmoutput;localsize : longint);override;
           procedure g_restore_frame_pointer(list : taasmoutput);override;
           procedure g_return_from_proc(list : taasmoutput;parasize : aword);override;
-          procedure g_save_standard_registers(list : taasmoutput; usedinproc : tregisterset);override;
-          procedure g_restore_standard_registers(list : taasmoutput; usedinproc : tregisterset);override;
+          procedure g_save_standard_registers(list:Taasmoutput;usedinproc:Tsupregset);override;
+          procedure g_restore_standard_registers(list:Taasmoutput;usedinproc:Tsupregset);override;
           procedure g_save_all_registers(list : taasmoutput);override;
           procedure g_restore_all_registers(list : taasmoutput;selfused,accused,acchiused:boolean);override;
           { for address register allocation }
           function get_scratch_reg_address(list : taasmoutput) : tregister;override;
-          function get_scratch_reg_int(list : taasmoutput) : tregister; override;
+          function get_scratch_reg_int(list:Taasmoutput;size:Tcgsize):Tregister; override;
 
 
      protected
@@ -172,54 +172,51 @@ Implementation
            end;
       end;
 
-    function tcg68k.get_scratch_reg_int(list : taasmoutput) : tregister;
+    function tcg68k.get_scratch_reg_int(list:Taasmoutput;size:Tcgsize):Tregister;
 
-      var
-         r : tregister;
-         i : longint;
+    var r:Tregister;
+        rs:Tsuperregister;
+        i:longint;
 
       begin
          if unusedscratchregisters=[] then
            internalerror(68996);
 
-         if R_D0 in unusedscratchregisters then
-           begin
-              r.enum := R_D0;
-           end
-         else if R_D1 in unusedscratchregisters then
-           begin
-              r.enum := R_D1;
-           end
+         if RS_D0 in unusedscratchregisters then
+            rs:=RS_D0
+         else if RS_D1 in unusedscratchregisters then
+            rs:=RS_D1
          else
            internalerror(10);
+         r.enum:=R_INTREGISTER;
+         r.number:=rs shl 8 or cgsize2subreg(size);
 
-         exclude(unusedscratchregisters,r.enum);
+         exclude(unusedscratchregisters,rs);
          a_reg_alloc(list,r);
          get_scratch_reg_int:=r;
       end;
 
 
-     function tcg68k.get_scratch_reg_address(list : taasmoutput) : tregister;
-      var
-         r : tregister;
-         i : longint;
+    function tcg68k.get_scratch_reg_address(list:Taasmoutput):Tregister;
+
+    var r:Tregister;
+        rs:Tsuperregister;
+        i:longint;
 
       begin
          if unusedscratchregisters=[] then
            internalerror(68996);
         
-         if R_A0 in unusedscratchregisters then
-           begin
-              r.enum := R_A0;
-           end
-         else if R_A1 in unusedscratchregisters then
-           begin
-              r.enum := R_A1;
-           end
+         if RS_A0 in unusedscratchregisters then
+           rs:=RS_A0
+         else if RS_A1 in unusedscratchregisters then
+           rs:=RS_A1
          else
            internalerror(10);
+         r.enum:=R_INTREGISTER;
+         r.number:=rs shl 8 or R_SUBWHOLE;
 
-         exclude(unusedscratchregisters,r.enum);
+         exclude(unusedscratchregisters,rs);
          a_reg_alloc(list,r);
          get_scratch_reg_address:=r;
       end;
@@ -460,10 +457,12 @@ Implementation
               Begin
              if aktoptprocessor = MC68000 then
                    begin
-                     r.enum:=R_D0;
-                     r2.enum:=R_D1;
-                     rg.getexplicitregisterint(list,R_D0);
-                     rg.getexplicitregisterint(list,R_D1);
+                     r.enum:=R_INTREGISTER;
+                     r.number:=NR_D0;
+                     r2.enum:=R_INTREGISTER;
+                     r2.number:=NR_D1;
+                     rg.getexplicitregisterint(list,NR_D0);
+                     rg.getexplicitregisterint(list,NR_D1);
                      list.concat(taicpu.op_const_reg(A_MOVE,S_L,a, r));
                      list.concat(taicpu.op_reg_reg(A_MOVE,S_L,reg, r2));
                      cg.a_call_name(list,'FPC_MUL_LONGINT');
@@ -475,7 +474,7 @@ Implementation
                     begin
                       if (rg.isaddressregister(reg)) then
                        begin
-                         scratch_reg := cg.get_scratch_reg_int(list);
+                         scratch_reg := cg.get_scratch_reg_int(list,OS_INT);
                          list.concat(taicpu.op_reg_reg(A_MOVE,S_L,reg, scratch_reg));
                          list.concat(taicpu.op_const_reg(A_MULS,S_L,a,scratch_reg));
                          list.concat(taicpu.op_reg_reg(A_MOVE,S_L,scratch_reg,reg));
@@ -489,10 +488,12 @@ Implementation
               Begin
                  if aktoptprocessor = MC68000 then
                    begin
-                     r.enum:=R_D0;
-                     r2.enum:=R_D1;
-                     rg.getexplicitregisterint(list,R_D0);
-                     rg.getexplicitregisterint(list,R_D1);
+                     r.enum:=R_INTREGISTER;
+                     r.number:=NR_D0;
+                     r2.enum:=R_INTREGISTER;
+                     r2.number:=NR_D1;
+                     rg.getexplicitregisterint(list,NR_D0);
+                     rg.getexplicitregisterint(list,NR_D1);
                      list.concat(taicpu.op_const_reg(A_MOVE,S_L,a, r));
                      list.concat(taicpu.op_reg_reg(A_MOVE,S_L,reg, r2));
                      cg.a_call_name(list,'FPC_MUL_LONGWORD');
@@ -504,7 +505,7 @@ Implementation
                     begin
                       if (rg.isaddressregister(reg)) then
                        begin
-                         scratch_reg := cg.get_scratch_reg_int(list);
+                         scratch_reg := cg.get_scratch_reg_int(list,OS_INT);
                          list.concat(taicpu.op_reg_reg(A_MOVE,S_L,reg, scratch_reg));
                          list.concat(taicpu.op_const_reg(A_MULU,S_L,a,scratch_reg));
                          list.concat(taicpu.op_reg_reg(A_MOVE,S_L,scratch_reg,reg));
@@ -523,7 +524,7 @@ Implementation
                    { now allowed to shift an address register }
                    if (rg.isaddressregister(reg)) then
                      begin
-                       scratch_reg := cg.get_scratch_reg_int(list);
+                       scratch_reg := cg.get_scratch_reg_int(list,OS_INT);
                        list.concat(taicpu.op_reg_reg(A_MOVE,S_L,reg, scratch_reg));
                        list.concat(taicpu.op_const_reg(opcode,S_L,a, scratch_reg));
                        list.concat(taicpu.op_reg_reg(A_MOVE,S_L,scratch_reg,reg));
@@ -535,12 +536,12 @@ Implementation
                 else
                  begin
                    { we must load the data into a register ... :() }
-                   scratch_reg := cg.get_scratch_reg_int(list);
+                   scratch_reg := cg.get_scratch_reg_int(list,OS_INT);
                    list.concat(taicpu.op_const_reg(A_MOVE,S_L,a, scratch_reg));
                    { again... since shifting with address register is not allowed }
                    if (rg.isaddressregister(reg)) then
                      begin
-                       scratch_reg2 := cg.get_scratch_reg_int(list);
+                       scratch_reg2 := cg.get_scratch_reg_int(list,OS_INT);
                        list.concat(taicpu.op_reg_reg(A_MOVE,S_L,reg, scratch_reg2));
                        list.concat(taicpu.op_reg_reg(opcode,S_L,scratch_reg, scratch_reg2));
                        list.concat(taicpu.op_reg_reg(A_MOVE,S_L,scratch_reg2,reg));
@@ -596,7 +597,7 @@ Implementation
                  { load to data registers }
                  if (rg.isaddressregister(reg1)) then
                    begin
-                     hreg1 := cg.get_scratch_reg_int(list);
+                     hreg1 := cg.get_scratch_reg_int(list,OS_INT);
                      list.concat(taicpu.op_reg_reg(A_MOVE,S_L,reg1,hreg1));
                    end
                  else
@@ -604,7 +605,7 @@ Implementation
 
                  if (rg.isaddressregister(reg2))  then
                    begin
-                      hreg2:= cg.get_scratch_reg_int(list);
+                      hreg2:= cg.get_scratch_reg_int(list,OS_INT);
                       list.concat(taicpu.op_reg_reg(A_MOVE,S_L,reg2,hreg2));
                    end
                  else
@@ -652,10 +653,12 @@ Implementation
                  sign_extend(list, size,reg2);
                  if aktoptprocessor = MC68000 then
                    begin
-                     r.enum:=R_D0;
-                     r2.enum:=R_D1;
-                     rg.getexplicitregisterint(list,R_D0);
-                     rg.getexplicitregisterint(list,R_D1);
+                     r.enum:=R_INTREGISTER;
+                     r.number:=NR_D0;
+                     r2.enum:=R_INTREGISTER;
+                     r2.number:=NR_D1;
+                     rg.getexplicitregisterint(list,NR_D0);
+                     rg.getexplicitregisterint(list,NR_D1);
                      list.concat(taicpu.op_reg_reg(A_MOVE,S_L,reg1, r));
                      list.concat(taicpu.op_reg_reg(A_MOVE,S_L,reg2, r2));
                      cg.a_call_name(list,'FPC_MUL_LONGINT');
@@ -666,17 +669,17 @@ Implementation
                   else
                     begin
                      if (rg.isaddressregister(reg1)) then
-                       hreg1 := cg.get_scratch_reg_int(list)
+                       hreg1 := cg.get_scratch_reg_int(list,OS_INT)
                      else
                        hreg1 := reg1;
                      if (rg.isaddressregister(reg2))  then
-                       hreg2:= cg.get_scratch_reg_int(list)
+                       hreg2:= cg.get_scratch_reg_int(list,OS_INT)
                      else
                        hreg2 := reg2;
 
-                     if reg1.enum <> hreg1.enum then
+                     if reg1.number <> hreg1.number then
                           list.concat(taicpu.op_reg_reg(A_MOVE,S_L,reg1,hreg1));
-                     if reg2.enum <> hreg2.enum then
+                     if reg2.number <> hreg2.number then
                           list.concat(taicpu.op_reg_reg(A_MOVE,S_L,reg2,hreg2));
 
                      list.concat(taicpu.op_reg_reg(A_MULS,S_L,reg1,reg2));
@@ -697,10 +700,12 @@ Implementation
                  sign_extend(list, size,reg2);
                  if aktoptprocessor = MC68000 then
                    begin
-                     r.enum:=R_D0;
-                     r2.enum:=R_D1;
-                     rg.getexplicitregisterint(list,R_D0);
-                     rg.getexplicitregisterint(list,R_D1);
+                     r.enum:=R_INTREGISTER;
+                     r.number:=NR_D0;
+                     r2.enum:=R_INTREGISTER;
+                     r2.number:=NR_D1;
+                     rg.getexplicitregisterint(list,NR_D0);
+                     rg.getexplicitregisterint(list,NR_D1);
                      list.concat(taicpu.op_reg_reg(A_MOVE,S_L,reg1, r));
                      list.concat(taicpu.op_reg_reg(A_MOVE,S_L,reg2, r2));
                      cg.a_call_name(list,'FPC_MUL_LONGWORD');
@@ -712,7 +717,7 @@ Implementation
                     begin
                      if (rg.isaddressregister(reg1)) then
                       begin
-                       hreg1 := cg.get_scratch_reg_int(list);
+                       hreg1 := cg.get_scratch_reg_int(list,OS_INT);
                        list.concat(taicpu.op_reg_reg(A_MOVE,S_L,reg1,hreg1));
                       end
                      else
@@ -720,7 +725,7 @@ Implementation
 
                      if (rg.isaddressregister(reg2))  then
                       begin
-                       hreg2:= cg.get_scratch_reg_int(list);
+                       hreg2:= cg.get_scratch_reg_int(list,OS_INT);
                        list.concat(taicpu.op_reg_reg(A_MOVE,S_L,reg2,hreg2));
                       end
                      else
@@ -729,10 +734,10 @@ Implementation
 
                      list.concat(taicpu.op_reg_reg(A_MULU,S_L,reg1,reg2));
 
-                     if reg1.enum <> hreg1.enum then
+                     if reg1.number <> hreg1.number then
                        cg.free_scratch_reg(list,hreg1);
                      { move back result into destination register }
-                     if reg2.enum <> hreg2.enum then
+                     if reg2.number <> hreg2.number then
                        begin
                           list.concat(taicpu.op_reg_reg(A_MOVE,S_L,hreg2,reg2));
                           cg.free_scratch_reg(list,hreg2);
@@ -751,7 +756,7 @@ Implementation
 
                 if (rg.isaddressregister(reg2)) then
                   begin
-                     hreg2 := cg.get_scratch_reg_int(list);
+                     hreg2 := cg.get_scratch_reg_int(list,OS_INT);
                      list.concat(taicpu.op_reg_reg(A_MOVE,S_L,reg2,hreg2));
                    end
                   else
@@ -799,7 +804,7 @@ Implementation
                  only longword comparison is supported,
                  and only on data registers.
                }
-               hregister := cg.get_scratch_reg_int(list);
+               hregister := cg.get_scratch_reg_int(list,OS_INT);
                { always move to a data register }
                list.concat(taicpu.op_reg_reg(A_MOVE,S_L,reg,hregister));
                { sign/zero extend the register }
@@ -850,7 +855,7 @@ Implementation
           { move to a Dx register? }
           if (rg.isaddressregister(reg)) then
             begin
-              hreg := get_scratch_reg_int(list);
+              hreg := get_scratch_reg_int(list,OS_INT);
               a_load_const_reg(list,size,0,hreg);
               ai:=Taicpu.Op_reg(A_Sxx,S_B,hreg);
               ai.SetCondition(flags_to_cond(f));
@@ -919,7 +924,7 @@ Implementation
          { this should never occur }
          if len > 65535 then
            internalerror(0);
-         hregister := get_scratch_reg_int(list);
+         hregister := get_scratch_reg_int(list,OS_INT);
          if delsource then
             reference_release(list,source);
 
@@ -1128,31 +1133,33 @@ Implementation
 
       end;
 
-    procedure tcg68k.g_save_standard_registers(list : taasmoutput; usedinproc : tregisterset);
-      var
-        tosave : tregisterlist;
+    procedure Tcg68k.g_save_standard_registers(list:Taasmoutput;usedinproc:Tsupregset);
+
+    var tosave:Tsupregset;
         r:Tregister;
-      begin
-         tosave:=std_saved_registers;
-         { only save the registers which are not used and must be saved }
-         tosave:=tosave*usedinproc;
-         r.enum:=R_SPPUSH;
-         if tosave<>[] then
-           list.concat(taicpu.op_reglist_reg(A_MOVEM,S_L,tosave,r));
-      end;
+         
+    begin
+      tosave:=std_saved_registers;
+      { only save the registers which are not used and must be saved }
+      tosave:=tosave*usedinproc;
+      r.enum:=R_SPPUSH;
+      if tosave<>[] then
+        list.concat(taicpu.op_reglist_reg(A_MOVEM,S_L,tosave,r));
+    end;
 
-    procedure tcg68k.g_restore_standard_registers(list : taasmoutput; usedinproc : tregisterset);
-      var
-       torestore : tregisterset;
+    procedure Tcg68k.g_restore_standard_registers(list:Taasmoutput;usedinproc:Tsupregset);
+
+    var torestore:Tsupregset;
         r:Tregister;
-      begin
-         torestore:=std_saved_registers;
-         { should be intersected with used regs, no ? }
-         torestore:=torestore*usedinproc;
-         r.enum:=R_SPPULL;
-         if torestore<>[] then
-           list.concat(taicpu.op_reg_reglist(A_MOVEM,S_L,r,torestore));
-      end;
+
+    begin
+      torestore:=std_saved_registers;
+      { should be intersected with used regs, no ? }
+      torestore:=torestore*usedinproc;
+      r.enum:=R_SPPULL;
+      if torestore<>[] then
+        list.concat(taicpu.op_reg_reglist(A_MOVEM,S_L,r,torestore));
+    end;
 
     procedure tcg68k.g_save_all_registers(list : taasmoutput);
       begin
@@ -1337,7 +1344,11 @@ end.
 
 {
   $Log$
-  Revision 1.17  2003-02-12 22:11:13  carl
+  Revision 1.18  2003-02-19 22:00:16  daniel
+    * Code generator converted to new register notation
+    - Horribily outdated todo.txt removed
+
+  Revision 1.17  2003/02/12 22:11:13  carl
     * some small m68k bugfixes
 
   Revision 1.16  2003/02/02 19:25:54  carl

+ 99 - 12
compiler/m68k/cpubase.pas

@@ -101,6 +101,7 @@ uses
                                   Registers
 *****************************************************************************}
 
+    {$packenum 1}
     type
        Toldregister = (
          R_NO,R_D0,R_D1,R_D2,R_D3,R_D4,R_D5,R_D6,R_D7,
@@ -112,14 +113,21 @@ uses
          R_FP7,R_FPCR,R_SR,R_SSP,R_DFC,R_SFC,R_VBR,R_FPSR,
          R_INTREGISTER,R_FLOATREGISTER);
 
-      {# Set type definition for registers }
-      tregisterset = set of Toldregister;
+      Tnewregister=word;
       
       Tregister=record
         enum:Toldregister;
         number:word;
       end;
 
+      Tsuperregister=byte;
+      Tsubregister=byte;
+
+      {# Set type definition for registers }
+      tregisterset = set of Toldregister;
+      Tsupregset = set of Tsuperregister;
+      {$packenum normal}
+
       { A type to store register locations for 64 Bit values. }
       tregister64 = packed record
         reglo,reghi : tregister;
@@ -145,6 +153,27 @@ uses
       NR_A4 = $0D00; NR_A5 = $0E00; NR_A6 = $0F00;
       NR_A7 = $1000; 
 
+    {Super registers.}
+      RS_D0 = $01; RS_D1 = $02; RS_D2 = $03; 
+      RS_D3 = $04; RS_D4 = $05; RS_D5 = $06; 
+      RS_D6 = $07; RS_D7 = $08; RS_A0 = $09; 
+      RS_A1 = $0A; RS_A2 = $0B; RS_A3 = $0C; 
+      RS_A4 = $0D; RS_A5 = $0E; RS_A6 = $0F; 
+      RS_A7 = $10;
+
+     {Sub register numbers:}
+                  R_SUBL        = $00;      {8 bits}
+                  R_SUBW        = $01;      {16 bits}
+                  R_SUBD        = $02;      {32 bits}
+
+     {The subregister that specifies the entire register.}
+                  R_SUBWHOLE    = R_SUBD;  {i386}
+                  {R_SUBWHOLE    = R_SUBQ;} {Hammer}
+
+      {Number of first and last superregister.}
+      first_supreg    = $01;
+      last_supreg     = $10;
+
       {# First register in the tregister enumeration }
       firstreg = low(Toldregister);
       {# Last register in the tregister enumeration }
@@ -153,6 +182,10 @@ uses
     type
       {# Type definition for the array of string of register nnames }
       reg2strtable = array[firstreg..lastreg] of string[7];
+      regname2regnumrec = record
+        name:string[6];
+        number:Tnewregister;
+      end;
 
     const
      std_reg2str : reg2strtable =
@@ -247,7 +280,7 @@ uses
          top_const  : (val:aword);
          top_symbol : (sym:tasmsymbol;symofs:longint);
          { used for pushing/popping multiple registers }
-         top_reglist : (registerlist : tregisterlist);
+         top_reglist : (registerlist:Tsupregset);
       end;
 
 {*****************************************************************************
@@ -352,8 +385,10 @@ uses
 
       {# Constant defining possibly all registers which might require saving }
       ALL_REGISTERS = [R_D1..R_FPCR];
+      ALL_INTREGISTERS = [1..255];
 
       general_registers = [R_D0..R_D7];
+      general_superregisters = [RS_D0..RS_D7];
 
       {# low and high of the available maximum width integer general purpose }
       { registers                                                            }
@@ -379,7 +414,7 @@ uses
 
       maxintregs = 8;
       intregs    = [R_D0..R_D7];
-      usableregsint = [R_D2..R_D7];
+      usableregsint = [RS_D2..RS_D7];
       c_countusableregsint = 6;
 
       maxfpuregs = 8;
@@ -393,14 +428,14 @@ uses
 
       maxaddrregs = 8;
       addrregs    = [R_A0..R_SP];
-      usableregsaddr = [R_A2..R_A4];
+      usableregsaddr = [RS_A2..RS_A4];
       c_countusableregsaddr = 3;
 
 
       { The first register in the usableregsint array }
-      firstsaveintreg = R_D2;
+      firstsaveintreg = RS_D2;
       { The last register in the usableregsint array }
-      lastsaveintreg  = R_D7;
+      lastsaveintreg  = RS_D7;
       { The first register in the usableregsfpu array }
       firstsavefpureg = R_FP2;
       { The last  register in the usableregsfpu array }
@@ -408,9 +443,9 @@ uses
 
       { these constants are m68k specific              }
       { The first register in the usableregsaddr array }
-      firstsaveaddrreg = R_A2;
+      firstsaveaddrreg = RS_A2;
       { The last  register in the usableregsaddr array }
-      lastsaveaddrreg  = R_A4;
+      lastsaveaddrreg  = RS_A4;
 
       firstsavemmreg  = R_NO;
       lastsavemmreg   = R_NO;
@@ -459,7 +494,7 @@ uses
          routine calls or in assembler blocks.
       }
       max_scratch_regs = 4;
-      scratch_regs: Array[1..max_scratch_regs] of Toldregister = (R_D0,R_D1,R_A0,R_A1);
+      scratch_regs: Array[1..max_scratch_regs] of Tsuperregister = (RS_D0,RS_D1,RS_A0,RS_A1);
 
 {*****************************************************************************
                           Default generic sizes
@@ -502,11 +537,17 @@ uses
 
       {# Stack pointer register }
       stack_pointer_reg = R_SP;
+      NR_STACK_POINTER_REG = NR_A7;
+      RS_STACK_POINTER_REG = RS_A7;
       {# Frame pointer register }
       frame_pointer_reg = R_A6;
+      NR_FRAME_POINTER_REG = NR_A6;
+      RS_FRAME_POINTER_REG = RS_A6;
       {# Self pointer register : contains the instance address of an
          object or class. }
       self_pointer_reg  = R_A5;
+      NR_SELF_POINTER_REG = NR_A5;
+      RS_SELF_POINTER_REG = RS_A5;
       {# Register for addressing absolute data in a position independant way,
          such as in PIC code. The exact meaning is ABI specific. For
          further information look at GCC source : PIC_OFFSET_TABLE_REGNUM
@@ -514,16 +555,22 @@ uses
       pic_offset_reg = R_A5;
       {# Results are returned in this register (32-bit values) }
       accumulator   = R_D0;
+      NR_ACCUMULATOR = NR_D0;
+      RS_ACCUMULATOR = RS_D0;
   {the return_result_reg, is used inside the called function to store its return
   value when that is a scalar value otherwise a pointer to the address of the
   result is placed inside it}
   return_result_reg   = accumulator;
+  NR_RETURN_RESULT_REG = NR_ACCUMULATOR;
+  RS_RETURN_RESULT_REG = RS_ACCUMULATOR;
 
   {the function_result_reg contains the function result after a call to a scalar
   function othewise it contains a pointer to the returned result}
   function_result_reg = accumulator;
       {# Hi-Results are returned in this register (64-bit value high register) }
       accumulatorhigh = R_D1;
+      NR_ACCUMULATORHIGH = NR_D1;
+      RS_ACCUMULATORHIGH = RS_D1;
       {# Floating point results will be placed into this register }
       FPU_RESULT_REG = R_FP0;
       mmresultreg = R_NO;
@@ -539,7 +586,7 @@ uses
          This value can be deduced from CALLED_USED_REGISTERS array in the
          GCC source.
       }
-      std_saved_registers = [R_D2..R_D7,R_A2..R_A5];
+      std_saved_registers = [RS_D2..RS_D7,RS_A2..RS_A5];
       {# Required parameter alignment when calling a routine declared as
          stdcall and cdecl. The alignment value should be the one defined
          by GCC or the target ABI.
@@ -563,6 +610,8 @@ uses
     procedure inverse_flags(var r : TResFlags);
     function  flags_to_cond(const f: TResFlags) : TAsmCond;
     procedure convert_register_to_enum(var r:Tregister);
+    function cgsize2subreg(s:Tcgsize):Tsubregister;
+    function supreg_name(r:Tsuperregister):string;
 
 implementation
 
@@ -640,10 +689,48 @@ implementation
         end;
     end;
 
+    function cgsize2subreg(s:Tcgsize):Tsubregister;
+
+    begin
+      case s of
+        OS_8,OS_S8:
+          cgsize2subreg:=R_SUBL;
+        OS_16,OS_S16:
+          cgsize2subreg:=R_SUBW;
+        OS_32,OS_S32:
+          cgsize2subreg:=R_SUBD;
+        else
+          internalerror(200301231);
+      end;
+    end;
+
+    function supreg_name(r:Tsuperregister):string;
+
+    var s:string[4];
+
+    const supreg_names:array[0..last_supreg] of string[4]=
+          ('INV',
+           'd0','d1','d2','d3','d4','d5','d6','d7',
+           'a0','a1','a2','a3','a4','a5','a6','sp');
+
+    begin
+      if r in [0..last_supreg] then
+        supreg_name:=supreg_names[r]
+      else
+        begin
+          str(r,s);
+          supreg_name:='reg'+s;
+        end;
+    end;
+
 end.
 {
   $Log$
-  Revision 1.17  2003-02-02 19:25:54  carl
+  Revision 1.18  2003-02-19 22:00:16  daniel
+    * Code generator converted to new register notation
+    - Horribily outdated todo.txt removed
+
+  Revision 1.17  2003/02/02 19:25:54  carl
     * Several bugfixes for m68k target (register alloc., opcode emission)
     + VIS target
     + Generic add more complete (still not verified)

+ 9 - 5
compiler/m68k/n68kcnv.pas

@@ -184,7 +184,7 @@ implementation
                   end
                 else
                   begin
-                     hreg2:=rg.getregisterint(exprasmlist);
+                     hreg2:=rg.getregisterint(exprasmlist,opsize);
                      cg.a_load_ref_reg(exprasmlist,opsize,
                         left.location.reference,hreg2);
                      exprasmlist.concat(taicpu.op_reg(A_TST,TCGSize2OpSize[opsize],hreg2));
@@ -192,19 +192,19 @@ implementation
                   end;
                 reference_release(exprasmlist,left.location.reference);
                 resflags:=F_NE;
-                hreg1 := rg.getregisterint(exprasmlist);
+                hreg1 := rg.getregisterint(exprasmlist,opsize);
               end;
             LOC_REGISTER,LOC_CREGISTER :
               begin
                 hreg2 := left.location.register;
                 exprasmlist.concat(taicpu.op_reg(A_TST,TCGSize2OpSize[opsize],hreg2));
                 rg.ungetregister(exprasmlist,hreg2);
-                hreg1 := rg.getregisterint(exprasmlist);
+                hreg1 := rg.getregisterint(exprasmlist,opsize);
                 resflags:=F_NE;
               end;
             LOC_FLAGS :
               begin
-                hreg1:=rg.getregisterint(exprasmlist);
+                hreg1:=rg.getregisterint(exprasmlist,opsize);
                 resflags:=left.location.resflags;
               end;
             else
@@ -296,7 +296,11 @@ begin
 end.
 {
   $Log$
-  Revision 1.7  2002-12-05 14:27:53  florian
+  Revision 1.8  2003-02-19 22:00:16  daniel
+    * Code generator converted to new register notation
+    - Horribily outdated todo.txt removed
+
+  Revision 1.7  2002/12/05 14:27:53  florian
     * some variant <-> dyn. array stuff
 
   Revision 1.6  2002/11/25 17:43:27  peter

+ 11 - 7
compiler/m68k/n68kmat.pas

@@ -124,7 +124,7 @@ implementation
              location_force_reg(exprasmlist,left.location,def_cgsize(left.resulttype.def),false);
              location_copy(location,left.location);
              if location.loc=LOC_CREGISTER then
-              location.register := rg.getregisterint(exprasmlist);
+              location.register := rg.getregisterint(exprasmlist,opsize);
              { perform the NOT operation }
              cg.a_op_reg_reg(exprasmlist,OP_NOT,opsize,location.register,left.location.register);
           end;
@@ -159,8 +159,8 @@ implementation
      else
        begin
          { On MC68000/68010 mw must pass through RTL routines }
-         reg_d0:=rg.getexplicitregisterint(exprasmlist,R_D0);
-         reg_d1:=rg.getexplicitregisterint(exprasmlist,R_D1);
+         reg_d0:=rg.getexplicitregisterint(exprasmlist,NR_D0);
+         reg_d1:=rg.getexplicitregisterint(exprasmlist,NR_D1);
          { put numerator in d0 }
          cg.a_load_reg_reg(exprasmlist,OS_INT,OS_INT,num,reg_d0);   
          { put denum in D1 }
@@ -192,7 +192,7 @@ implementation
          cg.a_call_name(exprasmlist,'FPC_HANDLEERROR');
          cg.a_label(exprasmlist, continuelabel);
 
-         tmpreg := cg.get_scratch_reg_int(exprasmlist);       
+         tmpreg := cg.get_scratch_reg_int(exprasmlist,OS_INT);
 
          { we have to prepare the high register with the  }
          { correct sign. i.e we clear it, check if the low dword reg }
@@ -218,8 +218,8 @@ implementation
      else
        begin
          { On MC68000/68010 mw must pass through RTL routines }
-         Reg_d0:=rg.getexplicitregisterint(exprasmlist,R_D0);
-         Reg_d1:=rg.getexplicitregisterint(exprasmlist,R_D1);
+         Reg_d0:=rg.getexplicitregisterint(exprasmlist,NR_D0);
+         Reg_d1:=rg.getexplicitregisterint(exprasmlist,NR_D1);
          { put numerator in d0 }
          cg.a_load_reg_reg(exprasmlist,OS_INT,OS_INT,num,Reg_D0);   
          { put denum in D1 }
@@ -242,7 +242,11 @@ begin
 end.
 {
   $Log$
-  Revision 1.5  2003-02-02 19:25:54  carl
+  Revision 1.6  2003-02-19 22:00:16  daniel
+    * Code generator converted to new register notation
+    - Horribily outdated todo.txt removed
+
+  Revision 1.5  2003/02/02 19:25:54  carl
     * Several bugfixes for m68k target (register alloc., opcode emission)
     + VIS target
     + Generic add more complete (still not verified)

+ 7 - 3
compiler/m68k/ncpuadd.pas

@@ -125,7 +125,7 @@ implementation
                   (nodetype = gten)) then
                 swapleftright;
               // now we have to check whether left >= right
-              tmpreg := cg.get_scratch_reg_int(exprasmlist);
+              tmpreg := cg.get_scratch_reg_int(exprasmlist,OS_INT);
               if left.location.loc = LOC_CONSTANT then
                 begin
                   cg.a_op_const_reg_reg(exprasmlist,OP_AND,OS_INT,
@@ -209,7 +209,7 @@ implementation
             else
               begin
                 useconst := false;
-                tmpreg := cg.get_scratch_reg_int(exprasmlist);
+                tmpreg := cg.get_scratch_reg_int(exprasmlist,OS_INT);
                 cg.a_load_const_reg(exprasmlist,OS_INT,
                   aword(right.location.value),tmpreg);
                end
@@ -432,7 +432,11 @@ end.
 
 {
   $Log$
-  Revision 1.1  2003-02-02 19:25:54  carl
+  Revision 1.2  2003-02-19 22:00:16  daniel
+    * Code generator converted to new register notation
+    - Horribily outdated todo.txt removed
+
+  Revision 1.1  2003/02/02 19:25:54  carl
     * Several bugfixes for m68k target (register alloc., opcode emission)
     + VIS target
     + Generic add more complete (still not verified)

+ 114 - 49
compiler/m68k/rasm.pas

@@ -47,7 +47,7 @@ Interface
 {$i fpcdefs.inc}
 
 Uses
-  node;
+  node,cpubase;
 
    function assemble: tnode;
 
@@ -62,7 +62,7 @@ Implementation
        globtype,globals,verbose,
        systems,
        { aasm }
-       cpubase,cpuinfo,aasmbase,aasmtai,aasmcpu,
+       cpuinfo,aasmbase,aasmtai,aasmcpu,
        { symtable }
        symconst,symbase,symtype,symsym,symtable,
        { pass 1 }
@@ -92,6 +92,28 @@ var
  { uppercased tables of registers }
  iasmregs: array[firstasmreg..lastasmreg] of string[6];
 
+const
+  regname_count=17;
+  regname_count_bsstart=16;
+
+  regname2regnum:array[0..regname_count-1] of regname2regnumrec=(
+    (name:'A0';     number:NR_A0),
+    (name:'A1';     number:NR_A1),
+    (name:'A2';     number:NR_A2),
+    (name:'A3';     number:NR_A3),
+    (name:'A4';     number:NR_A4),
+    (name:'A5';     number:NR_A5),
+    (name:'A6';     number:NR_A6),
+    (name:'A7';     number:NR_A7),
+    (name:'D0';     number:NR_D0),
+    (name:'D1';     number:NR_D1),
+    (name:'D2';     number:NR_D2),
+    (name:'D3';     number:NR_D3),
+    (name:'D4';     number:NR_D4),
+    (name:'D5';     number:NR_D5),
+    (name:'D6';     number:NR_D6),
+    (name:'D7';     number:NR_D7),
+    (name:'SP';     number:NR_A7));
 
 type
  tasmtoken = (
@@ -157,6 +179,28 @@ var
   {                     Routines for the tokenizing                     }
   {---------------------------------------------------------------------}
 
+    function regnum_search(const s:string):Tnewregister;
+
+    {Searches the register number that belongs to the register in s.
+     s must be in uppercase!.}
+
+    var i,p:byte;
+
+    begin
+      {Binary search.}
+      p:=0;
+      i:=regname_count_bsstart;
+      while i<>0 do
+        begin
+          if (p+i<regname_count) and (upper(regname2regnum[p+i].name)<=s) then
+            p:=p+i;
+          i:=i shr 1;
+        end;
+      if upper(regname2regnum[p].name)=s then
+        regnum_search:=regname2regnum[p].number
+      else
+        regnum_search:=NR_NO;
+   end;
 
    function is_asmopcode(s: string):Boolean;
   {*********************************************************************}
@@ -213,24 +257,29 @@ var
   {  Description: Determines if the s string is a valid register, if    }
   {  so return token equal to A_REGISTER, otherwise does not change token}
   {*********************************************************************}
-   Var
-    i: tregister;
-   Begin
-     for i.enum:=firstasmreg to lastasmreg do
-     begin
-      if s=iasmregs[i.enum] then
-      begin
-        token := AS_REGISTER;
-        exit;
-      end;
-     end;
-     { take care of other name for sp }
-     if s = 'A7' then
-     begin
-      token:=AS_REGISTER;
-      exit;
-     end;
-   end;
+    var
+     i: tregister;
+    begin
+      if regnum_search(s)=NR_NO then
+        begin
+          for i.enum:=firstasmreg to lastasmreg do
+            begin
+              if s=iasmregs[i.enum] then
+                begin
+                  token := AS_REGISTER;
+                  exit;
+                end;
+            end;
+          { take care of other name for sp }
+          if s = 'A7' then
+            begin
+              token:=AS_REGISTER;
+              exit;
+            end;
+        end
+      else
+        token:=AS_REGISTER;
+    end;
 
 
 
@@ -577,22 +626,29 @@ var
   {  Description: Determines if the s string is a valid register,       }
   {  if so returns correct tregister token, or R_NO if not found.       }
   {*********************************************************************}
-   var
-    i: tregister;
-   begin
-     findregister.enum := R_NO;
-     for i.enum:=firstasmreg to lastasmreg do
-       if s = iasmregs[i.enum] then
-       Begin
-         findregister := i;
-         exit;
-       end;
-    if s = 'A7' then
-    Begin
-      findregister.enum := R_SP;
-      exit;
+    var
+      i: tregister;
+    begin
+      i.enum:=R_INTREGISTER;
+      i.number:=regnum_search(s);
+      if i.number=NR_NO then
+        begin
+          findregister.enum := R_NO;
+          for i.enum:=firstasmreg to lastasmreg do
+            if s = iasmregs[i.enum] then
+              begin
+                findregister := i;
+                exit;
+              end;
+          if s = 'A7' then
+            begin
+              findregister.enum := R_SP;
+              exit;
+            end;
+        end
+      else
+        findregister:=i;
     end;
-   end;
 
 
    function findopcode(s: string; var opsize: topsize): tasmop;
@@ -1363,11 +1419,12 @@ type
     expr: string;
     lab: tasmlabel;
     l : longint;
-    i: tregister;
+    i: Tsuperregister;
+    r:Tregister;
     hl: tasmlabel;
     reg_one, reg_two: tregister;
-    reglist: Tregisterset;
-  Begin
+    reglist: Tsupregset;
+  begin
    reglist := [];
    tempstr := '';
    expr := '';
@@ -1529,7 +1586,10 @@ type
                    { // Individual register listing // }
                    if (actasmtoken = AS_SLASH) then
                    Begin
-                     reglist := [findregister(tempstr).enum];
+                     r:=findregister(tempstr);
+                     if r.enum<>R_INTREGISTER then
+                       internalerror(200302191);
+                     reglist := [r.number shr 8];
                      Consume(AS_SLASH);
                      if actasmtoken = AS_REGISTER then
                      Begin
@@ -1537,7 +1597,10 @@ type
                        Begin
                          case actasmtoken of
                           AS_REGISTER: Begin
-                                        reglist := reglist + [findregister(actasmpattern).enum];
+                                        r:=findregister(tempstr);
+                                        if r.enum<>R_INTREGISTER then
+                                          internalerror(200302191);
+                                        reglist := reglist + [r.number shr 8];
                                         Consume(AS_REGISTER);
                                        end;
                           AS_SLASH: Consume(AS_SLASH);
@@ -1576,16 +1639,14 @@ type
                      Begin
                       { determine the register range ... }
                       reg_two:=findregister(actasmpattern);
+                      if reg_two.enum<>R_INTREGISTER then
+                        internalerror(200302191);
                       if reg_one.enum > reg_two.enum then
-                      begin
-                       for i.enum:=reg_two.enum to reg_one.enum do
-                         reglist := reglist + [i.enum];
-                      end
+                       for i:=reg_two.number shr 8 to reg_one.number shr 8 do
+                         reglist:=reglist+[i]
                       else
-                      Begin
-                       for i.enum:=reg_one.enum to reg_two.enum do
-                         reglist := reglist + [i.enum];
-                      end;
+                       for i:=reg_one.number shr 8 to reg_two.number shr 8 do
+                         reglist:=reglist+[i];
                       Consume(AS_REGISTER);
                       if not (actasmtoken in [AS_SEPARATOR,AS_COMMA]) then
                       Begin
@@ -2208,7 +2269,11 @@ Begin
 end.
 {
   $Log$
-  Revision 1.12  2003-02-12 22:11:13  carl
+  Revision 1.13  2003-02-19 22:00:16  daniel
+    * Code generator converted to new register notation
+    - Horribily outdated todo.txt removed
+
+  Revision 1.12  2003/02/12 22:11:13  carl
     * some small m68k bugfixes
 
   Revision 1.11  2003/01/08 18:43:57  daniel

+ 95 - 76
compiler/m68k/rgcpu.pas

@@ -35,7 +35,7 @@ unit rgcpu;
 
      type
        trgcpu = class(trgobj)
-          unusedregsaddr,usableregsaddr : tregisterset;
+          unusedregsaddr,usableregsaddr:Tsupregset;
           countunusedregsaddr,
           countusableregsaddr : byte;
           procedure saveStateForInline(var state: pointer);override;
@@ -46,10 +46,11 @@ unit rgcpu;
           function getaddressregister(list: taasmoutput): tregister; override;
           procedure ungetaddressregister(list: taasmoutput; r: tregister); override;
           procedure resetusableregisters;override;
-          procedure restoreusedregisters(list : taasmoutput;
-             const saved : tpushedsaved);override;
-          procedure saveusedregisters(list: taasmoutput;
-        var saved : tpushedsaved; const s: tregisterset);override;
+          procedure restoreusedintregisters(list:Taasmoutput;
+                                            const saved:Tpushedsavedint);override;
+          procedure saveusedintregisters(list:Taasmoutput;
+                                         var saved:Tpushedsavedint;
+                                         const s:Tsupregset);override;
           procedure cleartempgen;override;
 
        end;
@@ -61,22 +62,30 @@ unit rgcpu;
 
      procedure trgcpu.ungetaddressregister(list: taasmoutput; r: tregister);
        begin
-         ungetregistergen(list,r,usableregsaddr,unusedregsaddr,
+         ungetregistergenint(list,r,usableregsaddr,unusedregsaddr,
            countunusedregsaddr);
        end;
 
 
-     function trgcpu.getaddressregister(list: taasmoutput): tregister;
-       begin
-         result := getregistergen(list,firstsaveaddrreg,lastsaveaddrreg,
-                   unusedregsaddr,countunusedregsaddr);
-       end;
-
+    function trgcpu.getaddressregister(list: taasmoutput): tregister;
 
-     function trgcpu.isaddressregister(reg: tregister): boolean;
-       begin
-         isaddressregister := reg.enum in addrregs;
-       end;
+    begin
+      result:=getregistergenint(list,
+                                R_SUBWHOLE,
+                                firstsaveaddrreg,
+                                lastsaveaddrreg,
+                                usedintbyproc,
+                                usedintinproc,
+                                unusedregsint,
+                                countunusedregsint);
+ 
+    end;
+     
+    function trgcpu.isaddressregister(reg: tregister): boolean;
+    
+    begin
+      isaddressregister := reg.enum in addrregs;
+    end;
 
 
     procedure trgcpu.resetusableregisters;
@@ -89,66 +98,72 @@ unit rgcpu;
       end;
 
 
-    procedure trgcpu.restoreusedregisters(list : taasmoutput;
-        const saved : tpushedsaved);
-      var
-         r,r2 : tregister;
-         hr : treference;
-     begin
-        inherited restoreusedregisters(list, saved);
-
-        for r.enum:=lastsaveaddrreg downto firstsaveaddrreg do
-          begin
-            if saved[r.enum].ofs <> reg_not_saved then
-              begin
-                r2.enum:=frame_pointer_reg;
-                reference_reset_base(hr,r2,saved[r.enum].ofs);
-                cg.a_reg_alloc(list,r);
-                cg.a_load_ref_reg(list,OS_ADDR,hr,r);
-                if not (r.enum in unusedregsaddr) then
-                  { internalerror(10)
-                    in n386cal we always save/restore the reg *state*
-                    using save/restoreunusedstate -> the current state
-                    may not be real (JM) }
-                else
-                  begin
-                    dec(countunusedregsaddr);
-                    exclude(unusedregsaddr,r.enum);
-                  end;
-                tg.ungettemp(list,hr);
-              end;
-          end;
-     end;
-
-
-     procedure trgcpu.saveusedregisters(list: taasmoutput;
-        var saved : tpushedsaved; const s: tregisterset);
-      var
-         r : tregister;
-         hr : treference;
-      begin
-        inherited saveusedregisters(list, saved, s);
-        for r.enum:=firstsaveaddrreg to lastsaveaddrreg do
-          begin
-            saved[r.enum].ofs:=reg_not_saved;
-            { if the register is used by the calling subroutine and if }
-            { it's not a regvar (those are handled separately)         }
-            if not is_reg_var[r.enum] and
-               (r.enum in s) and
+    procedure Trgcpu.restoreusedintregisters(list:Taasmoutput;
+                                             const saved:Tpushedsavedint);
+    var r:Tsuperregister;
+        r2,r3:Tregister;
+        hr:Treference;
+
+    begin
+      inherited restoreusedintregisters(list, saved);
+
+      for r:=lastsaveaddrreg downto firstsaveaddrreg do
+        begin
+          if saved[r].ofs<>reg_not_saved then
+            begin
+              r2.enum:=R_INTREGISTER;
+              r2.number:=NR_FRAME_POINTER_REG;
+              reference_reset_base(hr,r2,saved[r].ofs);
+              r3.enum:=R_INTREGISTER;
+              r3.number:=r shl 8 or R_SUBWHOLE;
+              cg.a_reg_alloc(list,r3);
+              cg.a_load_ref_reg(list,OS_ADDR,hr,r3);
+              if not (r in unusedregsaddr) then
+                { internalerror(10)
+                  in n386cal we always save/restore the reg *state*
+                  using save/restoreunusedstate -> the current state
+                  may not be real (JM) }
+              else
+                begin
+                  dec(countunusedregsaddr);
+                  exclude(unusedregsaddr,r);
+                end;
+              tg.ungettemp(list,hr);
+            end;
+        end;
+    end;
+
+
+    procedure Trgcpu.saveusedintregisters(list:Taasmoutput;
+                                          var saved:Tpushedsavedint;
+                                          const s:Tsupregset);
+    var r:Tsuperregister;
+        r2:Tregister;
+        hr:Treference;
+
+    begin
+      inherited saveusedintregisters(list,saved,s);
+      for r:=firstsaveaddrreg to lastsaveaddrreg do
+        begin
+          saved[r].ofs:=reg_not_saved;
+          { if the register is used by the calling subroutine and if }
+          { it's not a regvar (those are handled separately)         }
+          if not(r in is_reg_var_int) and (r in s) and
                { and is present in use }
-               not(r.enum in unusedregsaddr) then
-              begin
-                { then save it }
-                tg.gettemp(list,pointer_size,tt_persistant,hr);
-                saved[r.enum].ofs:=hr.offset;
-                cg.a_load_reg_ref(list,OS_ADDR,r,hr);
-                cg.a_reg_dealloc(list,r);
-                include(unusedregsaddr,r.enum);
-                inc(countunusedregsaddr);
-              end;
-          end;
-
-      end;
+               not(r in unusedregsaddr) then
+            begin
+              { then save it }
+              tg.gettemp(list,pointer_size,tt_persistant,hr);
+              saved[r].ofs:=hr.offset;
+              r2.enum:=R_INTREGISTER;
+              r2.number:=r shl 8 or R_SUBWHOLE;
+              cg.a_load_reg_ref(list,OS_ADDR,r2,hr);
+              cg.a_reg_dealloc(list,r2);
+              include(unusedregsaddr,r);
+              inc(countunusedregsaddr);
+            end;
+        end;
+    end;
 
 
 
@@ -200,7 +215,11 @@ end.
 
 {
   $Log$
-  Revision 1.6  2003-02-02 19:25:54  carl
+  Revision 1.7  2003-02-19 22:00:16  daniel
+    * Code generator converted to new register notation
+    - Horribily outdated todo.txt removed
+
+  Revision 1.6  2003/02/02 19:25:54  carl
     * Several bugfixes for m68k target (register alloc., opcode emission)
     + VIS target
     + Generic add more complete (still not verified)

+ 9 - 3
compiler/ncal.pas

@@ -1973,7 +1973,8 @@ type
               { procedure does a call }
               if not (block_type in [bt_const,bt_type]) then
                 procinfo.flags:=procinfo.flags or pi_do_call;
-              rg.incrementregisterpushed(all_registers);
+              rg.incrementintregisterpushed(all_intregisters);
+              rg.incrementotherregisterpushed(all_registers);
            end
          else
          { not a procedure variable }
@@ -2009,7 +2010,8 @@ type
                 end;
 
              { It doesn't hurt to calculate it already though :) (JM) }
-             rg.incrementregisterpushed(tprocdef(procdefinition).usedregisters);
+             rg.incrementintregisterpushed(tprocdef(procdefinition).usedintregisters);
+             rg.incrementotherregisterpushed(tprocdef(procdefinition).usedotherregisters);
 
            end;
 
@@ -2384,7 +2386,11 @@ begin
 end.
 {
   $Log$
-  Revision 1.127  2003-01-16 22:13:52  peter
+  Revision 1.128  2003-02-19 22:00:14  daniel
+    * Code generator converted to new register notation
+    - Horribily outdated todo.txt removed
+
+  Revision 1.127  2003/01/16 22:13:52  peter
     * convert_l3 convertlevel added. This level is used for conversions
       where information can be lost like converting widestring->ansistring
       or dword->byte

+ 22 - 15
compiler/ncgadd.pas

@@ -211,15 +211,16 @@ interface
         tmpreg : tregister;
         opdone,
         cmpop  : boolean;
+        size:Tcgsize;
       begin
 
 
         opdone := false;
-        
-        location_reset(location,LOC_REGISTER,def_cgsize(resulttype.def));
+        size:=def_cgsize(resulttype.def);
+        location_reset(location,LOC_REGISTER,size);
 
         if  (location.register.enum = R_NO) then
-          location.register := rg.getregisterint(exprasmlist);
+          location.register := rg.getregisterint(exprasmlist,size);
 
         case nodetype of
           addn :
@@ -238,7 +239,7 @@ interface
                       left.location.register,location.register)
                   else
                     begin
-                      tmpreg := cg.get_scratch_reg_int(exprasmlist);
+                      tmpreg := cg.get_scratch_reg_int(exprasmlist,size);
                       cg.a_load_const_reg(exprasmlist,OS_INT,1,tmpreg);
                       cg.a_op_reg_reg(exprasmlist,OP_SHL,OS_INT,
                         right.location.register,tmpreg);
@@ -278,7 +279,7 @@ interface
                 begin
                   if left.location.loc = LOC_CONSTANT then
                     begin
-                      tmpreg := cg.get_scratch_reg_int(exprasmlist);
+                      tmpreg := cg.get_scratch_reg_int(exprasmlist,OS_INT);
                       cg.a_load_const_reg(exprasmlist,OS_INT,
                         aword(left.location.value),tmpreg);
                       cg.a_op_reg_reg(exprasmlist,OP_NOT,OS_INT,right.location.register,right.location.register);
@@ -544,8 +545,8 @@ interface
                 begin
                   if (location.registerlow.enum = R_NO) then
                     begin
-                      location.registerlow := rg.getregisterint(exprasmlist);
-                      location.registerhigh := rg.getregisterint(exprasmlist);
+                      location.registerlow := rg.getregisterint(exprasmlist,OS_INT);
+                      location.registerhigh := rg.getregisterint(exprasmlist,OS_INT);
                     end;
 
                   if (left.location.loc = LOC_CONSTANT) then
@@ -566,8 +567,8 @@ interface
                     begin
                       if (location.registerlow.enum = R_NO) then
                         begin
-                         location.registerlow := rg.getregisterint(exprasmlist);
-                         location.registerhigh := rg.getregisterint(exprasmlist);
+                         location.registerlow := rg.getregisterint(exprasmlist,OS_INT);
+                         location.registerhigh := rg.getregisterint(exprasmlist,OS_INT);
                       end;
                       if right.location.loc <> LOC_CONSTANT then
                         // reg64 - reg64
@@ -589,8 +590,8 @@ interface
                         location.register64 := left.location.register64
                       else if (location.registerlow.enum = R_NO) then
                         begin
-                         location.registerlow := rg.getregisterint(exprasmlist);
-                         location.registerhigh := rg.getregisterint(exprasmlist);
+                         location.registerlow := rg.getregisterint(exprasmlist,OS_INT);
+                         location.registerhigh := rg.getregisterint(exprasmlist,OS_INT);
                         end;
                       cg64.a_op64_reg_reg_reg(exprasmlist,OP_SUB,
                         right.location.register64,left.location.register64,
@@ -625,9 +626,11 @@ interface
       checkoverflow : boolean;
       cgop : topcg;
       tmpreg : tregister;
+      size:Tcgsize;
      begin
+       size:=def_cgsize(resulttype.def);
        { set result location }
-       location_reset(location,LOC_REGISTER,def_cgsize(resulttype.def));
+       location_reset(location,LOC_REGISTER,size);
 
        { determine if the comparison will be unsigned }
        unsigned:=not(is_signed(left.resulttype.def)) or
@@ -638,7 +641,7 @@ interface
           (nodetype in [addn,subn,muln]));
 
        if (location.register.enum = R_NO) then
-         location.register := rg.getregisterint(exprasmlist);
+         location.register := rg.getregisterint(exprasmlist,OS_INT);
 
        { assume no overflow checking is require }
        checkoverflow := false;
@@ -706,7 +709,7 @@ interface
            end
          else
            begin
-             tmpreg := cg.get_scratch_reg_int(exprasmlist);
+             tmpreg := cg.get_scratch_reg_int(exprasmlist,OS_INT);
              cg.a_load_const_reg(exprasmlist,OS_INT,
                aword(left.location.value),tmpreg);
              cg.a_op_reg_reg_reg(exprasmlist,OP_SUB,OS_INT,
@@ -815,7 +818,11 @@ begin
 end.
 {
   $Log$
-  Revision 1.5  2003-02-02 19:25:54  carl
+  Revision 1.6  2003-02-19 22:00:14  daniel
+    * Code generator converted to new register notation
+    - Horribily outdated todo.txt removed
+
+  Revision 1.5  2003/02/02 19:25:54  carl
     * Several bugfixes for m68k target (register alloc., opcode emission)
     + VIS target
     + Generic add more complete (still not verified)

+ 63 - 24
compiler/ncgcal.pas

@@ -372,6 +372,7 @@ implementation
       var
         cgsize : tcgsize;
         r,hregister : tregister;
+        nr:Tnewregister;
       begin
         { structured results are easy to handle.... }
         { needed also when result_no_used !! }
@@ -424,25 +425,42 @@ implementation
                   if cgsize<>OS_NO then
                    begin
                      location_reset(location,LOC_REGISTER,cgsize);
-                     r.enum:=accumulator;
-                     hregister.enum:=accumulatorhigh;
-                     cg.a_reg_alloc(exprasmlist,r);
 {$ifndef cpu64bit}
                      if cgsize in [OS_64,OS_S64] then
                       begin
+                        {Move the function result to free registers, preferably the
+                         accumulator/accumulatorhigh, so no move is necessary.}
+                        r.enum:=R_INTREGISTER;
+                        r.number:=NR_ACCUMULATOR;
+                        hregister.enum:=R_INTREGISTER;
+                        hregister.number:=NR_ACCUMULATORHIGH;
+                        cg.a_reg_alloc(exprasmlist,r);
                         cg.a_reg_alloc(exprasmlist,hregister);
-                        location.registerhigh:=rg.getexplicitregisterint(exprasmlist,hregister.enum);
-                        location.registerlow:=rg.getexplicitregisterint(exprasmlist,r.enum);
+                        if RS_ACCUMULATOR in rg.unusedregsint then
+                          location.registerlow:=rg.getexplicitregisterint(exprasmlist,NR_ACCUMULATOR)
+                        else
+                          location.registerlow:=rg.getregisterint(exprasmlist,OS_INT);
+                        if RS_ACCUMULATORHIGH in rg.unusedregsint then
+                          location.registerhigh:=rg.getexplicitregisterint(exprasmlist,NR_ACCUMULATORHIGH)
+                        else
+                          location.registerhigh:=rg.getregisterint(exprasmlist,OS_INT);
                         cg64.a_load64_reg_reg(exprasmlist,joinreg64(r,hregister),
                             location.register64);
                       end
                      else
 {$endif cpu64bit}
                       begin
-                        location.register:=rg.getexplicitregisterint(exprasmlist,r.enum);
-                        hregister:=rg.makeregsize(r,cgsize);
-                        location.register:=rg.makeregsize(location.register,cgsize);
-                        cg.a_load_reg_reg(exprasmlist,cgsize,cgsize,hregister,location.register);
+                        {Move the function result to a free register, preferably the
+                         accumulator, so no move is necessary.}
+                        nr:=RS_ACCUMULATOR shl 8 or cgsize2subreg(cgsize);
+                        r.enum:=R_INTREGISTER;
+                        r.number:=nr;
+                        cg.a_reg_alloc(exprasmlist,r);
+                        if RS_ACCUMULATOR in rg.unusedregsint then
+                          location.register:=rg.getexplicitregisterint(exprasmlist,nr)
+                        else
+                          location.register:=rg.getregisterint(exprasmlist,cgsize);
+                        cg.a_load_reg_reg(exprasmlist,cgsize,cgsize,r,location.register);
                       end;
                    end;
                 end;
@@ -480,8 +498,12 @@ implementation
               else
                 begin
                   location_reset(location,LOC_REGISTER,OS_INT);
-                  location.register:=rg.getexplicitregisterint(exprasmlist,accumulator);
-                  r.enum:=accumulator;
+                  if RS_ACCUMULATOR in rg.unusedregsint then
+                    location.register:=rg.getexplicitregisterint(exprasmlist,NR_ACCUMULATOR)
+                  else
+                    location.register:=rg.getregisterint(exprasmlist,OS_INT);
+                  r.enum:=R_INTREGISTER;
+                  r.number:=NR_ACCUMULATOR;
                   cg.a_load_reg_reg(exprasmlist,OS_INT,OS_INT,r,location.register);
                 end;
             end;
@@ -491,9 +513,11 @@ implementation
 
     procedure tcgcallnode.pass_2;
       var
-         regs_to_push : tregisterset;
+         regs_to_push_int : Tsupregset;
+         regs_to_push_other : tregisterset;
          unusedstate: pointer;
          pushed : tpushedsaved;
+         pushedint : tpushedsavedint;
          tmpreg : tregister;
          hregister : tregister;
          hregister64 : tregister64;
@@ -624,25 +648,30 @@ implementation
 
               { save all used registers and possible registers
                 used for the return value }
-              regs_to_push := tprocdef(procdefinition).usedregisters;
+              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
                begin
-                 include(regs_to_push,accumulator);
+                 include(regs_to_push_int,RS_ACCUMULATOR);
 {$ifndef cpu64bit}
                  if resulttype.def.size>sizeof(aword) then
-                   include(regs_to_push,accumulatorhigh);
+                   include(regs_to_push_int,RS_ACCUMULATORHIGH);
 {$endif cpu64bit}
                end;
-              rg.saveusedregisters(exprasmlist,pushed,regs_to_push);
+              rg.saveusedintregisters(exprasmlist,pushedint,regs_to_push_int);
+              rg.saveusedotherregisters(exprasmlist,pushed,regs_to_push_other);
 
               { give used registers through }
-              rg.usedinproc:=rg.usedinproc + tprocdef(procdefinition).usedregisters;
+              rg.usedintinproc:=rg.usedintinproc + tprocdef(procdefinition).usedintregisters;
+              rg.usedinproc:=rg.usedinproc + tprocdef(procdefinition).usedotherregisters;
            end
          else
            begin
-              regs_to_push := all_registers;
-              rg.saveusedregisters(exprasmlist,pushed,regs_to_push);
+              regs_to_push_int := all_intregisters;
+              regs_to_push_other := all_registers;
+              rg.saveusedintregisters(exprasmlist,pushedint,regs_to_push_int);
+              rg.saveusedotherregisters(exprasmlist,pushed,regs_to_push_other);
               rg.usedinproc:=all_registers;
               { no IO check for methods and procedure variables }
               iolabel:=nil;
@@ -1129,8 +1158,10 @@ implementation
                 if (lexlevel>=normal_function_level) and assigned(tprocdef(procdefinition).parast) and
                   ((tprocdef(procdefinition).parast.symtablelevel)>normal_function_level) then
                   load_framepointer;
+
+              rg.saveintregvars(exprasmlist,regs_to_push_int);
+              rg.saveotherregvars(exprasmlist,regs_to_push_other);
 {$endif SPARC}
-              rg.saveregvars(exprasmlist,regs_to_push);
 
 {$ifdef dummy}
               if (po_virtualmethod in procdefinition.procoptions) and
@@ -1256,7 +1287,8 @@ implementation
                 end
               else
                 begin
-                   rg.saveregvars(exprasmlist,ALL_REGISTERS);
+                   rg.saveintregvars(exprasmlist,ALL_INTREGISTERS);
+                   rg.saveotherregvars(exprasmlist,ALL_REGISTERS);
                    cg.a_call_loc(exprasmlist,right.location);
                    location_release(exprasmlist,right.location);
                    location_freetemp(exprasmlist,right.location);
@@ -1374,7 +1406,8 @@ implementation
 {$endif i386}
 
          { restore registers }
-         rg.restoreusedregisters(exprasmlist,pushed);
+         rg.restoreusedotherregisters(exprasmlist,pushed);
+         rg.restoreusedintregisters(exprasmlist,pushedint);
 
          { at last, restore instance pointer (SELF) }
          if loadesi then
@@ -1485,7 +1518,9 @@ implementation
                     if assigned(regvars[i]) then
                       begin
                         tmpreg:=rg.makeregsize(regvars[i].reg,OS_INT);
-                        rg.makeregvar(tmpreg);
+                        {Fix me!!}
+{                        rg.makeregvar(tmpreg);}
+                        internalerror(200301232);
                       end;
             end;
           oldinlining_procedure:=inlining_procedure;
@@ -1627,7 +1662,11 @@ begin
 end.
 {
   $Log$
-  Revision 1.38  2003-02-15 22:17:38  carl
+  Revision 1.39  2003-02-19 22:00:14  daniel
+    * Code generator converted to new register notation
+    - Horribily outdated todo.txt removed
+
+  Revision 1.38  2003/02/15 22:17:38  carl
    * bugfix of FPU emulation code
 
   Revision 1.37  2003/02/12 22:10:07  carl

+ 6 - 2
compiler/ncgcnv.pas

@@ -162,7 +162,7 @@ interface
                 end
                else
                 begin
-                  location.register:=rg.getregisterint(exprasmlist);
+                  location.register:=rg.getregisterint(exprasmlist,OS_INT);
 {$ifdef fpc}
 {$warning Todo: convert widestrings to ascii when typecasting them to pchars}
 {$endif}
@@ -510,7 +510,11 @@ end.
 
 {
   $Log$
-  Revision 1.35  2003-01-02 22:20:51  peter
+  Revision 1.36  2003-02-19 22:00:14  daniel
+    * Code generator converted to new register notation
+    - Horribily outdated todo.txt removed
+
+  Revision 1.35  2003/01/02 22:20:51  peter
     * fix typecasts from void to int
 
   Revision 1.34  2002/11/25 17:43:17  peter

+ 35 - 18
compiler/ncgflw.pas

@@ -343,7 +343,7 @@ implementation
                 begin
                    cg.a_load_reg_ref(exprasmlist,opsize,
                      right.location.register,temp1);
-                   rg.ungetregister(exprasmlist,right.location.register);
+                   rg.ungetregisterint(exprasmlist,right.location.register);
                  end
               else
                 cg.g_concatcopy(exprasmlist,right.location.reference,temp1,
@@ -702,7 +702,8 @@ implementation
 {$ifdef cpuflags}
                     LOC_FLAGS :
                       begin
-                        r.enum:=accumulator;
+                        r.enum:=R_INTREGISTER;
+                        r.number:=NR_ACCUMULATOR;
                         cg.a_reg_alloc(exprasmlist,r);
                         allocated_acc := true;
                         cg.g_flags2reg(exprasmlist,OS_INT,left.location.resflags,r);
@@ -711,10 +712,10 @@ implementation
 {$endif cpuflags}
                     LOC_JUMP :
                       begin
-                        r.enum:=accumulator;
+                        r.enum:=R_INTREGISTER;
+                        r.number:=(RS_ACCUMULATOR shl 8) or R_SUBL;
                         cg.a_reg_alloc(exprasmlist,r);
                         { get an 8-bit register }
-                        hreg:=rg.makeregsize(r,OS_8);
                         allocated_acc := true;
                         cg.a_label(exprasmlist,truelabel);
                         cg.a_load_const_reg(exprasmlist,OS_8,1,hreg);
@@ -728,7 +729,8 @@ implementation
                     pointerdef,
                     procvardef :
                       begin
-                        r.enum:=accumulator;
+                        r.enum:=R_INTREGISTER;
+                        r.number:=NR_ACCUMULATOR;
                         cg.a_reg_alloc(exprasmlist,r);
                         allocated_acc := true;
                         cg.a_load_loc_reg(exprasmlist,left.location,r);
@@ -749,14 +751,16 @@ implementation
                     else
                       begin
                         cgsize:=def_cgsize(aktprocdef.rettype.def);
-                        r.enum:=accumulator;
-                        cg.a_reg_alloc(exprasmlist,r);
                         allocated_acc := true;
 {$ifndef cpu64bit}
 
                         if cgsize in [OS_64,OS_S64] then
                           begin
-                             hreg.enum:=accumulatorhigh;
+                             r.enum:=R_INTREGISTER;
+                             r.number:=NR_ACCUMULATOR;
+                             hreg.enum:=R_INTREGISTER;
+                             hreg.number:=NR_ACCUMULATORHIGH;
+                             cg.a_reg_alloc(exprasmlist,r);
                              cg.a_reg_alloc(exprasmlist,hreg);
                              allocated_acchigh := true;
                              cg64.a_load64_loc_reg(exprasmlist,left.location,
@@ -765,8 +769,10 @@ implementation
                          else
 {$endif cpu64bit}
                            begin
-                              hreg:=rg.makeregsize(r,cgsize);
-                              cg.a_load_loc_reg(exprasmlist,left.location,hreg);
+                             r.enum:=R_INTREGISTER;
+                             r.number:=(RS_ACCUMULATOR shl 8) or cgsize2subreg(cgsize);
+                             cg.a_reg_alloc(exprasmlist,r);
+                             cg.a_load_loc_reg(exprasmlist,left.location,r);
                            end;
                      end;
                   end;
@@ -775,8 +781,10 @@ implementation
                   truelabel:=otlabel;
                   falselabel:=oflabel;
                   cg.a_jmp_always(exprasmlist,aktexit2label);
-                  r.enum:=accumulator;
-                  hreg.enum:=accumulatorhigh;
+                  r.enum:=R_INTREGISTER;
+                  r.number:=NR_ACCUMULATOR;
+                  hreg.enum:=R_INTREGISTER;
+                  hreg.number:=NR_ACCUMULATORHIGH;
                   if allocated_acc then
                     cg.a_reg_dealloc(exprasmlist,r);
 {$ifndef cpu64bit}
@@ -904,7 +912,8 @@ implementation
                    cg.a_label(exprasmlist,a);
                    reference_reset_symbol(href2,a,0);
                    { push current frame }
-                   r.enum:=frame_pointer_reg;
+                   r.enum:=R_INTREGISTER;
+                   r.number:=NR_FRAME_POINTER_REG;
                    cg.a_param_reg(exprasmlist,OS_ADDR,r,paramanager.getintparaloc(2));
                    { push current address }
                    cg.a_paramaddr_ref(exprasmlist,href2,paramanager.getintparaloc(1));
@@ -961,7 +970,8 @@ implementation
 
       begin
          cg.a_call_name(exprasmlist,'FPC_POPOBJECTSTACK');
-         r.enum:=accumulator;
+         r.enum:=R_INTREGISTER;
+         r.number:=NR_ACCUMULATOR;
          cg.a_param_reg(exprasmlist,OS_ADDR,r,paramanager.getintparaloc(1));
          cg.a_call_name(exprasmlist,'FPC_DESTROYEXCEPTION');
          cg.g_maybe_loadself(exprasmlist);
@@ -1094,7 +1104,8 @@ implementation
 
               cg.a_call_name(exprasmlist,'FPC_POPSECONDOBJECTSTACK');
 
-              r.enum:=accumulator;
+              r.enum:=R_INTREGISTER;
+              r.number:=NR_ACCUMULATOR;
               cg.a_param_reg(exprasmlist, OS_ADDR, r, paramanager.getintparaloc(1));
               cg.a_call_name(exprasmlist,'FPC_DESTROYEXCEPTION');
               { we don't need to restore esi here because reraise never }
@@ -1210,7 +1221,8 @@ implementation
          r:Tregister;
 
       begin
-         r.enum:=accumulator;
+         r.enum:=R_INTREGISTER;
+         r.number:=NR_ACCUMULATOR;
          oldflowcontrol:=flowcontrol;
          flowcontrol:=[];
          objectlibrary.getlabel(nextonlabel);
@@ -1393,7 +1405,8 @@ implementation
 
          { the value should now be in the exception handler }
          cg.g_exception_reason_load(exprasmlist,href);
-         r.enum:=accumulator;
+         r.enum:=R_INTREGISTER;
+         r.number:=NR_ACCUMULATOR;
          cg.a_cmp_const_reg_label(exprasmlist,OS_S32,OC_EQ,0,r,endfinallylabel);
          cg.a_op_const_reg(exprasmlist,OP_SUB,1,r);
          cg.a_cmp_const_reg_label(exprasmlist,OS_S32,OC_EQ,0,r,reraiselabel);
@@ -1475,7 +1488,11 @@ begin
 end.
 {
   $Log$
-  Revision 1.50  2003-02-15 22:17:38  carl
+  Revision 1.51  2003-02-19 22:00:14  daniel
+    * Code generator converted to new register notation
+    - Horribily outdated todo.txt removed
+
+  Revision 1.50  2003/02/15 22:17:38  carl
    * bugfix of FPU emulation code
 
   Revision 1.49  2003/01/08 18:43:56  daniel

+ 10 - 5
compiler/ncginl.pas

@@ -190,7 +190,8 @@ implementation
        maketojumpbool(exprasmlist,tcallparanode(left).left,lr_load_regvars);
        cg.a_label(exprasmlist,falselabel);
        { erroraddr }
-       r.enum:=frame_pointer_reg;
+       r.enum:=R_INTREGISTER;
+       r.number:=NR_FRAME_POINTER_REG;
        cg.a_param_reg(exprasmlist,OS_ADDR,r,paramanager.getintparaloc(4));
        { lineno }
        cg.a_param_const(exprasmlist,OS_INT,aktfilepos.line,paramanager.getintparaloc(3));
@@ -282,7 +283,7 @@ implementation
            begin
              reference_reset_base(href,hregister,0);
              rg.ungetaddressregister(exprasmlist,hregister);
-             hregister:=rg.getregisterint(exprasmlist);
+             hregister:=rg.getregisterint(exprasmlist,OS_INT);
              cg.a_load_ref_reg(exprasmlist,OS_INT,href,hregister);
            end;
         location.register:=hregister;
@@ -513,8 +514,8 @@ implementation
               maybe_restore(exprasmlist,tcallparanode(left).left.location,pushedregs);
 
               { bitnumber - which must be loaded into register }
-              hregister := cg.get_scratch_reg_int(exprasmlist);
-              hregister2 := rg.getregisterint(exprasmlist);
+              hregister := cg.get_scratch_reg_int(exprasmlist,OS_INT);
+              hregister2 := rg.getregisterint(exprasmlist,OS_INT);
 
               case tcallparanode(tcallparanode(left).right).left.location.loc of
                  LOC_CREGISTER,
@@ -649,7 +650,11 @@ end.
 
 {
   $Log$
-  Revision 1.20  2003-01-31 22:47:27  peter
+  Revision 1.21  2003-02-19 22:00:14  daniel
+    * Code generator converted to new register notation
+    - Horribily outdated todo.txt removed
+
+  Revision 1.20  2003/01/31 22:47:27  peter
     * fix previous typeof change
 
   Revision 1.19  2003/01/30 21:46:57  peter

+ 33 - 17
compiler/ncgld.pas

@@ -68,11 +68,12 @@ implementation
       var
         intreg,
         r,hregister : tregister;
+        supreg:Tsuperregister;
         symtabletype : tsymtabletype;
         i : longint;
         href : treference;
         newsize : tcgsize;
-        pushed : tpushedsaved;
+        pushed : tpushedsavedint;
         dorelocatelab,
         norelocatelab : tasmlabel;
       begin
@@ -145,16 +146,19 @@ implementation
                        cg.a_loadaddr_ref_reg(exprasmlist,href,hregister);
                        cg.a_jmp_always(exprasmlist,norelocatelab);
                        cg.a_label(exprasmlist,dorelocatelab);
+                       if hregister.enum<>R_INTREGISTER then
+                         internalerror(200301171);
                        { don't save the allocated register else the result will be destroyed later }
-                       rg.saveusedregisters(exprasmlist,pushed,[accumulator]-[hregister.enum]);
+                       rg.saveusedintregisters(exprasmlist,pushed,[RS_ACCUMULATOR]-[hregister.number shr 8]);
                        reference_reset_symbol(href,objectlibrary.newasmsymbol(tvarsym(symtableentry).mangledname),0);
                        cg.a_param_ref(exprasmlist,OS_ADDR,href,paramanager.getintparaloc(1));
                        { the called procedure isn't allowed to change }
                        { any register except EAX                    }
                        cg.a_call_reg(exprasmlist,hregister);
-                       r.enum:=accumulator;
+                       r.enum:=R_INTREGISTER;
+                       r.number:=NR_ACCUMULATOR;
                        cg.a_load_reg_reg(exprasmlist,OS_INT,OS_ADDR,r,hregister);
-                       rg.restoreusedregisters(exprasmlist,pushed);
+                       rg.restoreusedintregisters(exprasmlist,pushed);
                        cg.a_label(exprasmlist,norelocatelab);
                        location.reference.base:=hregister;
                     end
@@ -169,16 +173,18 @@ implementation
                                  location_reset(location,LOC_CFPUREGISTER,def_cgsize(resulttype.def));
                                  location.register:=tvarsym(symtableentry).reg;
                               end
-                            else
+                            else if Tvarsym(symtableentry).reg.enum=R_INTREGISTER then
                              begin
-                               intreg:=rg.makeregsize(tvarsym(symtableentry).reg,OS_INT);
-                               if (intreg.enum in general_registers) and
-                                  (not rg.regvar_loaded[intreg.enum]) then
+                               supreg:=Tvarsym(symtableentry).reg.number shr 8;
+                               if (supreg in general_superregisters) and
+                                  not (supreg in rg.regvar_loaded_int) then
                                  load_regvar(exprasmlist,tvarsym(symtableentry));
                                location_reset(location,LOC_CREGISTER,cg.reg_cgsize(tvarsym(symtableentry).reg));
                                location.register:=tvarsym(symtableentry).reg;
-                               exclude(rg.unusedregsint,intreg.enum);
-                             end;
+                               exclude(rg.unusedregsint,supreg);
+                             end
+                           else
+                             internalerror(200301172);
                          end
                        else
                          begin
@@ -246,8 +252,9 @@ implementation
                                      location.reference.symbol:=objectlibrary.newasmsymbol(tvarsym(symtableentry).mangledname)
                                    else
                                      begin
-                                        rg.getexplicitregisterint(exprasmlist,SELF_POINTER_REG);
-                                        location.reference.base.enum:=SELF_POINTER_REG;
+                                        rg.getexplicitregisterint(exprasmlist,NR_SELF_POINTER_REG);
+                                        location.reference.base.enum:=R_INTREGISTER;
+                                        location.reference.base.number:=NR_SELF_POINTER_REG;
                                         location.reference.offset:=tvarsym(symtableentry).address;
                                      end;
                                 end;
@@ -356,7 +363,7 @@ implementation
                       else
                         begin
                           { we don't use the hregister }
-                          rg.ungetregister(exprasmlist,hregister);
+                          rg.ungetregisterint(exprasmlist,hregister);
                           { load address of the function }
                           reference_reset_symbol(href,objectlibrary.newasmsymbol(tprocdef(resulttype.def).mangledname),0);
                           hregister:=cg.get_scratch_reg_address(exprasmlist);
@@ -392,6 +399,7 @@ implementation
          releaseright : boolean;
          pushedregs : tmaybesave;
          cgsize : tcgsize;
+         r:Tregister;
 
       begin
         otlabel:=truelabel;
@@ -522,7 +530,11 @@ implementation
                     case right.location.loc of
                       LOC_REGISTER,
                       LOC_CREGISTER :
-                        cg.a_load_reg_ref(exprasmlist,OS_8,rg.makeregsize(right.location.register,OS_8),href);
+                        begin
+                          r.enum:=R_INTREGISTER;
+                          r.number:=(right.location.register.number and not $ff) or R_SUBL;
+                          cg.a_load_reg_ref(exprasmlist,OS_8,r,href);
+                        end;
                       LOC_REFERENCE,
                       LOC_CREFERENCE :
                         cg.a_load_ref_ref(exprasmlist,OS_8,right.location.reference,href);
@@ -644,7 +656,7 @@ implementation
 {$ifdef cpuflags}
               LOC_FLAGS :
                 begin
-                  // this can be a wordbool or longbool too, no?
+                  {This can be a wordbool or longbool too, no?}
                   if left.location.loc=LOC_CREGISTER then
                     cg.g_flags2reg(exprasmlist,def_cgsize(left.resulttype.def),right.location.resflags,left.location.register)
                   else
@@ -902,7 +914,7 @@ implementation
                        location_force_mem(exprasmlist,hp.left.location);
                        tmpreg:=cg.get_scratch_reg_address(exprasmlist);
                        cg.a_loadaddr_ref_reg(exprasmlist,hp.left.location.reference,tmpreg);
-                       cg.a_load_reg_ref(exprasmlist,cg.reg_cgsize(tmpreg),tmpreg,href);
+                       cg.a_load_reg_ref(exprasmlist,OS_ADDR,tmpreg,href);
                        cg.free_scratch_reg(exprasmlist,tmpreg);
                        location_release(exprasmlist,hp.left.location);
                        if freetemp then
@@ -960,7 +972,11 @@ begin
 end.
 {
   $Log$
-  Revision 1.44  2003-01-08 18:43:56  daniel
+  Revision 1.45  2003-02-19 22:00:14  daniel
+    * Code generator converted to new register notation
+    - Horribily outdated todo.txt removed
+
+  Revision 1.44  2003/01/08 18:43:56  daniel
    * Tregister changed into a record
 
   Revision 1.43  2003/01/05 22:44:14  peter

+ 10 - 6
compiler/ncgmat.pas

@@ -131,7 +131,7 @@ implementation
         else
         if _size <> OS_F32 then
            internalerror(20020814);
-        hreg := rg.getregisterint(exprasmlist);
+        hreg := rg.getregisterint(exprasmlist,OS_32);
         { load value }
         cg.a_load_ref_reg(exprasmlist,OS_32,href,hreg);
         { bitwise complement copied value }
@@ -181,7 +181,7 @@ implementation
                    end;
                  LOC_CREGISTER:
                    begin
-                      location.register:=rg.getregisterint(exprasmlist);
+                      location.register:=rg.getregisterint(exprasmlist,OS_INT);
                       cg.a_load_reg_reg(exprasmlist,OS_INT,OS_INT,left.location.register,
                         location.register);
                       cg.a_op_reg_reg(exprasmlist,OP_NEG,OS_INT,location.register,
@@ -202,7 +202,7 @@ implementation
                         end
                       else
                         begin
-                           location.register:=rg.getregisterint(exprasmlist);
+                           location.register:=rg.getregisterint(exprasmlist,OS_INT);
                            { why is the size is OS_INT, since in pass_1 we convert
                              everything to a signed natural value anyways
                            }
@@ -315,7 +315,7 @@ implementation
                   { hdenom is always free, it's }
                   { only used for temporary }
                   { purposes                }
-                  hdenom := rg.getregisterint(exprasmlist);
+                  hdenom := rg.getregisterint(exprasmlist,OS_INT);
                   if right.location.loc<>LOC_CREGISTER then
                    location_release(exprasmlist,right.location);
                   cg.a_load_loc_reg(exprasmlist,right.location,hdenom);
@@ -432,7 +432,7 @@ implementation
                      begin
                        if right.location.loc<>LOC_CREGISTER then
                         location_release(exprasmlist,right.location);
-                       hcountreg:=cg.get_scratch_reg_int(exprasmlist);
+                       hcountreg:=cg.get_scratch_reg_int(exprasmlist,OS_INT);
                        freescratch := true;
                        cg.a_load_loc_reg(exprasmlist,right.location,hcountreg);
                      end
@@ -454,7 +454,11 @@ begin
 end.
 {
   $Log$
-  Revision 1.5  2002-11-25 17:43:18  peter
+  Revision 1.6  2003-02-19 22:00:14  daniel
+    * Code generator converted to new register notation
+    - Horribily outdated todo.txt removed
+
+  Revision 1.5  2002/11/25 17:43:18  peter
     * splitted defbase in defutil,symutil,defcmp
     * merged isconvertable and is_equal into compare_defs(_ext)
     * made operator search faster by walking the list only once

+ 32 - 28
compiler/ncgmem.pas

@@ -347,18 +347,18 @@ implementation
 
     procedure tcgselfnode.pass_2;
       begin
-         rg.getexplicitregisterint(exprasmlist,SELF_POINTER_REG);
+         rg.getexplicitregisterint(exprasmlist,NR_SELF_POINTER_REG);
          if (resulttype.def.deftype=classrefdef) or
             (is_class(resulttype.def) or
              (po_staticmethod in aktprocdef.procoptions)) then
           begin
             location_reset(location,LOC_CREGISTER,OS_ADDR);
-            location.register.enum:=SELF_POINTER_REG;
+            location.register.number:=NR_SELF_POINTER_REG;
           end
          else
            begin
              location_reset(location,LOC_CREFERENCE,OS_ADDR);
-             location.reference.base.enum:=SELF_POINTER_REG;
+             location.reference.base.number:=NR_SELF_POINTER_REG;
            end;
       end;
 
@@ -387,7 +387,7 @@ implementation
                secondpass(left);
 {$ifdef i386}
                if (left.location.loc in [LOC_REFERENCE,LOC_CREFERENCE]) and
-                  (left.location.reference.segment.enum<>R_NO) then
+                  (left.location.reference.segment.number<>NR_NO) then
                  message(parser_e_no_with_for_variable_in_other_segments);
 {$endif i386}
 
@@ -407,7 +407,7 @@ implementation
                   usetemp:=true;
                   if is_class_or_interface(left.resulttype.def) then
                     begin
-                      tmpreg := cg.get_scratch_reg_int(exprasmlist);
+                      tmpreg := cg.get_scratch_reg_int(exprasmlist,OS_INT);
                       cg.a_load_loc_reg(exprasmlist,left.location,tmpreg)
                     end
                   else
@@ -560,7 +560,7 @@ implementation
          poslabel,
          neglabel : tasmlabel;
          hreg : tregister;
-         pushed : tpushedsaved;
+         pushed : tpushedsavedint;
        begin
          if is_open_array(left.resulttype.def) or
             is_array_of_const(left.resulttype.def) then
@@ -581,7 +581,7 @@ implementation
                  hreg:=right.location.register
                else
                  begin
-                   hreg := cg.get_scratch_reg_int(exprasmlist);
+                   hreg := cg.get_scratch_reg_int(exprasmlist,OS_INT);
                    freereg:=true;
                    cg.a_load_loc_reg(exprasmlist,right.location,hreg);
                  end;
@@ -602,12 +602,12 @@ implementation
          else
           if is_dynamic_array(left.resulttype.def) then
             begin
-               rg.saveusedregisters(exprasmlist,pushed,all_registers);
+               rg.saveusedintregisters(exprasmlist,pushed,all_intregisters);
                cg.a_param_loc(exprasmlist,right.location,paramanager.getintparaloc(2));
                cg.a_param_loc(exprasmlist,left.location,paramanager.getintparaloc(1));
-               rg.saveregvars(exprasmlist,all_registers);
+               rg.saveintregvars(exprasmlist,all_intregisters);
                cg.a_call_name(exprasmlist,'FPC_DYNARRAY_RANGECHECK');
-               rg.restoreusedregisters(exprasmlist,pushed);
+               rg.restoreusedintregisters(exprasmlist,pushed);
                cg.g_maybe_loadself(exprasmlist);
             end
          else
@@ -621,7 +621,7 @@ implementation
          extraoffset : longint;
          t : tnode;
          href : treference;
-         pushed : tpushedsaved;
+         pushed : tpushedsavedint;
          isjump  : boolean;
          otl,ofl : tasmlabel;
          newsize : tcgsize;
@@ -644,12 +644,12 @@ implementation
                         CGMessage(cg_e_illegal_expression);
                         exit;
                      end;
-                   rg.saveusedregisters(exprasmlist,pushed,all_registers);
+                   rg.saveusedintregisters(exprasmlist,pushed,all_intregisters);
                    cg.a_paramaddr_ref(exprasmlist,left.location.reference,paramanager.getintparaloc(1));
-                   rg.saveregvars(exprasmlist,all_registers);
-                   cg.a_call_name(exprasmlist,'FPC_'+Upper(tstringdef(left.resulttype.def).stringtypname)+'_UNIQUE');
+                   rg.saveintregvars(exprasmlist,all_intregisters);
+                   cg.a_call_name(exprasmlist,'FPC_'+upper(tstringdef(left.resulttype.def).stringtypname)+'_UNIQUE');
                    cg.g_maybe_loadself(exprasmlist);
-                   rg.restoreusedregisters(exprasmlist,pushed);
+                   rg.restoreusedintregisters(exprasmlist,pushed);
                 end;
 
               case left.location.loc of
@@ -660,7 +660,7 @@ implementation
                 LOC_REFERENCE :
                   begin
                     location_release(exprasmlist,left.location);
-                    location.reference.base:=rg.getregisterint(exprasmlist);
+                    location.reference.base:=rg.getregisterint(exprasmlist,OS_INT);
                     cg.a_load_ref_reg(exprasmlist,OS_ADDR,left.location.reference,location.reference.base);
                   end;
                 else
@@ -671,12 +671,12 @@ implementation
                 we can use the ansistring routine here }
               if (cs_check_range in aktlocalswitches) then
                 begin
-                   rg.saveusedregisters(exprasmlist,pushed,all_registers);
+                   rg.saveusedintregisters(exprasmlist,pushed,all_intregisters);
                    cg.a_param_reg(exprasmlist,OS_ADDR,location.reference.base,paramanager.getintparaloc(1));
-                   rg.saveregvars(exprasmlist,all_registers);
+                   rg.saveintregvars(exprasmlist,all_intregisters);
                    cg.a_call_name(exprasmlist,'FPC_'+Upper(tstringdef(left.resulttype.def).stringtypname)+'_CHECKZERO');
                    cg.g_maybe_loadself(exprasmlist);
-                   rg.restoreusedregisters(exprasmlist,pushed);
+                   rg.restoreusedintregisters(exprasmlist,pushed);
                 end;
 
               { in ansistrings/widestrings S[1] is p<w>char(S)[0] !! }
@@ -748,14 +748,14 @@ implementation
                          st_widestring,
                          st_ansistring:
                            begin
-                              rg.saveusedregisters(exprasmlist,pushed,all_registers);
+                              rg.saveusedintregisters(exprasmlist,pushed,all_intregisters);
                               cg.a_param_const(exprasmlist,OS_INT,tordconstnode(right).value,paramanager.getintparaloc(2));
                               href:=location.reference;
                               dec(href.offset,7);
                               cg.a_param_ref(exprasmlist,OS_INT,href,paramanager.getintparaloc(1));
-                              rg.saveregvars(exprasmlist,all_registers);
-                              cg.a_call_name(exprasmlist,'FPC_'+Upper(tstringdef(left.resulttype.def).stringtypname)+'_RANGECHECK');
-                              rg.restoreusedregisters(exprasmlist,pushed);
+                              rg.saveintregvars(exprasmlist,all_intregisters);
+                              cg.a_call_name(exprasmlist,'FPC_'+upper(tstringdef(left.resulttype.def).stringtypname)+'_RANGECHECK');
+                              rg.restoreusedintregisters(exprasmlist,pushed);
                               cg.g_maybe_loadself(exprasmlist);
                            end;
 
@@ -880,14 +880,14 @@ implementation
                          st_widestring,
                          st_ansistring:
                            begin
-                              rg.saveusedregisters(exprasmlist,pushed,all_registers);
+                              rg.saveusedintregisters(exprasmlist,pushed,all_intregisters);
                               cg.a_param_reg(exprasmlist,OS_INT,right.location.register,paramanager.getintparaloc(1));
                               href:=location.reference;
                               dec(href.offset,7);
                               cg.a_param_ref(exprasmlist,OS_INT,href,paramanager.getintparaloc(1));
-                              rg.saveregvars(exprasmlist,all_registers);
-                              cg.a_call_name(exprasmlist,'FPC_'+Upper(tstringdef(left.resulttype.def).stringtypname)+'_RANGECHECK');
-                              rg.restoreusedregisters(exprasmlist,pushed);
+                              rg.saveintregvars(exprasmlist,all_intregisters);
+                              cg.a_call_name(exprasmlist,'FPC_'+upper(tstringdef(left.resulttype.def).stringtypname)+'_RANGECHECK');
+                              rg.restoreusedintregisters(exprasmlist,pushed);
                               cg.g_maybe_loadself(exprasmlist);
                            end;
                          st_shortstring:
@@ -925,7 +925,11 @@ begin
 end.
 {
   $Log$
-  Revision 1.41  2003-01-30 21:46:57  peter
+  Revision 1.42  2003-02-19 22:00:14  daniel
+    * Code generator converted to new register notation
+    - Horribily outdated todo.txt removed
+
+  Revision 1.41  2003/01/30 21:46:57  peter
     * self fixes for static methods (merged)
 
   Revision 1.40  2003/01/08 18:43:56  daniel

+ 20 - 17
compiler/ncgset.pas

@@ -278,7 +278,7 @@ implementation
          { location is always LOC_JUMP }
          location_reset(location,LOC_REGISTER,OS_INT);
          { allocate a register for the result }
-         location.register := rg.getregisterint(exprasmlist);
+         location.register := rg.getregisterint(exprasmlist,OS_INT);
 
          if genjumps then
           begin
@@ -312,7 +312,7 @@ implementation
             else
              begin
                { load the value in a register }
-               pleftreg := cg.get_scratch_reg_int(exprasmlist);
+               pleftreg := cg.get_scratch_reg_int(exprasmlist,OS_INT);
                opsize := OS_INT;
                cg.a_load_ref_reg(exprasmlist,def_cgsize(left.resulttype.def),left.location.reference,pleftreg);
              end;
@@ -340,7 +340,7 @@ implementation
                       if (left.location.loc = LOC_CREGISTER) and
                          (hr.enum <> pleftreg.enum) then
                         begin
-                          hr:=cg.get_scratch_reg_int(exprasmlist);
+                          hr:=cg.get_scratch_reg_int(exprasmlist,OS_INT);
                           cg.a_op_const_reg_reg(exprasmlist,OP_SUB,opsize,setparts[i].start,pleftreg,hr);
                           pleftreg:=hr;
                           opsize := OS_INT;
@@ -412,7 +412,7 @@ implementation
                 begin
                   { clear the register value, indicating result is FALSE }
                   cg.a_load_const_reg(exprasmlist,OS_INT,0,location.register);
-                  hr:=cg.get_scratch_reg_int(exprasmlist);
+                  hr:=cg.get_scratch_reg_int(exprasmlist,OS_INT);
                   case right.location.loc of
                     LOC_REGISTER,
                     LOC_CREGISTER:
@@ -446,12 +446,12 @@ implementation
                        begin
                           hr3:=rg.makeregsize(left.location.register,OS_INT);
                           cg.a_load_reg_reg(exprasmlist,left.location.size,OS_INT,left.location.register,hr3);
-                          hr:=cg.get_scratch_reg_int(exprasmlist);
+                          hr:=cg.get_scratch_reg_int(exprasmlist,OS_INT);
                           cg.a_load_reg_reg(exprasmlist,OS_INT,OS_INT,hr3,hr);
                        end;
                   else
                     begin
-                      hr:=cg.get_scratch_reg_int(exprasmlist);
+                      hr:=cg.get_scratch_reg_int(exprasmlist,OS_INT);
                       cg.a_load_ref_reg(exprasmlist,def_cgsize(left.resulttype.def),
                          left.location.reference,hr);
                       location_release(exprasmlist,left.location);
@@ -466,7 +466,7 @@ implementation
                           end;
                    LOC_CONSTANT :
                        begin
-                         hr2:=rg.getregisterint(exprasmlist);
+                         hr2:=rg.getregisterint(exprasmlist,OS_32);
                          cg.a_load_const_reg(exprasmlist,OS_32,
                             right.location.value,hr2);
                        end;
@@ -474,7 +474,7 @@ implementation
                    LOC_REFERENCE :
                        begin
                          location_release(exprasmlist,right.location);
-                         hr2:=rg.getregisterint(exprasmlist);
+                         hr2:=rg.getregisterint(exprasmlist,OS_32);
                          cg.a_load_ref_reg(exprasmlist, OS_32,
                            right.location.reference,hr2);
                        end;
@@ -522,7 +522,7 @@ implementation
                           cg.a_label(exprasmlist,l);
                         { We have to load the value into a register because
                           btl does not accept values only refs or regs (PFV) }
-                          hr2:=rg.getregisterint(exprasmlist);
+                          hr2:=rg.getregisterint(exprasmlist,OS_INT);
                           cg.a_load_const_reg(exprasmlist,OS_INT,right.location.value,hr2);
                        end;
                      LOC_REFERENCE,LOC_CREFERENCE:
@@ -531,11 +531,11 @@ implementation
                           cg.a_jmp_always(exprasmlist,l2);
                           cg.a_label(exprasmlist,l);
                           location_release(exprasmlist,left.location);
-                          hr:=rg.getregisterint(exprasmlist);
+                          hr:=rg.getregisterint(exprasmlist,OS_32);
                           cg.a_load_ref_reg(exprasmlist,OS_32,left.location.reference,hr);
                         { We have to load the value into a register because
                           btl does not accept values only refs or regs (PFV) }
-                          hr2:=rg.getregisterint(exprasmlist);
+                          hr2:=rg.getregisterint(exprasmlist,OS_INT);
                           cg.a_load_const_reg(exprasmlist,OS_INT,
                             right.location.value,hr2);
                        end;
@@ -566,7 +566,7 @@ implementation
                   if (left.location.loc in [LOC_REGISTER,LOC_CREGISTER]) then
                     pleftreg:=rg.makeregsize(left.location.register,OS_INT)
                   else
-                    pleftreg:=rg.getregisterint(exprasmlist);
+                    pleftreg:=rg.getregisterint(exprasmlist,OS_INT);
                   cg.a_load_loc_reg(exprasmlist,left.location,pleftreg);
                   location_freetemp(exprasmlist,left.location);
                   location_release(exprasmlist,left.location);
@@ -683,7 +683,7 @@ implementation
            begin
               last:=0;
               first:=true;
-              scratch_reg := cg.get_scratch_reg_int(exprasmlist);
+              scratch_reg := cg.get_scratch_reg_int(exprasmlist,OS_INT);
               genitem(hp);
               cg.free_scratch_reg(exprasmlist,scratch_reg);
               cg.a_jmp_always(exprasmlist,elselabel);
@@ -875,8 +875,7 @@ implementation
          hp : tstatementnode;
       begin
          { Relabel for inlining? }
-         if inlining_procedure and
-            assigned(nodes) then
+         if inlining_procedure and assigned(nodes) then
           begin
             objectlibrary.CreateUsedAsmSymbolList;
             relabelcaserecord(nodes);
@@ -1013,7 +1012,7 @@ implementation
                 genlinearlist(nodes);
            end;
 
-         rg.ungetregister(exprasmlist,hregister);
+         rg.ungetregisterint(exprasmlist,hregister);
 
          { now generate the instructions }
          hp:=tstatementnode(right);
@@ -1064,7 +1063,11 @@ begin
 end.
 {
   $Log$
-  Revision 1.25  2003-01-08 18:43:56  daniel
+  Revision 1.26  2003-02-19 22:00:14  daniel
+    * Code generator converted to new register notation
+    - Horribily outdated todo.txt removed
+
+  Revision 1.25  2003/01/08 18:43:56  daniel
    * Tregister changed into a record
 
   Revision 1.24  2002/11/27 02:37:13  peter

+ 77 - 56
compiler/ncgutil.pas

@@ -47,7 +47,7 @@ interface
 
     procedure firstcomplex(p : tbinarynode);
     procedure maketojumpbool(list:TAAsmoutput; p : tnode; loadregvars: tloadregvars);
-    procedure remove_non_regvars_from_loc(const t: tlocation; var regs: tregisterset);
+    procedure remove_non_regvars_from_loc(const t: tlocation; var regs:Tsupregset);
 
     procedure location_force_reg(list: TAAsmoutput;var l:tlocation;dst_size:TCGSize;maybeconst:boolean);
     procedure location_force_mem(list: TAAsmoutput;var l:tlocation);
@@ -216,32 +216,32 @@ implementation
       end;
 
 
-    procedure remove_non_regvars_from_loc(const t: tlocation; var regs: tregisterset);
+    procedure remove_non_regvars_from_loc(const t: tlocation; var regs:Tsupregset);
       begin
         case t.loc of
           LOC_REGISTER:
             begin
               { can't be a regvar, since it would be LOC_CREGISTER then }
-              if t.register.enum>lastreg then
-                internalerror(200201081);
-              if t.registerhigh.enum>lastreg then
-                internalerror(200201081);
-              exclude(regs,t.register.enum);
+              if t.register.enum<>R_INTREGISTER then
+                internalerror(200301154);
+              if t.registerhigh.enum<>R_INTREGISTER then
+                internalerror(200301154);
+              exclude(regs,t.register.number shr 8);
               if t.registerhigh.enum <> R_NO then
-                exclude(regs,t.registerhigh.enum);
+                exclude(regs,t.registerhigh.number shr 8);
             end;
           LOC_CREFERENCE,LOC_REFERENCE:
             begin
-              if t.reference.base.enum>lastreg then
-                internalerror(200201081);
-              if t.reference.index.enum>lastreg then
-                internalerror(200201081);
+              if t.reference.base.enum<>R_INTREGISTER then
+                internalerror(200301154);
+              if t.reference.index.enum<>R_INTREGISTER then
+                internalerror(200301154);
               if not(cs_regalloc in aktglobalswitches) or
-                 (t.reference.base.enum in rg.usableregsint) then
-                exclude(regs,t.reference.base.enum);
+                 ((t.reference.base.number shr 8) in rg.usableregsint) then
+                exclude(regs,t.reference.base.number shr 8);
               if not(cs_regalloc in aktglobalswitches) or
-                 (t.reference.index.enum in rg.usableregsint) then
-              exclude(regs,t.reference.index.enum);
+                 ((t.reference.index.number shr 8) in rg.usableregsint) then
+                exclude(regs,t.reference.index.number);
             end;
         end;
       end;
@@ -309,11 +309,12 @@ implementation
               { load a smaller size to OS_64 }
               if l.loc=LOC_REGISTER then
                begin
-                 hregister:=rg.makeregsize(l.registerlow,OS_INT);
+                 hregister.enum:=R_INTREGISTER;
+                 hregister.number:=(l.registerlow.number and not $ff) or R_SUBWHOLE;
                  cg.a_load_reg_reg(list,l.size,OS_32,l.registerlow,hregister);
                end
               else
-               hregister:=rg.getregisterint(list);
+               hregister:=rg.getregisterint(list,OS_INT);
               { load value in low register }
               case l.loc of
                 LOC_FLAGS :
@@ -332,7 +333,7 @@ implementation
                   cg.a_load_loc_reg(list,l,hregister);
               end;
               { reset hi part, take care of the signed bit of the current value }
-              hregisterhi:=rg.getregisterint(list);
+              hregisterhi:=rg.getregisterint(list,OS_INT);
               if (dst_size=OS_S64) and
                  (l.size in [OS_S8,OS_S16,OS_S32]) then
                begin
@@ -366,8 +367,8 @@ implementation
                end
               else
                begin
-                 hregister:=rg.getregisterint(list);
-                 hregisterhi:=rg.getregisterint(list);
+                 hregister:=rg.getregisterint(list,OS_INT);
+                 hregisterhi:=rg.getregisterint(list,OS_INT);
                end;
               hreg64.reglo:=hregister;
               hreg64.reghi:=hregisterhi;
@@ -399,9 +400,11 @@ implementation
                  (TCGSize2Size[dst_size]=TCGSize2Size[l.size]) then
                hregister:=l.register
               else
-               hregister:=rg.getregisterint(list);
+               hregister:=rg.getregisterint(list,OS_INT);
             end;
-           hregister:=rg.makeregsize(hregister,dst_size);
+           if hregister.enum<>R_INTREGISTER then
+            internalerror(200302022);
+           hregister.number:=(hregister.number and not $ff) or cgsize2subreg(dst_size);
            { load value in new register }
            case l.loc of
              LOC_FLAGS :
@@ -424,7 +427,7 @@ implementation
                  if (TCGSize2Size[dst_size]<TCGSize2Size[l.size]) then
                   begin
                     if (l.loc in [LOC_REGISTER,LOC_CREGISTER]) then
-                     l.register:=rg.makeregsize(l.register,dst_size);
+                     l.register.number:=(l.register.number and not $ff) or cgsize2subreg(dst_size);
                     { for big endian systems, the reference's offset must }
                     { be increased in this case, since they have the      }
                     { MSB first in memory and e.g. byte(word_var) should  }
@@ -457,7 +460,7 @@ implementation
               if l.loc=LOC_REGISTER then
                hregister:=rg.makeregsize(l.register,OS_INT)
               else
-               hregister:=rg.getregisterint(list);
+               hregister:=rg.getregisterint(list,OS_INT);
               { load value in low register }
               case l.loc of
 {$ifdef cpuflags}
@@ -496,7 +499,7 @@ implementation
                  (TCGSize2Size[dst_size]=TCGSize2Size[l.size]) then
                hregister:=l.register
               else
-               hregister:=rg.getregisterint(list);
+               hregister:=rg.getregisterint(list,OS_INT);
             end;
            hregister:=rg.makeregsize(hregister,dst_size);
            { load value in new register }
@@ -533,6 +536,7 @@ implementation
                       inc(l.reference.offset,TCGSize2Size[l.size]-TCGSize2Size[dst_size]);
                     l.size:=dst_size;
                   end;
+                  
                  cg.a_load_loc_reg(list,l,hregister);
                end;
            end;
@@ -625,22 +629,24 @@ implementation
              LOC_REFERENCE,
              LOC_CREFERENCE :
                begin
-                 if l.reference.base.enum>lastreg then
-                   internalerror(200101081);
-                 if ((l.reference.base.enum<>R_NO) or
-                     (l.reference.index.enum<>R_NO)) then
+                 if l.reference.base.enum<>R_INTREGISTER then
+                   internalerror(200302101);
+                 if l.reference.index.enum<>R_INTREGISTER then
+                   internalerror(200302101);
+                 if ((l.reference.base.number<>NR_NO) or
+                     (l.reference.index.number<>NR_NO)) then
                   begin
                     { load address into a single base register }
-                    if l.reference.index.enum<>R_NO then
+                    if l.reference.index.number<>NR_NO then
                      begin
                        cg.a_loadaddr_ref_reg(list,l.reference,l.reference.index);
-                       rg.ungetregister(list,l.reference.base);
+                       rg.ungetregisterint(list,l.reference.base);
                        reference_reset_base(l.reference,l.reference.index,0);
                      end
                     else
                      begin
                        cg.a_loadaddr_ref_reg(list,l.reference,l.reference.base);
-                       rg.ungetregister(list,l.reference.index);
+                       rg.ungetregisterint(list,l.reference.index);
                        reference_reset_base(l.reference,l.reference.base,0);
                      end;
                     { save base register }
@@ -671,14 +677,14 @@ implementation
 {$ifndef cpu64bit}
               if l.size in [OS_64,OS_S64] then
                begin
-                 l.registerlow:=rg.getregisterint(exprasmlist);
-                 l.registerhigh:=rg.getregisterint(exprasmlist);
+                 l.registerlow:=rg.getregisterint(exprasmlist,OS_INT);
+                 l.registerhigh:=rg.getregisterint(exprasmlist,OS_INT);
                  cg64.a_load64_ref_reg(exprasmlist,s.ref,joinreg64(l.registerlow,l.registerhigh));
                end
               else
 {$endif cpu64bit}
                begin
-                 l.register:=rg.getregisterint(exprasmlist);
+                 l.register:=rg.getregisterint(exprasmlist,OS_INT);
                  cg.a_load_ref_reg(exprasmlist,OS_INT,s.ref,l.register);
                end;
             end;
@@ -812,7 +818,8 @@ implementation
               size:=align(p.resulttype.def.size,alignment);
               inc(pushedparasize,size);
               cg.g_stackpointer_alloc(exprasmlist,size);
-              r.enum:=stack_pointer_reg;
+              r.enum:=R_INTREGISTER;
+              r.number:=NR_STACK_POINTER_REG;
               reference_reset_base(href,r,0);
               cg.g_concatcopy(exprasmlist,p.location.reference,href,size,false,false);
 {$else i386}
@@ -865,8 +872,10 @@ implementation
                        { update register to use to match alignment }
                        if p.location.loc in [LOC_REGISTER,LOC_CREGISTER] then
                         begin
+                          if p.location.register.enum<>R_INTREGISTER then
+                            internalerror(200302024);
                           hreg:=p.location.register;
-                          p.location.register:=rg.makeregsize(p.location.register,cgsize);
+                          p.location.register.number:=(p.location.register.number and not $ff) or cgsize2subreg(cgsize);
                         end;
                        inc(pushedparasize,alignment);
                        if calloption=pocall_inline then
@@ -1161,7 +1170,8 @@ implementation
 {Here, we return the function result. In most architectures, the value is
 passed into the accumulator, but in a windowed architecure like sparc a
 function returns in a register and the caller receives it in an other one}
-                  r.enum:=return_result_reg;
+                  r.enum:=R_INTREGISTER;
+                  r.number:=NR_RETURN_RESULT_REG;
                   cg.a_reg_alloc(list,r);
 {$ifndef cpu64bit}
                  if cgsize in [OS_64,OS_S64] then
@@ -1169,8 +1179,10 @@ function returns in a register and the caller receives it in an other one}
                     uses_acchi:=true;
                     r.enum:=accumulatorhigh;
                     cg.a_reg_alloc(list,r);
-                    r.enum:=accumulator;
-                    r2.enum:=accumulatorhigh;
+                    r.enum:=R_INTREGISTER;
+                    r.number:=NR_ACCUMULATOR;
+                    r2.enum:=R_INTREGISTER;
+                    r2.number:=NR_ACCUMULATORHIGH;
                     cg64.a_load64_ref_reg(list,href,joinreg64(r,r2));
                   end
                  else
@@ -1180,8 +1192,8 @@ function returns in a register and the caller receives it in an other one}
 {Here, we return the function result. In most architectures, the value is
 passed into the accumulator, but in a windowed architecure like sparc a
 function returns in a register and the caller receives it in an other one}
-                    r.enum:=return_result_reg;
-                    hreg:=rg.makeregsize(r,cgsize);
+                    hreg.enum:=R_INTREGISTER;
+                    hreg.number:=RS_RETURN_RESULT_REG shl 8 or cgsize2subreg(cgsize);
                     cg.a_load_ref_reg(list,cgsize,href,hreg);
                   end;
                end;
@@ -1201,7 +1213,8 @@ function returns in a register and the caller receives it in an other one}
                  if paramanager.ret_in_acc(aktprocdef.rettype.def,aktprocdef.proccalloption) then
                   begin
                     uses_acc:=true;
-                    r.enum:=accumulator;
+                    r.enum:=R_INTREGISTER;
+                    r.number:=NR_RETURN_RESULT_REG;
                     cg.a_reg_alloc(list,r);
 {$ifndef cpu64bit}
                     { Win32 can return records in EAX:EDX }
@@ -1210,13 +1223,16 @@ function returns in a register and the caller receives it in an other one}
                        uses_acchi:=true;
                        r.enum:=accumulatorhigh;
                        cg.a_reg_alloc(list,r);
-                       r.enum:=accumulator;
-                       r2.enum:=accumulatorhigh;
+                       r.enum:=R_INTREGISTER;
+                       r.number:=NR_ACCUMULATOR;
+                       r2.enum:=R_INTREGISTER;
+                       r2.number:=NR_ACCUMULATORHIGH;
                        cg64.a_load64_ref_reg(list,href,joinreg64(r,r2));
                      end
                     else
 {$endif cpu64bit}
-                     r.enum:=accumulator;
+                     r.enum:=R_INTREGISTER;
+                     r.number:=NR_ACCUMULATOR;
                      cg.a_load_ref_reg(list,cgsize,href,r);
                    end
                end;
@@ -1303,7 +1319,7 @@ function returns in a register and the caller receives it in an other one}
         else
          { should we save edi,esi,ebx like C ? }
          if (po_savestdregs in aktprocdef.procoptions) then
-           cg.g_save_standard_registers(list,aktprocdef.usedregisters);
+           cg.g_save_standard_registers(list,aktprocdef.usedintregisters);
 
         { the actual profile code can clobber some registers,
           therefore if the context must be saved, do it before
@@ -1339,7 +1355,8 @@ function returns in a register and the caller receives it in an other one}
           we must load it into ESI }
         If (po_containsself in aktprocdef.procoptions) then
           begin
-             r.enum:=self_pointer_reg;
+             r.enum:=R_INTREGISTER;
+             r.number:=NR_SELF_POINTER_REG;
              list.concat(tai_regalloc.Alloc(r));
              reference_reset_base(href,procinfo.framepointer,procinfo.selfpointer_offset);
              cg.a_load_ref_reg(list,OS_ADDR,href,r);
@@ -1548,9 +1565,7 @@ function returns in a register and the caller receives it in an other one}
 {$ifndef powerpc}
            { at least for the ppc this applies always, so this code isn't usable (FK) }
            { omit stack frame ? }
-           if procinfo.framepointer.enum>lastreg then
-              internalerror(2003010801);
-           if (procinfo.framepointer.enum=STACK_POINTER_REG) then
+           if (procinfo.framepointer.number=NR_STACK_POINTER_REG) then
             begin
               CGMessage(cg_d_stackframe_omited);
               nostackframe:=true;
@@ -1655,7 +1670,8 @@ function returns in a register and the caller receives it in an other one}
            not(aktprocdef.proctypeoption in [potype_unitfinalize,potype_unitinit]) then
           begin
              { the exception helper routines modify all registers }
-             aktprocdef.usedregisters:=all_registers;
+             aktprocdef.usedintregisters:=all_intregisters;
+             aktprocdef.usedotherregisters:=all_registers;
              objectlibrary.getlabel(noreraiselabel);
              free_exception(list,
                   procinfo.exception_jmp_ref,
@@ -1676,7 +1692,8 @@ function returns in a register and the caller receives it in an other one}
                             objectlibrary.getlabel(nodestroycall);
                             reference_reset_base(href,procinfo.framepointer,procinfo.selfpointer_offset);
                             cg.a_cmp_const_ref_label(list,OS_ADDR,OC_EQ,0,href,nodestroycall);
-                            r.enum:=self_pointer_reg;
+                            r.enum:=R_INTREGISTER;
+                            r.number:=NR_SELF_POINTER_REG;
                             if is_class(procinfo._class) then
                              begin
                                cg.a_param_const(list,OS_INT,1,paramanager.getintparaloc(2));
@@ -1800,7 +1817,7 @@ function returns in a register and the caller receives it in an other one}
         else
          { should we restore edi ? }
          if (po_savestdregs in aktprocdef.procoptions) then
-           cg.g_restore_standard_registers(list,aktprocdef.usedregisters);
+           cg.g_restore_standard_registers(list,aktprocdef.usedintregisters);
 
         { remove stackframe }
         if not inlined then
@@ -1974,7 +1991,11 @@ function returns in a register and the caller receives it in an other one}
 end.
 {
   $Log$
-  Revision 1.76  2003-02-15 22:17:38  carl
+  Revision 1.77  2003-02-19 22:00:14  daniel
+    * Code generator converted to new register notation
+    - Horribily outdated todo.txt removed
+
+  Revision 1.76  2003/02/15 22:17:38  carl
    * bugfix of FPU emulation code
 
   Revision 1.75  2003/01/09 22:00:53  florian

+ 7 - 2
compiler/pmodules.pas

@@ -732,7 +732,8 @@ implementation
          begin
            _class:=nil;
            para_offset:=target_info.first_parm_offset;
-           framepointer.enum:=FRAME_POINTER_REG;
+           framepointer.enum:=R_INTREGISTER;
+           framepointer.number:=NR_FRAME_POINTER_REG;
            flags:=0;
            procdef:=aktprocdef;
          end;
@@ -1444,7 +1445,11 @@ So, all parameters are passerd into registers in sparc architecture.}
 end.
 {
   $Log$
-  Revision 1.95  2003-02-06 22:36:55  mazen
+  Revision 1.96  2003-02-19 22:00:14  daniel
+    * Code generator converted to new register notation
+    - Horribily outdated todo.txt removed
+
+  Revision 1.95  2003/02/06 22:36:55  mazen
   * fixing bug related to errornous program main entry stack frame
 
   Revision 1.94  2003/01/30 21:46:20  peter

+ 21 - 17
compiler/powerpc/cgcpu.pas

@@ -90,8 +90,8 @@ unit cgcpu;
         { that's the case, we can use rlwinm to do an AND operation        }
         function get_rlwi_const(a: aword; var l1, l2: longint): boolean;
 
-        procedure g_save_standard_registers(list : taasmoutput; usedinproc : tregisterset);override;
-        procedure g_restore_standard_registers(list : taasmoutput; usedinproc : tregisterset);override;
+        procedure g_save_standard_registers(list : taasmoutput; usedinproc : Tsupregset);override;
+        procedure g_restore_standard_registers(list : taasmoutput; usedinproc : Tsupregset);override;
         procedure g_save_all_registers(list : taasmoutput);override;
         procedure g_restore_all_registers(list : taasmoutput;selfused,accused,acchiused:boolean);override;
 
@@ -194,7 +194,7 @@ const
                reference_reset(ref);
                ref.base:=locpara.reference.index;
                ref.offset:=locpara.reference.offset;
-               tmpreg := get_scratch_reg_int(list);
+               tmpreg := get_scratch_reg_int(list,size);
                a_load_ref_reg(list,size,r,tmpreg);
                a_load_reg_ref(list,size,tmpreg,ref);
                free_scratch_reg(list,tmpreg);
@@ -269,7 +269,7 @@ const
             {Generate instruction to load the procedure address from
             the transition vector.}
             //TODO: Support cross-TOC calls.
-            tmpreg := get_scratch_reg_int(list);
+            tmpreg := get_scratch_reg_int(list,OS_INT);
             reference_reset(tmpref);
             tmpref.offset := 0;
             //tmpref.symaddr := refs_full;
@@ -297,7 +297,7 @@ const
         tmpref : treference;
 
       begin
-        tmpreg := get_scratch_reg_int(list);
+        tmpreg := get_scratch_reg_int(list,OS_ADDR);
         a_load_ref_reg(list,OS_ADDR,ref,tmpreg);
         if target_info.system=system_powerpc_macos then
           begin
@@ -655,7 +655,7 @@ const
             if gotrlwi and
                (src.enum = dst.enum) then
               begin
-                scratchreg := get_scratch_reg_int(list);
+                scratchreg := get_scratch_reg_int(list,OS_INT);
                 list.concat(taicpu.op_reg_const(A_LI,scratchreg,-1));
                 list.concat(taicpu.op_reg_reg_const_const_const(A_RLWIMI,dst,
                   scratchreg,0,l1,l2));
@@ -687,7 +687,7 @@ const
         { perform the operation                                        }
         if useReg then
           begin
-            scratchreg := get_scratch_reg_int(list);
+            scratchreg := get_scratch_reg_int(list,OS_INT);
             a_load_const_reg(list,OS_32,a,scratchreg);
             a_op_reg_reg_reg(list,op,OS_32,scratchreg,src,dst);
             free_scratch_reg(list,scratchreg);
@@ -737,7 +737,7 @@ const
               list.concat(taicpu.op_reg_reg_const(A_CMPWI,r,reg,longint(a)))
             else
               begin
-                scratch_register := get_scratch_reg_int(list);
+                scratch_register := get_scratch_reg_int(list,OS_INT);
                 a_load_const_reg(list,OS_32,a,scratch_register);
                 list.concat(taicpu.op_reg_reg_reg(A_CMPW,r,reg,scratch_register));
                 free_scratch_reg(list,scratch_register);
@@ -747,7 +747,7 @@ const
               list.concat(taicpu.op_reg_reg_const(A_CMPLWI,r,reg,a))
             else
               begin
-                scratch_register := get_scratch_reg_int(list);
+                scratch_register := get_scratch_reg_int(list,OS_32);
                 a_load_const_reg(list,OS_32,a,scratch_register);
                 list.concat(taicpu.op_reg_reg_reg(A_CMPLW,r,reg,scratch_register));
                 free_scratch_reg(list,scratch_register);
@@ -774,12 +774,12 @@ const
         end;
 
 
-     procedure tcgppc.g_save_standard_registers(list : taasmoutput; usedinproc : tregisterset);
+     procedure tcgppc.g_save_standard_registers(list : taasmoutput; usedinproc : Tsupregset);
        begin
          {$warning FIX ME}
        end;
 
-     procedure tcgppc.g_restore_standard_registers(list : taasmoutput; usedinproc : tregisterset);
+     procedure tcgppc.g_restore_standard_registers(list : taasmoutput; usedinproc : Tsupregset);
        begin
          {$warning FIX ME}
        end;
@@ -1647,7 +1647,7 @@ const
             inc(src.offset,8);
             list.concat(taicpu.op_reg_reg_const(A_SUBI,src.base,src.base,8));
             list.concat(taicpu.op_reg_reg_const(A_SUBI,dst.base,dst.base,8));
-            countreg := get_scratch_reg_int(list);
+            countreg := get_scratch_reg_int(list,OS_INT);
             a_load_const_reg(list,OS_32,count,countreg);
             { explicitely allocate R_0 since it can be used safely here }
             { (for holding date that's being copied)                    }
@@ -1778,7 +1778,7 @@ const
                 ((ref.offset <> 0) or assigned(ref.symbol)) then
                begin
                  result := true;
-                 tmpreg := cg.get_scratch_reg_int(list);
+                 tmpreg := cg.get_scratch_reg_int(list,OS_INT);
                  if not assigned(ref.symbol) and
                     (cardinal(ref.offset-low(smallint)) <=
                       high(smallint)-low(smallint)) then
@@ -2070,7 +2070,7 @@ const
                     end
                   else if ((value shr 32) = 0) then
                     begin
-                      tmpreg := cg.get_scratch_reg_int(list);
+                      tmpreg := cg.get_scratch_reg_int(list,OS_32);
                       cg.a_load_const_reg(list,OS_32,cardinal(value),tmpreg);
                       list.concat(taicpu.op_reg_reg_reg(ops[issub,2],
                         regdst.reglo,regsrc.reglo,tmpreg));
@@ -2080,8 +2080,8 @@ const
                     end
                   else
                     begin
-                      tmpreg64.reglo := cg.get_scratch_reg_int(list);
-                      tmpreg64.reghi := cg.get_scratch_reg_int(list);
+                      tmpreg64.reglo := cg.get_scratch_reg_int(list,OS_INT);
+                      tmpreg64.reghi := cg.get_scratch_reg_int(list,OS_INT);
                       a_load64_const_reg(list,value,tmpreg64);
                       a_op64_reg_reg_reg(list,op,tmpreg64,regsrc,regdst);
                       cg.free_scratch_reg(list,tmpreg64.reghi);
@@ -2107,7 +2107,11 @@ begin
 end.
 {
   $Log$
-  Revision 1.70  2003-01-13 17:17:50  olle
+  Revision 1.71  2003-02-19 22:00:16  daniel
+    * Code generator converted to new register notation
+    - Horribily outdated todo.txt removed
+
+  Revision 1.70  2003/01/13 17:17:50  olle
     * changed global var access, TOC now contain pointers to globals
     * fixed handling of function pointers
 

+ 57 - 7
compiler/powerpc/cpubase.pas

@@ -115,13 +115,18 @@ uses
         R_INTREGISTER {Only for use by the register allocator.}
       );
 
+      Tnewregister=word;
+      Tsuperregister=byte;
+      Tsubregister=byte;
+
       Tregister=record
         enum:Toldregister;
-        number:word;
+        number:Tnewregister;
       end;
 
       {# Set type definition for registers }
       tregisterset = set of Toldregister;
+      Tsupregset=set of Tsuperregister;
 
       { A type to store register locations for 64 Bit values. }
       tregister64 = packed record
@@ -213,6 +218,26 @@ uses
       NR_R27 = $1C00; NR_R28 = $1D00; NR_R29 = $1E00;
       NR_R30 = $1F00; NR_R31 = $2000;
 
+    {Super registers:}
+      RS_R0 = $01; RS_R1 = $02; RS_R2 = $03;
+      RS_R3 = $04; RS_R4 = $05; RS_R5 = $06;
+      RS_R6 = $07; RS_R7 = $08; RS_R8 = $09;
+      RS_R9 = $0A; RS_R10 = $0B; RS_R11 = $0C;
+      RS_R12 = $0D; RS_R13 = $0E; RS_R14 = $0F;
+      RS_R15 = $10; RS_R16 = $11; RS_R17 = $12;
+      RS_R18 = $13; RS_R19 = $14; RS_R20 = $15;
+      RS_R21 = $16; RS_R22 = $17; RS_R23 = $18;
+      RS_R24 = $19; RS_R25 = $1A; RS_R26 = $1B;
+      RS_R27 = $1C; RS_R28 = $1D; RS_R29 = $1E;
+      RS_R30 = $1F; RS_R31 = $20;
+
+      first_supreg = $00;
+      last_supreg = $20;
+
+    {Subregisters, situation unknown!!.}
+      R_SUBWHOLE=$00;
+      R_SUBL=$00;
+
 
 {*****************************************************************************
                                 Conditions
@@ -473,8 +498,10 @@ uses
       {# Constant defining possibly all registers which might require saving }
 {$warning FIX ME !!!!!!!!! }
       ALL_REGISTERS = [R_0..R_FPSCR];
+      ALL_INTREGISTERS = [1..255];
 
       general_registers = [R_0..R_31];
+      general_superregisters = [RS_R0..RS_R31];
 
       {# low and high of the available maximum width integer general purpose }
       { registers                                                            }
@@ -500,7 +527,7 @@ uses
 
       maxintregs = 18;
       intregs    = [R_0..R_31];
-      usableregsint = [R_13..R_27];
+      usableregsint = [RS_R13..RS_R27];
       c_countusableregsint = 18;
 
       maxfpuregs = 31-14+1;
@@ -519,8 +546,8 @@ uses
       c_countusableregsaddr = 0;
       
 
-      firstsaveintreg = R_13;
-      lastsaveintreg  = R_27;
+      firstsaveintreg = RS_R13;
+      lastsaveintreg  = RS_R27;
       firstsavefpureg = R_F14;
       lastsavefpureg  = R_F31;
       { no altivec support yet. Need to override tcgobj.a_loadmm_* first in tcgppc }
@@ -553,7 +580,7 @@ uses
          routine calls or in assembler blocks.
       }
       max_scratch_regs = 3;
-      scratch_regs: Array[1..max_scratch_regs] of Toldregister = (R_28,R_29,R_30);
+      scratch_regs: Array[1..max_scratch_regs] of Tsuperregister = (RS_R28,RS_R29,RS_R30);
 
 {*****************************************************************************
                           Default generic sizes
@@ -631,11 +658,17 @@ uses
 
       {# Stack pointer register }
       stack_pointer_reg = R_1;
+      NR_STACK_POINTER_REG = NR_R1;
+      RS_STACK_POINTER_REG = RS_R1;
       {# Frame pointer register }
       frame_pointer_reg = stack_pointer_reg;
+      NR_FRAME_POINTER_REG = NR_STACK_POINTER_REG;
+      RS_FRAME_POINTER_REG = RS_STACK_POINTER_REG;
       {# Self pointer register : contains the instance address of an
          object or class. }
       self_pointer_reg  = R_9;
+      NR_SELF_POINTER_REG = NR_R9;
+      RS_SELF_POINTER_REG = RS_R9;
       {# Register for addressing absolute data in a position independant way,
          such as in PIC code. The exact meaning is ABI specific. For
          further information look at GCC source : PIC_OFFSET_TABLE_REGNUM
@@ -646,16 +679,22 @@ uses
       pic_offset_reg = R_30;
       {# Results are returned in this register (32-bit values) }
       accumulator   = R_3;
+      NR_ACCUMULATOR = NR_R3;
+      RS_ACCUMULATOR = RS_R3;
   {the return_result_reg, is used inside the called function to store its return
   value when that is a scalar value otherwise a pointer to the address of the
   result is placed inside it}
         return_result_reg               =       accumulator;
+      NR_RETURN_RESULT_REG = NR_ACCUMULATOR;
+      RS_RETURN_RESULT_REG = RS_ACCUMULATOR;
 
   {the function_result_reg contains the function result after a call to a scalar
   function othewise it contains a pointer to the returned result}
         function_result_reg     =       accumulator;
       {# Hi-Results are returned in this register (64-bit value high register) }
       accumulatorhigh = R_4;
+      NR_ACCUMULATORHIGH = NR_R4;
+      RS_ACCUMULATORHIGH = RS_R4;
       { WARNING: don't change to R_ST0!! See comments above implementation of }
       { a_loadfpu* methods in rgcpu (JM)                                      }
       fpu_result_reg = R_F1;
@@ -672,7 +711,7 @@ uses
          This value can be deduced from CALLED_USED_REGISTERS array in the
          GCC source.
       }
-      std_saved_registers = [R_13..R_29];
+      std_saved_registers = [RS_R13..RS_R29];
       {# Required parameter alignment when calling a routine declared as
          stdcall and cdecl. The alignment value should be the one defined
          by GCC or the target ABI.
@@ -708,6 +747,7 @@ uses
     procedure create_cond_imm(BO,BI:byte;var r : TAsmCond);
     procedure create_cond_norm(cond: TAsmCondFlag; cr: byte;var r : TasmCond);
     procedure convert_register_to_enum(var r:Tregister);
+    function cgsize2subreg(s:Tcgsize):Tsubregister;
 
 implementation
 
@@ -825,10 +865,20 @@ implementation
         end;
     end;
 
+    function cgsize2subreg(s:Tcgsize):Tsubregister;
+
+    begin
+      cgsize2subreg:=R_SUBWHOLE;
+    end;
+
 end.
 {
   $Log$
-  Revision 1.43  2003-02-02 19:25:54  carl
+  Revision 1.44  2003-02-19 22:00:16  daniel
+    * Code generator converted to new register notation
+    - Horribily outdated todo.txt removed
+
+  Revision 1.43  2003/02/02 19:25:54  carl
     * Several bugfixes for m68k target (register alloc., opcode emission)
     + VIS target
     + Generic add more complete (still not verified)

+ 26 - 22
compiler/powerpc/nppcadd.pas

@@ -245,7 +245,7 @@ interface
             else
               begin
                 useconst := false;
-                tmpreg := cg.get_scratch_reg_int(exprasmlist);
+                tmpreg := cg.get_scratch_reg_int(exprasmlist,OS_INT);
                 cg.a_load_const_reg(exprasmlist,OS_INT,
                   aword(right.location.value),tmpreg);
                end
@@ -563,7 +563,7 @@ interface
 
         if not(cmpop) and
            (location.register.enum = R_NO) then
-          location.register := rg.getregisterint(exprasmlist);
+          location.register := rg.getregisterint(exprasmlist,OS_INT);
 
         case nodetype of
           addn :
@@ -582,7 +582,7 @@ interface
                       left.location.register,location.register)
                   else
                     begin
-                      tmpreg := cg.get_scratch_reg_int(exprasmlist);
+                      tmpreg := cg.get_scratch_reg_int(exprasmlist,OS_INT);
                       cg.a_load_const_reg(exprasmlist,OS_INT,1,tmpreg);
                       cg.a_op_reg_reg(exprasmlist,OP_SHL,OS_INT,
                         right.location.register,tmpreg);
@@ -622,7 +622,7 @@ interface
                 begin
                   if left.location.loc = LOC_CONSTANT then
                     begin
-                      tmpreg := cg.get_scratch_reg_int(exprasmlist);
+                      tmpreg := cg.get_scratch_reg_int(exprasmlist,OS_INT);
                       cg.a_load_const_reg(exprasmlist,OS_INT,
                         aword(left.location.value),tmpreg);
                       exprasmlist.concat(taicpu.op_reg_reg_reg(A_ANDC,
@@ -649,7 +649,7 @@ interface
                   (nodetype = gten)) then
                 swapleftright;
               // now we have to check whether left >= right
-              tmpreg := cg.get_scratch_reg_int(exprasmlist);
+              tmpreg := cg.get_scratch_reg_int(exprasmlist,OS_INT);
               if left.location.loc = LOC_CONSTANT then
                 begin
                   cg.a_op_const_reg_reg(exprasmlist,OP_AND,OS_INT,
@@ -897,11 +897,11 @@ interface
                       else
                         begin
                           if (aword(right.location.valueqword) <> 0) then
-                            tempreg64.reglo := cg.get_scratch_reg_int(exprasmlist)
+                            tempreg64.reglo := cg.get_scratch_reg_int(exprasmlist,OS_INT)
                           else
                             tempreg64.reglo := left.location.registerlow;
                           if ((right.location.valueqword shr 32) <> 0) then
-                            tempreg64.reghi := cg.get_scratch_reg_int(exprasmlist)
+                            tempreg64.reghi := cg.get_scratch_reg_int(exprasmlist,OS_INT)
                           else
                             tempreg64.reghi := left.location.registerhigh;
                         end;
@@ -932,8 +932,8 @@ interface
                     end
                   else
                     begin
-                       tempreg64.reglo := cg.get_scratch_reg_int(exprasmlist);
-                       tempreg64.reghi := cg.get_scratch_reg_int(exprasmlist);
+                       tempreg64.reglo := cg.get_scratch_reg_int(exprasmlist,OS_INT);
+                       tempreg64.reghi := cg.get_scratch_reg_int(exprasmlist,OS_INT);
                        cg64.a_op64_reg_reg_reg(exprasmlist,OP_XOR,
                          left.location.register64,right.location.register64,
                          tempreg64);
@@ -956,8 +956,8 @@ interface
                 begin
                   if (location.registerlow.enum = R_NO) then
                     begin
-                      location.registerlow := rg.getregisterint(exprasmlist);
-                      location.registerhigh := rg.getregisterint(exprasmlist);
+                      location.registerlow := rg.getregisterint(exprasmlist,OS_INT);
+                      location.registerhigh := rg.getregisterint(exprasmlist,OS_INT);
                     end;
 
                   if (left.location.loc = LOC_CONSTANT) then
@@ -978,8 +978,8 @@ interface
                     begin
                       if (location.registerlow.enum = R_NO) then
                         begin
-                         location.registerlow := rg.getregisterint(exprasmlist);
-                         location.registerhigh := rg.getregisterint(exprasmlist);
+                         location.registerlow := rg.getregisterint(exprasmlist,OS_INT);
+                         location.registerhigh := rg.getregisterint(exprasmlist,OS_INT);
                       end;
                       if right.location.loc <> LOC_CONSTANT then
                         // reg64 - reg64
@@ -996,8 +996,8 @@ interface
                     begin
                       if (location.registerlow.enum = R_NO) then
                         begin
-                         location.registerlow := rg.getregisterint(exprasmlist);
-                         location.registerhigh := rg.getregisterint(exprasmlist);
+                         location.registerlow := rg.getregisterint(exprasmlist,OS_INT);
+                         location.registerhigh := rg.getregisterint(exprasmlist,OS_INT);
                       end;
                       if (int64(left.location.valueqword) >= low(smallint)) and
                          (int64(left.location.valueqword) <= high(smallint)) then
@@ -1024,8 +1024,8 @@ interface
                       // (const32 shl 32) - reg64
                       if (location.registerlow.enum = R_NO) then
                         begin
-                         location.registerlow := rg.getregisterint(exprasmlist);
-                         location.registerhigh := rg.getregisterint(exprasmlist);
+                         location.registerlow := rg.getregisterint(exprasmlist,OS_INT);
+                         location.registerhigh := rg.getregisterint(exprasmlist,OS_INT);
                       end;
                       exprasmlist.concat(taicpu.op_reg_reg_const(A_SUBFIC,
                         location.registerlow,right.location.registerlow,0));
@@ -1044,8 +1044,8 @@ interface
                         location.register64 := left.location.register64
                       else if (location.registerlow.enum = R_NO) then
                         begin
-                         location.registerlow := rg.getregisterint(exprasmlist);
-                         location.registerhigh := rg.getregisterint(exprasmlist);
+                         location.registerlow := rg.getregisterint(exprasmlist,OS_INT);
+                         location.registerhigh := rg.getregisterint(exprasmlist,OS_INT);
                         end;
                       cg64.a_op64_reg_reg_reg(exprasmlist,OP_SUB,
                         right.location.register64,left.location.register64,
@@ -1370,7 +1370,7 @@ interface
 
          if (location.register.enum = R_NO) and
             not(cmpop) then
-           location.register := rg.getregisterint(exprasmlist);
+           location.register := rg.getregisterint(exprasmlist,OS_INT);
 
          if not(cs_check_overflow in aktlocalswitches) or
             (cmpop) or
@@ -1428,7 +1428,7 @@ interface
                        end
                      else
                        begin
-                         tmpreg := cg.get_scratch_reg_int(exprasmlist);
+                         tmpreg := cg.get_scratch_reg_int(exprasmlist,OS_INT);
                          cg.a_load_const_reg(exprasmlist,OS_INT,
                            aword(left.location.value),tmpreg);
                          cg.a_op_reg_reg_reg(exprasmlist,OP_SUB,OS_INT,
@@ -1468,7 +1468,11 @@ begin
 end.
 {
   $Log$
-  Revision 1.21  2003-01-08 18:43:58  daniel
+  Revision 1.22  2003-02-19 22:00:16  daniel
+    * Code generator converted to new register notation
+    - Horribily outdated todo.txt removed
+
+  Revision 1.21  2003/01/08 18:43:58  daniel
    * Tregister changed into a record
 
   Revision 1.20  2002/11/25 17:43:27  peter

+ 11 - 7
compiler/powerpc/nppccnv.pas

@@ -189,7 +189,7 @@ implementation
               leftreg := left.location.register;
               if signed then
                 begin
-                  valuereg := cg.get_scratch_reg_int(exprasmlist);
+                  valuereg := cg.get_scratch_reg_int(exprasmlist,OS_INT);
                   valuereg_is_scratch := true;
                 end
               else
@@ -197,7 +197,7 @@ implementation
             end;
           LOC_REFERENCE,LOC_CREFERENCE:
             begin
-              leftreg := cg.get_scratch_reg_int(exprasmlist);
+              leftreg := cg.get_scratch_reg_int(exprasmlist,OS_INT);
               valuereg := leftreg;
               valuereg_is_scratch := true;
               cg.a_load_ref_reg(exprasmlist,def_cgsize(left.resulttype.def),
@@ -206,7 +206,7 @@ implementation
           else
             internalerror(200110012);
          end;
-         tempreg := cg.get_scratch_reg_int(exprasmlist);
+         tempreg := cg.get_scratch_reg_int(exprasmlist,OS_INT);
          exprasmlist.concat(taicpu.op_reg_const(A_LIS,tempreg,$4330));
          cg.a_load_reg_ref(exprasmlist,OS_32,tempreg,ref);
          cg.free_scratch_reg(exprasmlist,tempreg);
@@ -287,13 +287,13 @@ implementation
                 if left.location.loc in [LOC_CREFERENCE,LOC_REFERENCE] then
                   begin
                     reference_release(exprasmlist,left.location.reference);
-                    hreg2:=rg.getregisterint(exprasmlist);
+                    hreg2:=rg.getregisterint(exprasmlist,OS_INT);
                     cg.a_load_ref_reg(exprasmlist,opsize,
                       left.location.reference,hreg2);
                   end
                 else
                   hreg2 := left.location.register;
-                hreg1 := rg.getregisterint(exprasmlist);
+                hreg1 := rg.getregisterint(exprasmlist,OS_INT);
                 exprasmlist.concat(taicpu.op_reg_reg_const(A_SUBIC,hreg1,
                   hreg2,1));
                 exprasmlist.concat(taicpu.op_reg_reg_reg(A_SUBFE,hreg1,hreg1,
@@ -302,7 +302,7 @@ implementation
               end;
             LOC_FLAGS :
               begin
-                hreg1:=rg.getregisterint(exprasmlist);
+                hreg1:=rg.getregisterint(exprasmlist,OS_INT);
                 resflags:=left.location.resflags;
                 cg.g_flags2reg(exprasmlist,location.size,resflags,hreg1);
               end;
@@ -394,7 +394,11 @@ begin
 end.
 {
   $Log$
-  Revision 1.28  2002-12-05 14:28:13  florian
+  Revision 1.29  2003-02-19 22:00:16  daniel
+    * Code generator converted to new register notation
+    - Horribily outdated todo.txt removed
+
+  Revision 1.28  2002/12/05 14:28:13  florian
     * some variant <-> dyn. array stuff
 
   Revision 1.27  2002/11/25 17:43:28  peter

+ 19 - 13
compiler/powerpc/nppcmat.pas

@@ -78,6 +78,7 @@ implementation
          divider,
          resultreg  : tregister;
          saved      : tmaybesave;
+         size       : Tcgsize;
 
       begin
          secondpass(left);
@@ -87,20 +88,21 @@ implementation
          location_copy(location,left.location);
 
          { put numerator in register }
+         size:=def_cgsize(left.resulttype.def);
          location_force_reg(exprasmlist,left.location,
-           def_cgsize(left.resulttype.def),true);
+           size,true);
          location_copy(location,left.location);
          numerator := location.register;
          resultreg := location.register;
          if (location.loc = LOC_CREGISTER) then
            begin
              location.loc := LOC_REGISTER;
-             location.register := rg.getregisterint(exprasmlist);
+             location.register := rg.getregisterint(exprasmlist,size);
              resultreg := location.register;
            end;
          if (nodetype = modn) then
            begin
-             resultreg := cg.get_scratch_reg_int(exprasmlist);
+             resultreg := cg.get_scratch_reg_int(exprasmlist,size);
            end;
 
          if (nodetype = divn) and
@@ -195,8 +197,8 @@ implementation
              if (location.loc = LOC_CREGISTER) then
                begin
                  location.loc := LOC_REGISTER;
-                 location.registerhigh := rg.getregisterint(exprasmlist);
-                 location.registerlow := rg.getregisterint(exprasmlist);
+                 location.registerhigh := rg.getregisterint(exprasmlist,OS_32);
+                 location.registerlow := rg.getregisterint(exprasmlist,OS_32);
                end;
              if (right.nodetype = ordconstn) then
                begin
@@ -265,7 +267,7 @@ implementation
                      location.registerlow := resultreg;
                    end;
 
-                 rg.getexplicitregisterint(exprasmlist,R_0);
+                 rg.getexplicitregisterint(exprasmlist,NR_R0);
                  r.enum:=R_0;
                  exprasmlist.concat(taicpu.op_reg_reg_const(A_SUBFIC,
                    r,hregister1,32));
@@ -301,7 +303,7 @@ implementation
              if (location.loc = LOC_CREGISTER) then
                begin
                  location.loc := LOC_REGISTER;
-                 resultreg := rg.getregisterint(exprasmlist);
+                 resultreg := rg.getregisterint(exprasmlist,OS_32);
                  location.register := resultreg;
                end;
 
@@ -348,8 +350,8 @@ implementation
              location_copy(location,left.location);
              if (location.loc = LOC_CREGISTER) then
                begin
-                 location.registerlow := rg.getregisterint(exprasmlist);
-                 location.registerhigh := rg.getregisterint(exprasmlist);
+                 location.registerlow := rg.getregisterint(exprasmlist,OS_INT);
+                 location.registerhigh := rg.getregisterint(exprasmlist,OS_INT);
                  location.loc := LOC_CREGISTER;
                end;
              exprasmlist.concat(taicpu.op_reg_reg_const(A_SUBFIC,
@@ -375,7 +377,7 @@ implementation
                   begin
                      src1 := left.location.register;
                      if left.location.loc = LOC_CREGISTER then
-                       location.register := rg.getregisterint(exprasmlist)
+                       location.register := rg.getregisterint(exprasmlist,OS_INT)
                      else
                        location.register := rg.getregisterfpu(exprasmlist);
                   end;
@@ -391,7 +393,7 @@ implementation
                        end
                      else
                        begin
-                          src1 := rg.getregisterint(exprasmlist);
+                          src1 := rg.getregisterint(exprasmlist,OS_32);
                           location.register:= src1;
                           cg.a_load_ref_reg(exprasmlist,OS_32,
                             left.location.reference,src1);
@@ -491,7 +493,7 @@ implementation
              location_force_reg(exprasmlist,left.location,def_cgsize(left.resulttype.def),false);
              location_copy(location,left.location);
              if location.loc=LOC_CREGISTER then
-              location.register := rg.getregisterint(exprasmlist);
+              location.register := rg.getregisterint(exprasmlist,OS_INT);
              { perform the NOT operation }
              exprasmlist.concat(taicpu.op_reg_reg(A_NOT,location.register,
                left.location.register));
@@ -506,7 +508,11 @@ begin
 end.
 {
   $Log$
-  Revision 1.22  2003-01-09 20:41:10  florian
+  Revision 1.23  2003-02-19 22:00:16  daniel
+    * Code generator converted to new register notation
+    - Horribily outdated todo.txt removed
+
+  Revision 1.22  2003/01/09 20:41:10  florian
     * fixed broken PowerPC compiler
 
   Revision 1.21  2003/01/08 18:43:58  daniel

+ 6 - 2
compiler/powerpc/nppcset.pas

@@ -78,7 +78,7 @@ implementation
                 hregister,value))
             else
               begin
-                tmpreg := cg.get_scratch_reg_int(exprasmlist);
+                tmpreg := cg.get_scratch_reg_int(exprasmlist,OS_INT);
                 cg.a_load_const_reg(exprasmlist,OS_INT,aword(value),tmpreg);
                 exprasmlist.concat(taicpu.op_reg_reg_reg(A_ADD_,hregister,
                   hregister,tmpreg));
@@ -159,7 +159,11 @@ begin
 end.
 {
   $Log$
-  Revision 1.6  2003-01-08 18:43:58  daniel
+  Revision 1.7  2003-02-19 22:00:16  daniel
+    * Code generator converted to new register notation
+    - Horribily outdated todo.txt removed
+
+  Revision 1.6  2003/01/08 18:43:58  daniel
    * Tregister changed into a record
 
   Revision 1.5  2002/11/25 17:43:28  peter

+ 10 - 5
compiler/powerpc/rgcpu.pas

@@ -35,7 +35,7 @@ unit rgcpu;
 
      type
        trgcpu = class(trgobj)
-         function getexplicitregisterint(list: taasmoutput; reg: Toldregister): tregister; override;
+         function getexplicitregisterint(list: taasmoutput; reg: Tnewregister): tregister; override;
          procedure ungetregisterint(list: taasmoutput; reg: tregister); override;
        end;
 
@@ -44,14 +44,15 @@ unit rgcpu;
     uses
       cgobj;
 
-    function trgcpu.getexplicitregisterint(list: taasmoutput; reg: Toldregister): tregister;
+    function trgcpu.getexplicitregisterint(list: taasmoutput; reg: Tnewregister): tregister;
 
     var r:Tregister;
 
       begin
-        if reg = R_0 then
+        if reg = NR_R0 then
           begin
-            r.enum:=R_0;
+            r.enum:=R_INTREGISTER;
+            r.number:=NR_R0;
             cg.a_reg_alloc(list,r);
             result := r;
           end
@@ -74,7 +75,11 @@ end.
 
 {
   $Log$
-  Revision 1.4  2003-01-08 18:43:58  daniel
+  Revision 1.5  2003-02-19 22:00:16  daniel
+    * Code generator converted to new register notation
+    - Horribily outdated todo.txt removed
+
+  Revision 1.4  2003/01/08 18:43:58  daniel
    * Tregister changed into a record
 
   Revision 1.3  2002/07/07 09:44:32  florian

+ 9 - 3
compiler/pstatmnt.pas

@@ -1017,7 +1017,8 @@ implementation
         aktprocdef.localst.datasize:=0;
         procinfo.firsttemp_offset:=0;
         { replace framepointer with stackpointer }
-        procinfo.framepointer.enum:=STACK_POINTER_REG;
+        procinfo.framepointer.enum:=R_INTREGISTER;
+        procinfo.framepointer.number:=NR_STACK_POINTER_REG;
         { set the right value for parameters }
         dec(aktprocdef.parast.address_fixup,pointer_size);
         dec(procinfo.para_offset,pointer_size);
@@ -1041,7 +1042,8 @@ implementation
                        ref_parafixup :
                          begin
                            ref^.offsetfixup:=parafixup;
-                           ref^.base.enum:=STACK_POINTER_REG;
+                           ref^.base.enum:=R_INTREGISTER;
+                           ref^.base.number:=NR_STACK_POINTER_REG;
                          end;
                      end;
                    end;
@@ -1125,7 +1127,11 @@ implementation
 end.
 {
   $Log$
-  Revision 1.85  2003-01-08 18:43:56  daniel
+  Revision 1.86  2003-02-19 22:00:14  daniel
+    * Code generator converted to new register notation
+    - Horribily outdated todo.txt removed
+
+  Revision 1.85  2003/01/08 18:43:56  daniel
    * Tregister changed into a record
 
   Revision 1.84  2003/01/01 21:05:24  peter

+ 9 - 3
compiler/psub.pas

@@ -358,7 +358,8 @@ implementation
                 genexitcode(procinfo.aktexitcode,parasize,nostackframe,false);
 
                 { now all the registers used are known }
-                aktprocdef.usedregisters:=rg.usedinproc;
+                aktprocdef.usedintregisters:=rg.usedintinproc;
+                aktprocdef.usedotherregisters:=rg.usedinproc;
                 procinfo.aktproccode.insertlist(procinfo.aktentrycode);
                 procinfo.aktproccode.concatlist(procinfo.aktexitcode);
 {$ifdef i386}
@@ -545,7 +546,8 @@ implementation
           { clear flags }
             flags:=0;
           { standard frame pointer }
-            framepointer.enum:=frame_pointer_reg;
+            framepointer.enum:=R_INTREGISTER;
+            framepointer.number:=NR_FRAME_POINTER_REG;
           { is this a nested function of a method ? }
             if assigned(oldprocinfo) then
               _class:=oldprocinfo._class;
@@ -846,7 +848,11 @@ implementation
 end.
 {
   $Log$
-  Revision 1.91  2003-01-09 21:52:37  peter
+  Revision 1.92  2003-02-19 22:00:14  daniel
+    * Code generator converted to new register notation
+    - Horribily outdated todo.txt removed
+
+  Revision 1.91  2003/01/09 21:52:37  peter
     * merged some verbosity options.
     * V_LineInfo is a verbosity flag to include line info
 

+ 13 - 3
compiler/rautils.pas

@@ -78,7 +78,7 @@ type
       OPR_REFERENCE : (ref:treference);
       OPR_REGISTER  : (reg:tregister);
 {$ifdef m68k}
-      OPR_REGLIST   : (reglist:tregisterlist);
+      OPR_REGLIST   : (reglist:Tsupregset);
 {$else not m68k}
       OPR_REGLIST   : ();
 {$endif m68k}
@@ -825,7 +825,8 @@ Begin
                 that %esi is valid there }
               else
                 begin
-                  opr.ref.base.enum:=SELF_POINTER_REG;
+                  opr.ref.base.enum:=R_INTREGISTER;
+                  opr.ref.base.number:=NR_SELF_POINTER_REG;
                   opr.ref.offset:=tvarsym(sym).address;
                 end;
               hasvar:=true;
@@ -1037,6 +1038,11 @@ Begin
   end;
   opr.typ := OPR_REFERENCE;
   Fillchar(opr.ref,sizeof(treference),0);
+{$ifdef i386}
+  opr.ref.segment.enum:=R_INTREGISTER;
+{$endif}
+  opr.ref.index.enum:=R_INTREGISTER;
+  opr.ref.base.enum:=R_INTREGISTER;
 end;
 
 
@@ -1591,7 +1597,11 @@ end;
 end.
 {
   $Log$
-  Revision 1.52  2003-01-08 18:43:56  daniel
+  Revision 1.53  2003-02-19 22:00:14  daniel
+    * Code generator converted to new register notation
+    - Horribily outdated todo.txt removed
+
+  Revision 1.52  2003/01/08 18:43:56  daniel
    * Tregister changed into a record
 
   Revision 1.51  2002/12/14 15:02:03  carl

+ 17 - 3
compiler/regvars.pas

@@ -35,6 +35,7 @@ interface
     procedure assign_regvars(p: tnode);
     procedure load_regvars(asml: TAAsmoutput; p: tnode);
     procedure cleanup_regvars(asml: TAAsmoutput);
+    procedure store_regvar_int(asml:Taasmoutput;reg:Tsuperregister);
     procedure store_regvar(asml: TAAsmoutput; reg: tregister);
     procedure load_regvar(asml: TAAsmoutput; vsym: tvarsym);
     procedure load_regvar_reg(asml: TAAsmoutput; reg: tregister);
@@ -174,7 +175,10 @@ implementation
                       { search the register which is the most }
                       { unused                                }
                       r.enum:=varregs[i];
-                      rg.makeregvar(r);
+                      if r.enum=R_INTREGISTER then
+                        rg.makeregvarint(r.number)
+                      else
+                        rg.makeregvarother(r);
 
                       { possibly no 32 bit register are needed }
                       { call by reference/const ? }
@@ -260,7 +264,7 @@ implementation
                        r.enum:=R_ST0;
                        regvarinfo^.fpuregvars[i].reg:=trgcpu(rg).correct_fpuregister(r,i);
 {$else i386}
-                       rg.makeregvar(regvarinfo^.fpuregvars[i].reg);
+                       rg.makeregvarother(regvarinfo^.fpuregvars[i].reg);
 {$endif i386}
                      end;
                   end;
@@ -269,6 +273,12 @@ implementation
      end;
 
 
+    procedure store_regvar_int(asml:Taasmoutput;reg:Tsuperregister);
+    
+    begin
+      internalerror(200301104);
+    end;
+
     procedure store_regvar(asml: TAAsmoutput; reg: tregister);
     var
       i: longint;
@@ -487,7 +497,11 @@ end.
 
 {
   $Log$
-  Revision 1.44  2003-01-08 18:43:57  daniel
+  Revision 1.45  2003-02-19 22:00:14  daniel
+    * Code generator converted to new register notation
+    - Horribily outdated todo.txt removed
+
+  Revision 1.44  2003/01/08 18:43:57  daniel
    * Tregister changed into a record
 
   Revision 1.43  2002/11/25 17:43:24  peter

+ 337 - 161
compiler/rgobj.pas

@@ -46,6 +46,7 @@ unit rgobj;
 
 
        regvar_longintarray = array[firstreg..lastreg] of longint;
+       regvarint_longintarray = array[first_supreg..last_supreg] of longint;
        regvar_booleanarray = array[firstreg..lastreg] of boolean;
        regvar_ptreearray = array[firstreg..lastreg] of tnode;
 
@@ -56,48 +57,7 @@ unit rgobj;
        end;
 
        tpushedsaved = array[firstreg..lastreg] of tpushedsavedloc;
-
-      (******************************* private struct **********************)
-      psavedstate = ^tsavedstate;
-      tsavedstate = record
-        unusedregsint,usableregsint : tregisterset;
-        unusedregsfpu,usableregsfpu : tregisterset;
-        unusedregsmm,usableregsmm : tregisterset;
-        unusedregsaddr,usableregsaddr : tregisterset;
-        countunusedregsaddr,
-        countunusedregsint,
-        countunusedregsfpu,
-        countunusedregsmm : byte;
-        countusableregsaddr,
-        countusableregsint,
-        countusableregsfpu,
-        countusableregsmm : byte;
-        { contains the registers which are really used by the proc itself }
-        usedbyproc,
-        usedinproc : tregisterset;
-        reg_pushes : regvar_longintarray;
-        is_reg_var : regvar_booleanarray;
-        regvar_loaded: regvar_booleanarray;
-{$ifdef TEMPREGDEBUG}
-         reg_user   : regvar_ptreearray;
-         reg_releaser : regvar_ptreearray;
-{$endif TEMPREGDEBUG}
-      end;
-
-      (******************************* private struct **********************)
-      punusedstate = ^tunusedstate;
-      tunusedstate = record
-        unusedregsint : tregisterset;
-        unusedregsfpu : tregisterset;
-        unusedregsmm : tregisterset;
-        unusedregsaddr : tregisterset; 
-        countunusedregsaddr,
-        countunusedregsint,
-        countunusedregsfpu,
-        countunusedregsmm : byte;
-      end;
-
-
+       Tpushedsavedint = array[first_supreg..last_supreg] of Tpushedsavedloc;
 
        {#
           This class implements the abstract register allocator
@@ -113,7 +73,7 @@ unit rgobj;
           { aren't currently allocated to a regvar. The "unusedregsxxx"  }
           { contain all registers of type "xxx" that aren't currenly     }
           { allocated                                                    }
-          unusedregsint,usableregsint : tregisterset;
+          unusedregsint,usableregsint:Tsupregset;
           unusedregsfpu,usableregsfpu : tregisterset;
           unusedregsmm,usableregsmm : tregisterset;
           { these counters contain the number of elements in the }
@@ -130,10 +90,14 @@ unit rgobj;
           }
           usedbyproc,
           usedinproc : tregisterset;
+          usedintbyproc,usedintinproc:Tsupregset;
 
           reg_pushes : regvar_longintarray;
+          reg_pushes_int : regvarint_longintarray;
           is_reg_var : regvar_booleanarray;
+          is_reg_var_int:Tsupregset;
           regvar_loaded: regvar_booleanarray;
+          regvar_loaded_int: Tsupregset;
 
 
           { tries to hold the amount of times which the current tree is processed  }
@@ -146,7 +110,7 @@ unit rgobj;
              An internalerror will be generated if there
              is no more free registers which can be allocated
           }
-          function getregisterint(list: taasmoutput) : tregister; virtual;
+          function getregisterint(list:Taasmoutput;size:Tcgsize):Tregister;virtual;
           {# Free a general purpose register
 
              @param(r register to free)
@@ -180,7 +144,7 @@ unit rgobj;
              An internalerror will be generated if there
              is no more free registers which can be allocated
           }
-          function getaddressregister(list: taasmoutput): tregister; virtual;
+          function getaddressregister(list:Taasmoutput):Tregister;virtual;
           procedure ungetaddressregister(list: taasmoutput; r: tregister); virtual;
           {# Verify if the specified register is an address or
              general purpose register. Returns TRUE if @var(reg)
@@ -199,7 +163,7 @@ unit rgobj;
 
              @param(r specific register to allocate)
           }
-          function getexplicitregisterint(list: taasmoutput; r : Toldregister) : tregister;virtual;
+          function getexplicitregisterint(list:Taasmoutput;r:Tnewregister):Tregister;virtual;
           {# Tries to allocate the passed fpu register, if possible
 
              @param(r specific register to allocate)
@@ -226,7 +190,8 @@ unit rgobj;
 
 
           {# saves register variables (restoring happens automatically) }
-          procedure saveregvars(list: taasmoutput; const s: tregisterset);
+          procedure saveintregvars(list:Taasmoutput;const s:Tsupregset);
+          procedure saveotherregvars(list:Taasmoutput;const s:Tregisterset);
 
           {# Saves in temporary references (allocated via the temp. allocator)
              the registers defined in @var(s). The registers are only saved
@@ -239,23 +204,31 @@ unit rgobj;
              @param(saved)  Array of saved register information
              @param(s)      Registers which might require saving
           }
-          procedure saveusedregisters(list: taasmoutput;
-            var saved : tpushedsaved;const s: tregisterset);virtual;
+          procedure saveusedintregisters(list:Taasmoutput;
+                                         var saved:Tpushedsavedint;
+                                         const s:Tsupregset);virtual;
+          procedure saveusedotherregisters(list:Taasmoutput;
+                                           var saved:Tpushedsaved;
+                                           const s:Tregisterset);virtual;
           {# Restores the registers which were saved with a call
              to @var(saveusedregisters).
 
              On processors which have instructions which manipulate the stack,
              this routine should be overriden for performance reasons.
           }
-          procedure restoreusedregisters(list: taasmoutput;
-            const saved : tpushedsaved);virtual;
+          procedure restoreusedintregisters(list:Taasmoutput;
+                                            const saved:Tpushedsavedint);virtual;
+          procedure restoreusedotherregisters(list:Taasmoutput;
+                                              const saved:Tpushedsaved);virtual;
 
           { used when deciding which registers to use for regvars }
-          procedure incrementregisterpushed(const s: tregisterset);
+          procedure incrementintregisterpushed(const s:Tsupregset);
+          procedure incrementotherregisterpushed(const s: tregisterset);
           procedure clearregistercount;
           procedure resetusableregisters;virtual;
 
-          procedure makeregvar(reg: tregister);
+          procedure makeregvarint(reg:Tnewregister);
+          procedure makeregvarother(reg:Tregister);
 
           procedure saveStateForInline(var state: pointer);virtual;
           procedure restoreStateAfterInline(var state: pointer);virtual;
@@ -266,9 +239,17 @@ unit rgobj;
           { the following two contain the common (generic) code for all }
           { get- and ungetregisterxxx functions/procedures              }
           function getregistergen(list: taasmoutput; const lowreg, highreg: Toldregister;
-              var unusedregs: tregisterset; var countunusedregs: byte): tregister;
+              var unusedregs:Tregisterset; var countunusedregs: byte): tregister;
+          function getregistergenint(list:Taasmoutput;subreg:Tsubregister;
+                                     const lowreg,highreg:Tsuperregister;
+                                     var fusedinproc,fusedbyproc,unusedregs:Tsupregset;
+                                     var countunusedregs:byte):Tregister;
           procedure ungetregistergen(list: taasmoutput; const r: tregister;
               const usableregs: tregisterset; var unusedregs: tregisterset; var countunusedregs: byte);
+          procedure ungetregistergenint(list:taasmoutput;const r:Tregister;
+                                        const usableregs:Tsupregset;
+                                        var unusedregs:Tsupregset;
+                                        var countunusedregs:byte);
 {$ifdef TEMPREGDEBUG}
          reg_user   : regvar_ptreearray;
          reg_releaser : regvar_ptreearray;
@@ -311,6 +292,45 @@ unit rgobj;
      procedure location_copy(var destloc,sourceloc : tlocation);
      procedure location_swap(var destloc,sourceloc : tlocation);
 
+    type
+      psavedstate = ^tsavedstate;
+      tsavedstate = record
+        unusedregsint,usableregsint : Tsupregset;
+        unusedregsaddr,usableregsaddr : Tsupregset;
+        unusedregsfpu,usableregsfpu : tregisterset;
+        unusedregsmm,usableregsmm : tregisterset;
+        countunusedregsint,
+        countunusedregsaddr,
+        countunusedregsfpu,
+        countunusedregsmm : byte;
+        countusableregsint,
+        countusableregsfpu,
+        countusableregsmm : byte;
+        { contains the registers which are really used by the proc itself }
+        usedbyproc,
+        usedinproc : tregisterset;
+        reg_pushes : regvar_longintarray;
+        is_reg_var : regvar_booleanarray;
+        is_reg_var_int : Tsupregset;
+        regvar_loaded: regvar_booleanarray;
+        regvar_loaded_int: Tsupregset;
+{$ifdef TEMPREGDEBUG}
+         reg_user   : regvar_ptreearray;
+         reg_releaser : regvar_ptreearray;
+{$endif TEMPREGDEBUG}
+      end;
+
+      punusedstate = ^tunusedstate;
+      tunusedstate = record
+        unusedregsint : Tsupregset;
+        unusedregsaddr : Tsupregset;
+        unusedregsfpu : tregisterset;
+        unusedregsmm : tregisterset;
+        countunusedregsint,
+        countunusedregsaddr,
+        countunusedregsfpu,
+        countunusedregsmm : byte;
+      end;
 
   implementation
 
@@ -319,10 +339,6 @@ unit rgobj;
        globals,verbose,
        cgobj,tgobj,regvars;
 
-
-
-
-
     constructor trgobj.create;
 
      begin
@@ -360,6 +376,34 @@ unit rgobj;
          internalerror(10);
       end;
 
+    function Trgobj.getregistergenint(list:Taasmoutput;
+                                      subreg:Tsubregister;
+                                      const lowreg,highreg:Tsuperregister;
+                                      var fusedinproc,fusedbyproc,unusedregs:Tsupregset;
+                                      var countunusedregs:byte):Tregister;
+
+    var i:Tsuperregister;
+        r:Tregister;
+
+    begin
+      for i:=lowreg to highreg do
+        begin
+          if i in unusedregs then
+            begin
+              exclude(unusedregs,i);
+              include(fusedinproc,i);
+              include(fusedbyproc,i);
+              dec(countunusedregs);
+              r.enum:=R_INTREGISTER;
+              r.number:=i shl 8 or subreg;
+              list.concat(tai_regalloc.alloc(r));
+              result:=r;
+              exit;
+            end;
+        end;
+      internalerror(10);
+    end;
+
 
     procedure trgobj.ungetregistergen(list: taasmoutput; const r: tregister;
         const usableregs: tregisterset; var unusedregs: tregisterset; var countunusedregs: byte);
@@ -387,33 +431,74 @@ unit rgobj;
         list.concat(tai_regalloc.dealloc(r));
       end;
 
+    procedure trgobj.ungetregistergenint(list:taasmoutput;const r:Tregister;
+                                         const usableregs:Tsupregset;
+                                         var unusedregs:Tsupregset;
+                                         var countunusedregs:byte);
 
-    function trgobj.getregisterint(list : taasmoutput) : tregister;
+    var supreg:Tsuperregister;
 
-      begin
-         if countunusedregsint=0 then
-           internalerror(10);
+    begin
+      if r.enum<=lastreg then
+        internalerror(2003010803);
+      supreg:=r.number shr 8;
+      { takes much time }
+      if not(supreg in usableregs) then
+        exit;
 {$ifdef TEMPREGDEBUG}
-         if curptree^^.usableregs-countunusedregsint>curptree^^.registers32 then
-           internalerror(10);
+         if (supreg in unusedregs) then
+{$ifdef EXTTEMPREGDEBUG}
+           begin
+             comment(v_debug,'register freed twice '+supreg_name(supreg));
+             testregisters32;
+             exit;
+           end
+{$else EXTTEMPREGDEBUG}
+           exit
+{$endif EXTTEMPREGDEBUG}
+         else
+{$endif TEMPREGDEBUG}
+          inc(countunusedregs);
+        include(unusedregs,supreg);
+        list.concat(tai_regalloc.dealloc(r));
+      end;
+
+
+    function trgobj.getregisterint(list:taasmoutput;size:Tcgsize):Tregister;
+
+    var subreg:Tsubregister;
+
+    begin
+      if countunusedregsint=0 then
+        internalerror(10);
+{$ifdef TEMPREGDEBUG}
+      if curptree^^.usableregs-countunusedregsint>curptree^^.registers32 then
+        internalerror(10);
 {$endif TEMPREGDEBUG}
 {$ifdef EXTTEMPREGDEBUG}
-         if curptree^^.usableregs-countunusedregsint>curptree^^.reallyusedregs then
-           curptree^^.reallyusedregs:=curptree^^.usableregs-countunusedregsint;
+      if curptree^^.usableregs-countunusedregsint>curptree^^.reallyusedregs then
+        curptree^^.reallyusedregs:=curptree^^.usableregs-countunusedregsint;
 {$endif EXTTEMPREGDEBUG}
-         result := getregistergen(list,firstsaveintreg,lastsaveintreg,
-                     unusedregsint,countunusedregsint);
+      subreg:=cgsize2subreg(size);
+      result:=getregistergenint(list,
+                                subreg,
+                                first_supreg,
+                                last_supreg,
+                                usedintbyproc,
+                                usedintinproc,
+                                unusedregsint,
+                                countunusedregsint);
 {$ifdef TEMPREGDEBUG}
-         reg_user[result]:=curptree^;
-         testregisters32;
+      reg_user[result]:=curptree^;
+      testregisters32;
 {$endif TEMPREGDEBUG}
-      end;
+    end;
 
 
     procedure trgobj.ungetregisterint(list : taasmoutput; r : tregister);
 
       begin
-         ungetregistergen(list,r,usableregsint,unusedregsint,
+         ungetregistergenint(list,r,usableregsint,unusedregsint,
            countunusedregsint);
 {$ifdef TEMPREGDEBUG}
         reg_releaser[r]:=curptree^;
@@ -423,32 +508,34 @@ unit rgobj;
 
 
     { tries to allocate the passed register, if possible }
-    function trgobj.getexplicitregisterint(list : taasmoutput; r : Toldregister) : tregister;
+    function trgobj.getexplicitregisterint(list:Taasmoutput;r:Tnewregister):Tregister;
 
     var r2:Tregister;
 
-      begin
-         if r in unusedregsint then
-           begin
-              dec(countunusedregsint);
+    begin
+      if (r shr 8) in unusedregsint then
+        begin
+          dec(countunusedregsint);
 {$ifdef TEMPREGDEBUG}
-              if curptree^^.usableregs-countunusedregsint>curptree^^.registers32 then
-                internalerror(10);
-              reg_user[r]:=curptree^;
+          if curptree^^.usableregs-countunusedregsint>curptree^^.registers32 then
+            internalerror(10);
+          reg_user[r shr 8]:=curptree^;
 {$endif TEMPREGDEBUG}
-              exclude(unusedregsint,r);
-              include(usedinproc,r);
-              include(usedbyproc,r);
-              r2.enum:=r;
-              list.concat(tai_regalloc.alloc(r2));
-              getexplicitregisterint:=r2;
+          exclude(unusedregsint,r shr 8);
+          include(usedintinproc,r shr 8);
+          include(usedintbyproc,r shr 8);
+          r2.enum:=R_INTREGISTER;
+          r2.number:=r;
+          list.concat(tai_regalloc.alloc(r2));
+          getexplicitregisterint:=r2;
 {$ifdef TEMPREGDEBUG}
-              testregisters32;
+          testregisters32;
 {$endif TEMPREGDEBUG}
-           end
-         else
-           getexplicitregisterint:=getregisterint(list);
-      end;
+         end
+       else
+{         getexplicitregisterint:=getregisterint(list,r and $ff);}
+          internalerror(200301103);
+    end;
 
 
     { tries to allocate the passed register, if possible }
@@ -465,7 +552,7 @@ unit rgobj;
                 internalerror(10);
               reg_user[r]:=curptree^;
 {$endif TEMPREGDEBUG}
-              exclude(unusedregsint,r);
+              exclude(unusedregsfpu,r);
               include(usedinproc,r);
               include(usedbyproc,r);
               r2.enum:=r;
@@ -513,9 +600,10 @@ unit rgobj;
       end;
 
 
-    function trgobj.getaddressregister(list: taasmoutput): tregister;
+    function trgobj.getaddressregister(list:Taasmoutput): tregister;
       begin
-        result := getregisterint(list);
+        {An address register is OS_INT per definition.}
+        result := getregisterint(list,OS_INT);
       end;
 
 
@@ -570,16 +658,25 @@ unit rgobj;
       end;
 
 
-    procedure trgobj.saveregvars(list: taasmoutput; const s: tregisterset);
+    procedure trgobj.saveintregvars(list:Taasmoutput;const s:Tsupregset);
+
+    var r:Tsuperregister;
+
+    begin
+      if not(cs_regalloc in aktglobalswitches) then
+        exit;
+      for r:=firstsaveintreg to lastsaveintreg do
+        if (r in is_reg_var_int) and
+           (r in s) then
+          store_regvar_int(list,r);
+    end;
+
+    procedure trgobj.saveotherregvars(list: taasmoutput; const s: tregisterset);
       var
         r: Tregister;
       begin
         if not(cs_regalloc in aktglobalswitches) then
           exit;
-        for r.enum := firstsaveintreg to lastsaveintreg do
-          if is_reg_var[r.enum] and
-             (r.enum in s) then
-            store_regvar(list,r);
         if firstsavefpureg <> R_NO then
           for r.enum := firstsavefpureg to lastsavefpureg do
             if is_reg_var[r.enum] and
@@ -593,7 +690,43 @@ unit rgobj;
       end;
 
 
-    procedure trgobj.saveusedregisters(list: taasmoutput;
+    procedure trgobj.saveusedintregisters(list:Taasmoutput;
+                                          var saved:Tpushedsavedint;
+                                          const s:Tsupregset);
+
+    var r:Tsuperregister;
+        r2:Tregister;
+        hr : treference;
+
+    begin
+      usedintinproc:=usedintinproc+s;
+      for r:=firstsaveintreg to lastsaveintreg do
+        begin
+          saved[r].ofs:=reg_not_saved;
+          { if the register is used by the calling subroutine and if }
+          { it's not a regvar (those are handled separately)         }
+          if not (r in is_reg_var_int) and
+             (r in s) and
+             { and is present in use }
+             not(r in unusedregsint) then
+            begin
+              { then save it }
+              tg.GetTemp(list,sizeof(aword),tt_persistant,hr);
+              saved[r].ofs:=hr.offset;
+              r2.enum:=R_INTREGISTER;
+              r2.number:=r shl 8 or R_SUBWHOLE;
+              cg.a_load_reg_ref(list,OS_INT,r2,hr);
+              cg.a_reg_dealloc(list,r2);
+              include(unusedregsint,r);
+              inc(countunusedregsint);
+            end;
+        end;
+{$ifdef TEMPREGDEBUG}
+      testregisters32;
+{$endif TEMPREGDEBUG}
+    end;
+
+    procedure trgobj.saveusedotherregisters(list: taasmoutput;
         var saved : tpushedsaved; const s: tregisterset);
 
       var
@@ -602,25 +735,6 @@ unit rgobj;
 
       begin
         usedinproc:=usedinproc + s;
-        for r.enum:=firstsaveintreg to lastsaveintreg do
-          begin
-            saved[r.enum].ofs:=reg_not_saved;
-            { if the register is used by the calling subroutine and if }
-            { it's not a regvar (those are handled separately)         }
-            if not is_reg_var[r.enum] and
-               (r.enum in s) and
-               { and is present in use }
-               not(r.enum in unusedregsint) then
-              begin
-                { then save it }
-                tg.GetTemp(list,sizeof(aword),tt_persistant,hr);
-                saved[r.enum].ofs:=hr.offset;
-                cg.a_load_reg_ref(list,OS_INT,r,hr);
-                cg.a_reg_dealloc(list,r);
-                include(unusedregsint,r.enum);
-                inc(countunusedregsint);
-              end;
-          end;
 
         { don't try to save the fpu registers if not desired (e.g. for }
         { the 80x86)                                                   }
@@ -672,7 +786,44 @@ unit rgobj;
       end;
 
 
-    procedure trgobj.restoreusedregisters(list : taasmoutput;
+    procedure trgobj.restoreusedintregisters(list:Taasmoutput;
+                                             const saved:Tpushedsavedint);
+
+    var r:Tsuperregister;
+        r2:Tregister;
+        hr:Treference;
+
+      begin
+        for r:=lastsaveintreg downto firstsaveintreg do
+          begin
+            if saved[r].ofs <> reg_not_saved then
+              begin
+                r2.enum:=R_INTREGISTER;
+                r2.number:=NR_FRAME_POINTER_REG;
+                reference_reset_base(hr,r2,saved[r].ofs);
+                r2.enum:=R_INTREGISTER;
+                r2.number:=r shl 8 or R_SUBWHOLE;
+                cg.a_reg_alloc(list,r2);
+                cg.a_load_ref_reg(list,OS_INT,hr,r2);
+                if not (r in unusedregsint) then
+                  { internalerror(10)
+                    in n386cal we always save/restore the reg *state*
+                    using save/restoreunusedstate -> the current state
+                    may not be real (JM) }
+                else
+                  begin
+                    dec(countunusedregsint);
+                    exclude(unusedregsint,r);
+                  end;
+                tg.UnGetTemp(list,hr);
+              end;
+          end;
+{$ifdef TEMPREGDEBUG}
+        testregisters32;
+{$endif TEMPREGDEBUG}
+      end;
+
+    procedure trgobj.restoreusedotherregisters(list : taasmoutput;
         const saved : tpushedsaved);
 
       var
@@ -685,7 +836,8 @@ unit rgobj;
             begin
               if saved[r.enum].ofs <> reg_not_saved then
                 begin
-                  r2.enum:=FRAME_POINTER_REG;
+                  r2.enum:=R_INTREGISTER;
+                  r2.number:=NR_FRAME_POINTER_REG;
                   reference_reset_base(hr,r2,saved[r.enum].ofs);
                   cg.a_reg_alloc(list,r);
                   cg.a_loadmm_ref_reg(list,hr,r);
@@ -708,7 +860,8 @@ unit rgobj;
             begin
               if saved[r.enum].ofs <> reg_not_saved then
                 begin
-                  r2.enum:=FRAME_POINTER_REG;
+                  r2.enum:=R_INTREGISTER;
+                  r2.number:=NR_FRAME_POINTER_REG;
                   reference_reset_base(hr,r2,saved[r.enum].ofs);
                   cg.a_reg_alloc(list,r);
                   cg.a_loadfpu_ref_reg(list,OS_FLOAT,hr,r);
@@ -725,45 +878,30 @@ unit rgobj;
                   tg.UnGetTemp(list,hr);
                 end;
             end;
-
-        for r.enum:=lastsaveintreg downto firstsaveintreg do
-          begin
-            if saved[r.enum].ofs <> reg_not_saved then
-              begin
-                r2.enum:=FRAME_POINTER_REG;
-                reference_reset_base(hr,r2,saved[r.enum].ofs);
-                cg.a_reg_alloc(list,r);
-                cg.a_load_ref_reg(list,OS_INT,hr,r);
-                if not (r.enum in unusedregsint) then
-                  { internalerror(10)
-                    in n386cal we always save/restore the reg *state*
-                    using save/restoreunusedstate -> the current state
-                    may not be real (JM) }
-                else
-                  begin
-                    dec(countunusedregsint);
-                    exclude(unusedregsint,r.enum);
-                  end;
-                tg.UnGetTemp(list,hr);
-              end;
-          end;
 {$ifdef TEMPREGDEBUG}
         testregisters32;
 {$endif TEMPREGDEBUG}
       end;
 
 
-    procedure trgobj.incrementregisterpushed(const s: tregisterset);
+    procedure trgobj.incrementintregisterpushed(const s:Tsupregset);
+
+    var regi:Tsuperregister;
+
+    begin
+      for regi:=firstsaveintreg to lastsaveintreg do
+        begin
+          if (regi in s) then
+            inc(reg_pushes_int[regi],t_times*2);
+        end;
+    end;
+
+    procedure trgobj.incrementotherregisterpushed(const s:Tregisterset);
 
       var
          regi : Toldregister;
 
       begin
-         for regi:=firstsaveintreg to lastsaveintreg do
-           begin
-              if (regi in s) then
-                inc(reg_pushes[regi],t_times*2);
-           end;
          if firstsavefpureg <> R_NO then
            for regi:=firstsavefpureg to lastsavefpureg do
              begin
@@ -784,7 +922,9 @@ unit rgobj;
       begin
         fillchar(reg_pushes,sizeof(reg_pushes),0);
         fillchar(is_reg_var,sizeof(is_reg_var),false);
+        is_reg_var_int:=[];
         fillchar(regvar_loaded,sizeof(regvar_loaded),false);
+        regvar_loaded_int:=[];
       end;
 
 
@@ -802,17 +942,25 @@ unit rgobj;
       end;
 
 
-    procedure trgobj.makeregvar(reg: tregister);
+    procedure trgobj.makeregvarint(reg:Tnewregister);
+    
+    var supreg:Tsuperregister;
+
+    begin
+      supreg:=reg shr 8;
+      dec(countusableregsint);
+      dec(countunusedregsint);
+      exclude(usableregsint,reg);
+      exclude(unusedregsint,reg);
+      include(is_reg_var_int,supreg);
+    end;
+
+    procedure trgobj.makeregvarother(reg: tregister);
       begin
         if reg.enum>lastreg then
           internalerror(200301081);
         if reg.enum in intregs then
-          begin
-            dec(countusableregsint);
-            dec(countunusedregsint);
-            exclude(usableregsint,reg.enum);
-            exclude(unusedregsint,reg.enum);
-          end
+          internalerror(200301151)
         else if reg.enum in fpuregs then
           begin
              dec(countusableregsfpu);
@@ -865,7 +1013,9 @@ unit rgobj;
         psavedstate(state)^.usedbyproc := usedbyproc;
         psavedstate(state)^.reg_pushes := reg_pushes;
         psavedstate(state)^.is_reg_var := is_reg_var;
+        psavedstate(state)^.is_reg_var_int := is_reg_var_int;
         psavedstate(state)^.regvar_loaded := regvar_loaded;
+        psavedstate(state)^.regvar_loaded_int := regvar_loaded_int;
 {$ifdef TEMPREGDEBUG}
         psavedstate(state)^.reg_user := reg_user;
         psavedstate(state)^.reg_releaser := reg_releaser;
@@ -891,7 +1041,9 @@ unit rgobj;
         usedbyproc := psavedstate(state)^.usedbyproc;
         reg_pushes := psavedstate(state)^.reg_pushes;
         is_reg_var := psavedstate(state)^.is_reg_var;
+        is_reg_var_int := psavedstate(state)^.is_reg_var_int;
         regvar_loaded := psavedstate(state)^.regvar_loaded;
+        regvar_loaded_int := psavedstate(state)^.regvar_loaded_int;
 {$ifdef TEMPREGDEBUG}
         reg_user := psavedstate(state)^.reg_user;
         reg_releaser := psavedstate(state)^.reg_releaser;
@@ -933,20 +1085,25 @@ unit rgobj;
     procedure reference_reset(var ref : treference);
       begin
         FillChar(ref,sizeof(treference),0);
+        ref.base.enum:=R_INTREGISTER;
+        ref.index.enum:=R_INTREGISTER;
+      {$ifdef i386}
+        ref.segment.enum:=R_INTREGISTER;
+      {$endif}
       end;
 
 
     procedure reference_reset_base(var ref : treference;base : tregister;offset : longint);
       begin
-        FillChar(ref,sizeof(treference),0);
+        reference_reset(ref);
         ref.base:=base;
         ref.offset:=offset;
       end;
 
 
     procedure reference_reset_symbol(var ref : treference;sym : tasmsymbol;offset : longint);
-          begin
-        FillChar(ref,sizeof(treference),0);
+      begin
+        reference_reset(ref);
         ref.symbol:=sym;
         ref.offset:=offset;
       end;
@@ -981,6 +1138,21 @@ unit rgobj;
         FillChar(l,sizeof(tlocation),0);
         l.loc:=lt;
         l.size:=lsize;
+        case l.loc of
+          LOC_REGISTER,LOC_CREGISTER:
+            begin
+              l.register.enum:=R_INTREGISTER;
+              l.registerhigh.enum:=R_INTREGISTER;
+            end;
+          LOC_REFERENCE,LOC_CREFERENCE:
+            begin
+              l.reference.base.enum:=R_INTREGISTER;
+              l.reference.index.enum:=R_INTREGISTER;
+            {$ifdef i386}
+              l.reference.segment.enum:=R_INTREGISTER;
+            {$endif}
+            end;
+        end;
       end;
 
 
@@ -1030,7 +1202,11 @@ end.
 
 {
   $Log$
-  Revision 1.22  2003-02-02 19:25:54  carl
+  Revision 1.23  2003-02-19 22:00:14  daniel
+    * Code generator converted to new register notation
+    - Horribily outdated todo.txt removed
+
+  Revision 1.22  2003/02/02 19:25:54  carl
     * Several bugfixes for m68k target (register alloc., opcode emission)
     + VIS target
     + Generic add more complete (still not verified)

+ 12 - 8
compiler/sparc/cgcpu.pas

@@ -80,10 +80,10 @@ specific processor ABI. It is overriden for each CPU target.
     procedure g_stackframe_entry(list:TAasmOutput;localsize:LongInt);override;
     procedure g_restore_all_registers(list:TAasmOutput;selfused,accused,acchiused:boolean);override;
     procedure g_restore_frame_pointer(list:TAasmOutput);override;
-    procedure g_restore_standard_registers(list:taasmoutput;usedinproc:tregisterset);override;
+    procedure g_restore_standard_registers(list:taasmoutput;usedinproc:Tsupregset);override;
     procedure g_return_from_proc(list:TAasmOutput;parasize:aword);override;
     procedure g_save_all_registers(list : taasmoutput);override;
-    procedure g_save_standard_registers(list : taasmoutput; usedinproc : tregisterset);override;
+    procedure g_save_standard_registers(list : taasmoutput; usedinproc : Tsupregset);override;
     procedure g_concatcopy(list:TAasmOutput;CONST source,dest:TReference;len:aword;delsource,loadref:boolean);override;
     class function reg_cgsize(CONST reg:tregister):tcgsize;override;
   PRIVATE
@@ -180,7 +180,7 @@ procedure TCgSparc.a_param_ref(list:TAasmOutput;sz:TCgSize;const r:TReference;co
             reference_reset(ref);
             ref.base:=locpara.reference.index;
             ref.offset:=locpara.reference.offset;
-            tmpreg := get_scratch_reg_int(list);
+            tmpreg := get_scratch_reg_int(list,sz);
             a_load_ref_reg(list,sz,r,tmpreg);
             a_load_reg_ref(list,sz,tmpreg,ref);
             free_scratch_reg(list,tmpreg);
@@ -860,7 +860,7 @@ procedure TCgSparc.a_cmp_ref_reg_label(list:TAasmOutput;size:tcgsize;cmp_op:topc
   var
     TempReg:TRegister;
    begin
-     TempReg:=cg.get_scratch_reg_int(List);
+     TempReg:=cg.get_scratch_reg_int(List,size);
      a_load_ref_reg(list,OS_32,Ref,TempReg);
      list.concat(taicpu.op_reg_reg(A_SUBcc,TempReg,Reg));
      a_jmp_cond(list,cmp_op,l);
@@ -953,7 +953,7 @@ procedure TCgSparc.g_restore_frame_pointer(list:TAasmOutput);
 {This function intontionally does nothing as frame pointer is restored in the
 delay slot of the return instrucion done in g_return_from_proc}
   end;
-procedure TCgSparc.g_restore_standard_registers(list:taasmoutput;usedinproc:tregisterset);
+procedure TCgSparc.g_restore_standard_registers(list:taasmoutput;usedinproc:Tsupregset);
   begin
     {$WARNING FIX ME TCgSparc.g_restore_standard_registers}
   end;
@@ -987,7 +987,7 @@ procedure TCgSparc.g_save_all_registers(list : taasmoutput);
   begin
     {$warning FIX ME TCgSparc.g_save_all_registers}
   end;
-procedure TCgSparc.g_save_standard_registers(list : taasmoutput; usedinproc : tregisterset);
+procedure TCgSparc.g_save_standard_registers(list : taasmoutput; usedinproc:Tsupregset);
   begin
     {$warning FIX ME tcgppc.g_save_standard_registers}
   end;
@@ -1198,7 +1198,7 @@ procedure TCgSparc.g_concatcopy(list:taasmoutput;const source,dest:treference;le
             inc(src.offset,8);
             list.concat(taicpu.op_reg_const_reg(A_SUB,src.base,8,src.base));
             list.concat(taicpu.op_reg_const_reg(A_SUB,dst.base,8,dst.base));
-            countreg := get_scratch_reg_int(list);
+            countreg := get_scratch_reg_int(list,OS_32);
             a_load_const_reg(list,OS_32,count,countreg);
             { explicitely allocate R_O0 since it can be used safely here }
             { (for holding date that's being copied)                    }
@@ -1403,7 +1403,11 @@ BEGIN
 END.
 {
   $Log$
-  Revision 1.38  2003-02-18 22:00:20  mazen
+  Revision 1.39  2003-02-19 22:00:16  daniel
+    * Code generator converted to new register notation
+    - Horribily outdated todo.txt removed
+
+  Revision 1.38  2003/02/18 22:00:20  mazen
   * asm condition generation modified by TAiCpu.SetCondition
 
   Revision 1.37  2003/02/05 21:48:34  mazen

+ 110 - 41
compiler/sparc/cpubase.pas

@@ -191,9 +191,12 @@ TYPE
   { enumeration for registers, don't change the order }
   { it's used by the register size conversions        }
   ToldRegister=({$INCLUDE registers.inc});
+  Tnewregister=word;
+  Tsuperregister=byte;
+  Tsubregister=byte;
   Tregister=record
     enum:Toldregister;
-    number:word;
+    number:Tnewregister;
   end;
   TRegister64=PACKED RECORD
   {A type to store register locations for 64 Bit values.}
@@ -201,10 +204,83 @@ TYPE
   END;
   treg64=tregister64;{alias for compact code}
   TRegisterSet=SET OF ToldRegister;
+  Tsupregset=set of Tsuperregister;
 CONST
   R_NO=R_NONE;
   firstreg = low(Toldregister);
   lastreg  = high(R_ASR31);
+
+{General registers.}
+
+const
+  NR_NO=$0000;
+  NR_G0=$0001;
+  NR_G1=$0002;
+  NR_G2=$0003;
+  NR_G3=$0004;
+  NR_G4=$0005;
+  NR_G5=$0006;
+  NR_G6=$0007;
+  NR_G7=$0008;
+  NR_O0=$0100;
+  NR_O1=$0200;
+  NR_O2=$0300;
+  NR_O3=$0400;
+  NR_O4=$0500;
+  NR_O5=$0600;
+  NR_O6=$0700;
+  NR_O7=$0800;
+  NR_L0=$0900;
+  NR_L1=$0A00;
+  NR_L2=$0B00;
+  NR_L3=$0C00;
+  NR_L4=$0D00;
+  NR_L5=$0E00;
+  NR_L6=$0F00;
+  NR_L7=$1000;
+  NR_I0=$1100;
+  NR_I1=$1200;
+  NR_I2=$1300;
+  NR_I3=$1400;
+  NR_I4=$1500;
+  NR_I5=$1600;
+  NR_I6=$1700;
+  NR_I7=$1800;
+
+{Superregisters.}
+
+const
+  RS_O0=$01;
+  RS_O1=$02;
+  RS_O2=$03;
+  RS_O3=$04;
+  RS_O4=$05;
+  RS_O5=$06;
+  RS_O6=$07;
+  RS_O7=$08;
+  RS_L0=$09;
+  RS_L1=$0A;
+  RS_L2=$0B;
+  RS_L3=$0C;
+  RS_L4=$0D;
+  RS_L5=$0E;
+  RS_L6=$0F;
+  RS_L7=$10;
+  RS_I0=$11;
+  RS_I1=$12;
+  RS_I2=$13;
+  RS_I3=$14;
+  RS_I4=$15;
+  RS_I5=$16;
+  RS_I6=$17;
+  RS_I7=$18;
+
+  first_supreg = $01;
+  last_supreg = $18;
+
+  {Subregisters; nothing known about.}
+  R_SUBWHOLE=$00;
+  R_SUBL=$00;
   
 type
   reg2strtable=ARRAY[firstreg..lastreg] OF STRING[7];
@@ -361,6 +437,7 @@ used, because contains a lot of unnessary fields.}
 
 const
   general_registers = [R_G0..R_I7];
+  general_superregisters = [RS_O0..RS_I7];
   { legend:                                                                }
   { xxxregs = set of all possibly used registers of that type in the code  }
   {           generator                                                    }
@@ -370,7 +447,7 @@ const
   {           passing on ABI's that define this)                           }
   { c_countusableregsxxx = amount of registers in the usableregsxxx set    }
   IntRegs=[R_G0..R_I7];
-  usableregsint=[R_O0..R_I7];
+  usableregsint=[RS_O0..RS_I7];
   c_countusableregsint = 24;
   fpuregs=[R_F0..R_F31];
   usableregsfpu=[R_F0..R_F31];
@@ -385,8 +462,8 @@ const
   c_countusableregsaddr = 0;
   
   
-  firstsaveintreg = R_O0;
-  lastsaveintreg = R_I7;
+  firstsaveintreg = RS_O0;
+  lastsaveintreg = RS_I7;
   firstsavefpureg = R_F0;
   lastsavefpureg = R_F31;
   firstsavemmreg = R_I0;
@@ -395,6 +472,7 @@ const
   highsavereg = R_I7;
 
   ALL_REGISTERS = [lowsavereg..highsavereg];
+  ALL_INTREGISTERS = [1..255];
 
   lvaluelocations = [LOC_REFERENCE,LOC_CFPUREGISTER,
     LOC_CREGISTER,LOC_MMXREGISTER,LOC_CMMXREGISTER];
@@ -407,22 +485,36 @@ const
   stab_regindex:ARRAY[firstreg..lastreg]OF ShortInt=({$INCLUDE stabregi.inc});
 {*************************** generic register names **************************}
   stack_pointer_reg   = R_O6;
+  NR_STACK_POINTER_REG = NR_O6;
+  RS_STACK_POINTER_REG = RS_O6;
   frame_pointer_reg   = R_I6;
+  NR_FRAME_POINTER_REG = NR_I6;
+  RS_FRAME_POINTER_REG = RS_I6;
   {the return_result_reg, is used inside the called function to store its return
   value when that is a scalar value otherwise a pointer to the address of the
   result is placed inside it}
   return_result_reg   = R_I0;
+  NR_RETURN_RESULT_REG = NR_I0;
+  RS_RETURN_RESULT_REG = RS_I0;
   {the function_result_reg contains the function result after a call to a scalar
   function othewise it contains a pointer to the returned result}
   function_result_reg = R_O0;
+  NR_FUNCTION_RESULT_REG = NR_O0;
+  RS_FUNCTION_RESULT_REG = RS_O0;
   self_pointer_reg  =R_G5;
+  NR_SELF_POINTER_REG = NR_G5;
+{  RS_SELF_POINTER_REG = RS_G5;}
   {There is no accumulator in the SPARC architecture. There are just families
   of registers. All registers belonging to the same family are identical except
   in the "global registers" family where GO is different from the others :
   G0 gives always 0 when it is red and thows away any value written to it.
   Nevertheless, scalar routine results are returned onto R_O0.}
   accumulator     = R_O0;
+  NR_ACCUMULATOR = NR_O0;
+  RS_ACCUMULATOR = RS_O1;
   accumulatorhigh = R_O1;
+  NR_ACCUMULATORHIGH = NR_O1;
+  RS_ACCUMULATORHIGH = RS_O1;
   fpu_result_reg  =R_F0;
   mmresultreg     =R_G0;
 {*****************************************************************************}
@@ -434,7 +526,7 @@ as defined in the target ABI and / or GCC.
 
 This value can be deduced from the CALLED_USED_REGISTERS array in the GCC
 source.}
-  std_saved_registers=[R_O6];
+  std_saved_registers=[RS_O6];
 {# Required parameter alignment when calling a routine declared as stdcall and
 cdecl. The alignment value should be the one defined by GCC or the target ABI.
 
@@ -444,7 +536,7 @@ PARM_BOUNDARY / BITS_PER_UNIT in the GCC source.}
 {# Registers which are defined as scratch and no need to save across routine
 calls or in assembler blocks.}
   ScratchRegsCount=8;
-  scratch_regs:ARRAY[1..ScratchRegsCount]OF ToldRegister=(R_L0,R_L1,R_L2,R_L3,R_L4,R_L5,R_L6,R_L7);
+  scratch_regs:ARRAY[1..ScratchRegsCount] OF Tsuperregister=(RS_L0,RS_L1,RS_L2,RS_L3,RS_L4,RS_L5,RS_L6,RS_L7);
 { low and high of the available maximum width integer general purpose }
 { registers                                                           }
   LoGPReg = R_G0;
@@ -505,6 +597,7 @@ const
 FUNCTION is_calljmp(o:tasmop):boolean;
 FUNCTION flags_to_cond(CONST f:TResFlags):TAsmCond;
 procedure convert_register_to_enum(var r:Tregister);
+function cgsize2subreg(s:Tcgsize):Tsubregister;
 
 IMPLEMENTATION
 
@@ -529,40 +622,6 @@ function flags_to_cond(const f:TResFlags):TAsmCond;
   END;
 
 procedure convert_register_to_enum(var r:Tregister);
-const
-  NR_NO=$0000;
-  NR_G0=$0001;
-  NR_G1=$0002;
-  NR_G2=$0003;
-  NR_G3=$0004;
-  NR_G4=$0005;
-  NR_G5=$0006;
-  NR_G6=$0007;
-  NR_G7=$0008;
-  NR_O0=$0100;
-  NR_O1=$0200;
-  NR_O2=$0300;
-  NR_O3=$0400;
-  NR_O4=$0500;
-  NR_O5=$0600;
-  NR_O6=$0700;
-  NR_O7=$0800;
-  NR_L0=$0900;
-  NR_L1=$0A00;
-  NR_L2=$0B00;
-  NR_L3=$0C00;
-  NR_L4=$0D00;
-  NR_L5=$0E00;
-  NR_L6=$0F00;
-  NR_L7=$1000;
-  NR_I0=$1100;
-  NR_I1=$1200;
-  NR_I2=$1300;
-  NR_I3=$1400;
-  NR_I4=$1500;
-  NR_I5=$1600;
-  NR_I6=$1700;
-  NR_I7=$1800;
 begin
   if r.enum=R_INTREGISTER
   then
@@ -605,13 +664,23 @@ begin
     end;
 end;
 
+function cgsize2subreg(s:Tcgsize):Tsubregister;
+
+begin
+  cgsize2subreg:=R_SUBWHOLE;
+end;
+
 END.
 
 
 
 {
   $Log$
-  Revision 1.22  2003-02-02 19:25:54  carl
+  Revision 1.23  2003-02-19 22:00:17  daniel
+    * Code generator converted to new register notation
+    - Horribily outdated todo.txt removed
+
+  Revision 1.22  2003/02/02 19:25:54  carl
     * Several bugfixes for m68k target (register alloc., opcode emission)
     + VIS target
     + Generic add more complete (still not verified)

+ 20 - 16
compiler/sparc/ncpuadd.pas

@@ -612,11 +612,11 @@ procedure TSparcAddNode.second_add64bit;
                         begin
                           if (right.location.valueqword <> 0)
                           then
-                            tempreg64.reglo := cg.get_scratch_reg_int(exprasmlist)
+                            tempreg64.reglo := cg.get_scratch_reg_int(exprasmlist,OS_INT)
                           else
                             tempreg64.reglo := left.location.registerlow;
                           if ((right.location.valueqword shr 32) <> 0) then
-                            tempreg64.reghi := cg.get_scratch_reg_int(exprasmlist)
+                            tempreg64.reghi := cg.get_scratch_reg_int(exprasmlist,OS_INT)
                           else
                             tempreg64.reghi := left.location.registerhigh;
                         end;
@@ -647,8 +647,8 @@ procedure TSparcAddNode.second_add64bit;
                     end
                   else
                     begin
-                       tempreg64.reglo := cg.get_scratch_reg_int(exprasmlist);
-                       tempreg64.reghi := cg.get_scratch_reg_int(exprasmlist);
+                       tempreg64.reglo := cg.get_scratch_reg_int(exprasmlist,OS_INT);
+                       tempreg64.reghi := cg.get_scratch_reg_int(exprasmlist,OS_INT);
                        cg64.a_op64_reg_reg_reg(exprasmlist,OP_XOR,
                          left.location.register64,right.location.register64,
                          tempreg64);
@@ -671,8 +671,8 @@ procedure TSparcAddNode.second_add64bit;
                 begin
                   if (location.registerlow.enum = R_NO) then
                     begin
-                      location.registerlow := rg.getregisterint(exprasmlist);
-                      location.registerhigh := rg.getregisterint(exprasmlist);
+                      location.registerlow := rg.getregisterint(exprasmlist,OS_INT);
+                      location.registerhigh := rg.getregisterint(exprasmlist,OS_INT);
                     end;
 
                   if (left.location.loc = LOC_CONSTANT) then
@@ -693,8 +693,8 @@ procedure TSparcAddNode.second_add64bit;
                     begin
                       if (location.registerlow.enum = R_NO) then
                         begin
-                         location.registerlow := rg.getregisterint(exprasmlist);
-                         location.registerhigh := rg.getregisterint(exprasmlist);
+                         location.registerlow := rg.getregisterint(exprasmlist,OS_INT);
+                         location.registerhigh := rg.getregisterint(exprasmlist,OS_INT);
                       end;
                       if right.location.loc <> LOC_CONSTANT then
                         // reg64 - reg64
@@ -711,8 +711,8 @@ procedure TSparcAddNode.second_add64bit;
                     begin
                       if (location.registerlow.enum = R_NO) then
                         begin
-                         location.registerlow := rg.getregisterint(exprasmlist);
-                         location.registerhigh := rg.getregisterint(exprasmlist);
+                         location.registerlow := rg.getregisterint(exprasmlist,OS_INT);
+                         location.registerhigh := rg.getregisterint(exprasmlist,OS_INT);
                       end;
                       if (int64(left.location.valueqword) >= low(smallint)) and
                          (int64(left.location.valueqword) <= high(smallint))
@@ -738,8 +738,8 @@ procedure TSparcAddNode.second_add64bit;
                       // (const32 shl 32) - reg64
                       if (location.registerlow.enum = R_NO) then
                         begin
-                         location.registerlow := rg.getregisterint(exprasmlist);
-                         location.registerhigh := rg.getregisterint(exprasmlist);
+                         location.registerlow := rg.getregisterint(exprasmlist,OS_INT);
+                         location.registerhigh := rg.getregisterint(exprasmlist,OS_INT);
                       end;
                       exprasmlist.concat(taicpu.op_reg_Const_reg(A_SUBcc,location.registerlow,0,right.location.registerlow));
                       cg.a_load_const_reg(exprasmlist,OS_INT,
@@ -757,8 +757,8 @@ procedure TSparcAddNode.second_add64bit;
                         location.register64 := left.location.register64
                       else if (location.registerlow.enum = R_NO) then
                         begin
-                         location.registerlow := rg.getregisterint(exprasmlist);
-                         location.registerhigh := rg.getregisterint(exprasmlist);
+                         location.registerlow := rg.getregisterint(exprasmlist,OS_INT);
+                         location.registerhigh := rg.getregisterint(exprasmlist,OS_INT);
                         end;
                       cg64.a_op64_reg_reg_reg(exprasmlist,OP_SUB,
                         right.location.register64,left.location.register64,
@@ -1015,7 +1015,7 @@ procedures }
     load_left_right(cmpop,(cs_check_overflow in aktlocalswitches)and(nodetype in [addn,subn,muln]));
     if(location.register.enum = R_NO)and not(cmpop)
     then
-      location.register := rg.getregisterint(exprasmlist);
+      location.register := rg.getregisterint(exprasmlist,OS_INT);
     if not(cs_check_overflow in aktlocalswitches)or cmpop or (nodetype in [orn,andn,xorn])
     then
       begin
@@ -1111,7 +1111,11 @@ begin
 end.
 {
     $Log$
-    Revision 1.9  2003-02-13 21:15:18  mazen
+    Revision 1.10  2003-02-19 22:00:17  daniel
+      * Code generator converted to new register notation
+      - Horribily outdated todo.txt removed
+
+    Revision 1.9  2003/02/13 21:15:18  mazen
     + Load_left_right and clear_left_right implemented fixing test0001 register
     allocation bug.
 

+ 11 - 7
compiler/sparc/ncpucnv.pas

@@ -203,7 +203,7 @@ procedure TSparctypeconvnode.second_int_to_real;
           if signed
           then
             begin
-              valuereg := cg.get_scratch_reg_int(exprasmlist);
+              valuereg := cg.get_scratch_reg_int(exprasmlist,OS_INT);
               valuereg_is_scratch := true;
             end
           else
@@ -211,7 +211,7 @@ procedure TSparctypeconvnode.second_int_to_real;
         end;
       LOC_REFERENCE,LOC_CREFERENCE:
         begin
-          leftreg := cg.get_scratch_reg_int(exprasmlist);
+          leftreg := cg.get_scratch_reg_int(exprasmlist,OS_INT);
           valuereg := leftreg;
           valuereg_is_scratch := true;
           cg.a_load_ref_reg(exprasmlist,def_cgsize(left.resulttype.def),
@@ -220,7 +220,7 @@ procedure TSparctypeconvnode.second_int_to_real;
       else
         internalerror(200110012);
     end;
-      tempreg := cg.get_scratch_reg_int(exprasmlist);
+      tempreg := cg.get_scratch_reg_int(exprasmlist,OS_32);
       {$WARNING FIXME what really should be done?}
       exprasmlist.concat(taicpu.op_reg_const_reg(A_OR,tempreg,$4330,tempreg));
       cg.a_load_reg_ref(exprasmlist,OS_32,tempreg,ref);
@@ -292,19 +292,19 @@ procedure TSparctypeconvnode.second_int_to_bool;
           then
             begin
               reference_release(exprasmlist,left.location.reference);
-              hreg2:=rg.getregisterint(exprasmlist);
+              hreg2:=rg.getregisterint(exprasmlist,opsize);
               cg.a_load_ref_reg(exprasmlist,opsize,left.location.reference,hreg2);
             end
           else
             hreg2 := left.location.register;
-            hreg1 := rg.getregisterint(exprasmlist);
+            hreg1 := rg.getregisterint(exprasmlist,opsize);
             exprasmlist.concat(taicpu.op_reg_const_reg(A_SUB,hreg1,1,hreg2));
             exprasmlist.concat(taicpu.op_reg_reg_reg(A_SUB,hreg1,hreg1,hreg2));
             rg.ungetregister(exprasmlist,hreg2);
         end;
       LOC_FLAGS :
         begin
-          hreg1:=rg.getregisterint(exprasmlist);
+          hreg1:=rg.getregisterint(exprasmlist,location.size);
           resflags:=left.location.resflags;
           cg.g_flags2reg(exprasmlist,location.size,resflags,hreg1);
         end;
@@ -388,7 +388,11 @@ begin
 end.
 {
   $Log$
-  Revision 1.11  2003-01-22 20:45:15  mazen
+  Revision 1.12  2003-02-19 22:00:17  daniel
+    * Code generator converted to new register notation
+    - Horribily outdated todo.txt removed
+
+  Revision 1.11  2003/01/22 20:45:15  mazen
   * making math code in RTL compiling.
   *NB : This does NOT mean necessary that it will generate correct code!
 

+ 16 - 12
compiler/sparc/ncpumat.pas

@@ -95,12 +95,12 @@ implementation
          if (location.loc = LOC_CREGISTER) then
            begin
              location.loc := LOC_REGISTER;
-             location.register := rg.getregisterint(exprasmlist);
+             location.register := rg.getregisterint(exprasmlist,OS_INT);
              resultreg := location.register;
            end;
          if (nodetype = modn) then
            begin
-             resultreg := cg.get_scratch_reg_int(exprasmlist);
+             resultreg := cg.get_scratch_reg_int(exprasmlist,OS_INT);
            end;
 
          if (nodetype = divn) and
@@ -191,8 +191,8 @@ procedure tSparcshlshrnode.pass_2;
         then
           begin
             location.loc := LOC_REGISTER;
-            location.registerhigh := rg.getregisterint(exprasmlist);
-            location.registerlow := rg.getregisterint(exprasmlist);
+            location.registerhigh := rg.getregisterint(exprasmlist,OS_INT);
+            location.registerlow := rg.getregisterint(exprasmlist,OS_INT);
           end;
         if (right.nodetype = ordconstn)
         then
@@ -254,7 +254,7 @@ procedure tSparcshlshrnode.pass_2;
                 location.registerlow := resultreg;
               end;
             r.enum:=R_G0;
-            rg.getexplicitregisterint(exprasmlist,R_G0);
+            rg.getexplicitregisterint(exprasmlist,NR_G0);
 {            exprasmlist.concat(taicpu.op_reg_reg_const(A_SUBFIC,R_0,hregister1,32));
             exprasmlist.concat(taicpu.op_reg_reg_reg(asmop1,location.registerhigh,hregisterhigh,hregister1));
             exprasmlist.concat(taicpu.op_reg_reg_reg(asmop2,R_0,hregisterlow,R_0));
@@ -282,7 +282,7 @@ procedure tSparcshlshrnode.pass_2;
         then
           begin
             location.loc := LOC_REGISTER;
-            resultreg := rg.getregisterint(exprasmlist);
+            resultreg := rg.getregisterint(exprasmlist,OS_INT);
             location.register := resultreg;
           end;
         { determine operator }
@@ -323,8 +323,8 @@ procedure tSparcshlshrnode.pass_2;
              location_copy(location,left.location);
              if (location.loc = LOC_CREGISTER) then
                begin
-                 location.registerlow := rg.getregisterint(exprasmlist);
-                 location.registerhigh := rg.getregisterint(exprasmlist);
+                 location.registerlow := rg.getregisterint(exprasmlist,OS_INT);
+                 location.registerhigh := rg.getregisterint(exprasmlist,OS_INT);
                  location.loc := LOC_CREGISTER;
                end;
              exprasmlist.concat(taicpu.op_reg_const_reg(A_SUB,location.registerlow,0,left.location.registerlow));
@@ -347,7 +347,7 @@ procedure tSparcshlshrnode.pass_2;
                   begin
                      src1 := left.location.register;
                      if left.location.loc = LOC_CREGISTER then
-                       location.register := rg.getregisterint(exprasmlist)
+                       location.register := rg.getregisterint(exprasmlist,OS_INT)
                      else
                        location.register := rg.getregisterfpu(exprasmlist);
                   end;
@@ -363,7 +363,7 @@ procedure tSparcshlshrnode.pass_2;
                        end
                      else
                        begin
-                          src1 := rg.getregisterint(exprasmlist);
+                          src1 := rg.getregisterint(exprasmlist,OS_32);
                           location.register:= src1;
                           cg.a_load_ref_reg(exprasmlist,OS_32,
                             left.location.reference,src1);
@@ -464,7 +464,7 @@ begin
       location_copy(location,left.location);
       if location.loc=LOC_CREGISTER
       then
-        location.register := rg.getregisterint(exprasmlist);
+        location.register := rg.getregisterint(exprasmlist,OS_INT);
         { perform the NOT operation }
         exprasmlist.concat(taicpu.op_reg_reg(A_NOT,location.register,
         left.location.register));
@@ -478,7 +478,11 @@ begin
 end.
 {
   $Log$
-  Revision 1.4  2003-02-04 21:50:54  mazen
+  Revision 1.5  2003-02-19 22:00:17  daniel
+    * Code generator converted to new register notation
+    - Horribily outdated todo.txt removed
+
+  Revision 1.4  2003/02/04 21:50:54  mazen
   * fixing internal errors related to notn when compiling RTL
 
   Revision 1.3  2003/01/08 18:43:58  daniel

+ 19 - 8
compiler/sparc/rgcpu.pas

@@ -33,40 +33,51 @@ code generator to allocate and free registers which might be valid across
 nodes. It also contains utility routines related to registers. Some of the
 methods in this class overrides generic implementations in rgobj.pas.}
   trgcpu=class(trgobj)
-    function GetExplicitRegisterInt(list:taasmoutput;Reg:Toldregister):tregister;override;
+    function GetExplicitRegisterInt(list:taasmoutput;Reg:Tnewregister):tregister;override;
     procedure UngetregisterInt(list:taasmoutput;Reg:tregister);override;
   end;
 implementation
 uses
-  cgobj;
-function trgcpu.GetExplicitRegisterInt(list:taasmoutput;reg:Toldregister):tregister;
+  cgobj,verbose;
+
+function trgcpu.GetExplicitRegisterInt(list:taasmoutput;reg:Tnewregister):tregister;
 
 var r:Tregister;
 
   begin
-    if reg in [R_O7,R_I7]
+    if (reg=RS_O7) or (reg=NR_I7)
     then
       begin
-        r.enum:=reg;
+        r.enum:=R_INTREGISTER;
+        r.number:=reg;
         cg.a_reg_alloc(list,r);
         result := r;
       end
     else result := inherited GetExplicitRegisterInt(list,reg);
   end;
+
 procedure trgcpu.UngetregisterInt(list: taasmoutput; reg: tregister);
+
   begin
-    if reg.enum in [R_O7,R_I7]
+    if reg.enum<>R_INTREGISTER then
+      internalerror(200302191);
+    if (reg.number=RS_O7) or (reg.number=NR_I7)
     then
       cg.a_reg_dealloc(list,reg)
     else
       inherited ungetregisterint(list,reg);
   end;
-initialization
+
+begin
   rg := trgcpu.create;
 end.
 {
   $Log$
-  Revision 1.5  2003-01-08 18:43:58  daniel
+  Revision 1.6  2003-02-19 22:00:17  daniel
+    * Code generator converted to new register notation
+    - Horribily outdated todo.txt removed
+
+  Revision 1.5  2003/01/08 18:43:58  daniel
    * Tregister changed into a record
 
   Revision 1.4  2002/10/13 21:46:07  mazen

+ 15 - 6
compiler/symdef.pas

@@ -518,7 +518,8 @@ interface
           { check the problems of manglednames }
           has_mangledname : boolean;
           { small set which contains the modified registers }
-          usedregisters : tregisterset;
+          usedintregisters:Tsupregset;
+          usedotherregisters:Tregisterset;
           constructor create;
           constructor ppuload(ppufile:tcompilerppufile);
           destructor  destroy;override;
@@ -3381,7 +3382,8 @@ implementation
           end;
          lastref:=defref;
        { first, we assume that all registers are used }
-         usedregisters:=ALL_REGISTERS;
+         usedintregisters:=ALL_INTREGISTERS;
+         usedotherregisters:=ALL_REGISTERS;
          forwarddef:=true;
          interfacedef:=false;
          hasforward:=false;
@@ -3400,7 +3402,8 @@ implementation
          inherited ppuload(ppufile);
          deftype:=procdef;
 
-         ppufile.getnormalset(usedregisters);
+         ppufile.getnormalset(usedintregisters);
+         ppufile.getnormalset(usedotherregisters);
          has_mangledname:=boolean(ppufile.getbyte);
          if has_mangledname then
           _mangledname:=stringdup(ppufile.getstring)
@@ -3522,10 +3525,12 @@ implementation
          { set all registers to used for simplified compilation PM }
          if simplify_ppu then
            begin
-             usedregisters:=ALL_REGISTERS;
+             usedintregisters:=ALL_INTREGISTERS;
+             usedotherregisters:=ALL_REGISTERS;
            end;
 
-         ppufile.putnormalset(usedregisters);
+         ppufile.putnormalset(usedintregisters);
+         ppufile.putnormalset(usedotherregisters);
          ppufile.do_interface_crc:=oldintfcrc;
          ppufile.putbyte(byte(has_mangledname));
          if has_mangledname then
@@ -5651,7 +5656,11 @@ implementation
 end.
 {
   $Log$
-  Revision 1.128  2003-02-02 19:25:54  carl
+  Revision 1.129  2003-02-19 22:00:14  daniel
+    * Code generator converted to new register notation
+    - Horribily outdated todo.txt removed
+
+  Revision 1.128  2003/02/02 19:25:54  carl
     * Several bugfixes for m68k target (register alloc., opcode emission)
     + VIS target
     + Generic add more complete (still not verified)

+ 15 - 11
compiler/tgobj.pas

@@ -438,22 +438,22 @@ unit tgobj;
          { ref.index = R_NO was missing
            led to problems with local arrays
            with lower bound > 0 (PM) }
-         if ref.base.enum>lastreg then
-           internalerror(200301081);
-         if ref.index.enum>lastreg then
-           internalerror(200301081);
-         if procinfo.framepointer.enum>lastreg then
-           internalerror(200301081);
+         if ref.base.enum<>R_INTREGISTER then
+           internalerror(200301225);
+         if ref.index.enum<>R_INTREGISTER then
+           internalerror(200301225);
+         if procinfo.framepointer.enum<>R_INTREGISTER then
+           internalerror(200301225);
          if direction = 1 then
            begin
-             istemp:=((ref.base.enum=procinfo.framepointer.enum) and
-                     (ref.index.enum=R_NO) and
+             istemp:=((ref.base.number=procinfo.framepointer.number) and
+                     (ref.index.number=NR_NO) and
                       (ref.offset>firsttemp));
            end
         else
            begin
-             istemp:=((ref.base.enum=procinfo.framepointer.enum) and
-                     (ref.index.enum=R_NO) and
+             istemp:=((ref.base.number=procinfo.framepointer.number) and
+                     (ref.index.number=NR_NO) and
                       (ref.offset<firsttemp));
            end;
       end;
@@ -542,7 +542,11 @@ finalization
 end.
 {
   $Log$
-  Revision 1.25  2003-02-03 23:10:39  daniel
+  Revision 1.26  2003-02-19 22:00:15  daniel
+    * Code generator converted to new register notation
+    - Horribily outdated todo.txt removed
+
+  Revision 1.25  2003/02/03 23:10:39  daniel
     * Fixed last commit
 
   Revision 1.24  2003/02/03 23:07:39  daniel

+ 0 - 106
compiler/todo.txt

@@ -1,106 +0,0 @@
-$Id$
-This list contains tasks which should be done til version 1.0.
-Don't hesitate to insert jobs :)
-Don't insert bugs there, for this purpose is the bugs directory.
-
-Please indent task which are done 8 spaces and add the
-compiler version and your short cut.
-
-* OPOM (Object Pascal Object Modell)
-        - virtual constructors ................................... 0.99.6 (FK)
-  * properties
-        - save the def and not the sym which
-          does read/write access ................................. 0.99.6 (FK)
-        - indexed properties ..................................... 0.99.6 (FK)
-        - default properties ..................................... 0.99.6 (FK)
-    - save array for overriding
-        - stored qualifier ...................................... 0.99.11 (FK)
-        - read/write from/to unit file ........................... 0.99.6 (FK)
-        - call of destructor helper routine ..................... 0.99.11 (FK)
-        - message qualifier ..................................... 0.99.11 (FK)
-        - correct handling of constructor result type ............ 0.99.6 (FK)
-        - rtti ................................................... 0.99.8 (FK)
-        - published .............................................. 0.99.8 (FK)
-  - dynamic methods
-        - correct handling of access specifiers .................. 0.99.7 (FK)
-  - interface
-* rtti
-          - generation ........................................... 0.99.7 (FK)
-          - use when copying etc. ................................ 0.99.7 (FK)
-          - new/dispose should look for rtti'ed data ............. 0.99.8 (FK)
-          - enumeration names ................................... 0.99.11 (FK)
-  - methodpointers
-  - change booleans into enumerations
-* AnsiString
-          - operators ........................................... 0.99.11 (FK)
-          - indexed access ...................................... 0.99.11 (FK)
-          - type conversions .................................... 0.99.11 (FK)
-* LongString and WideString
-* MMX support by the compiler
-          - unary minus .......................................... 0.99.1 (FK)
-          - proper handling of fixed type ........................ 0.99.1 (FK)
-  - array access
-          - binary operators ..................................... 0.99.1 (FK)
-          - mul operator ......................................... 0.99.1 (FK)
-  * special functions
-    - lo function
-    - pack/unpack function
-  - div by 2^n
-  - function results
-  - shift operators
-  - andn optimization
-  - muladdn optimization
-  - comparisations
-  - KNI
-  - 3DNow
-* Delphi 4 support
-  - overloaded directive
-  - default parameters
-  - dynamic arrays
-  - 64 bit int
-* QWord
-  - constants
-  - case
-  - for
-  - inc/dec
-  - read
-        - write ................................................. 0.99.13 (FK)
-        - str ................................................... 0.99.13 (FK)
-  - val
-  - range checking
-  - type cast QWord -> real
-        - lo/hi testing ......................................... 0.99.13 (FK)
-        - overflow checking test ................................ 0.99.13 (FK)
-* Misc
-        - array of const as subroutine parameter ................ 0.99.9 (PFV)
-        - open array with call by value ......................... 0.99.6 (FK)
-        - subrange types of enumerations ........................ 0.99.7 (PFV)
-        - code generation for exceptions ........................ 0.99.7 (FK)
-        - assertation ........................................... 0.99.9 (PFV)
-        - add abstract virtual method runtime error (210) ....... 0.99.1 (FK)
-        - add debug info $D switch .............................. 0.99.1 (FK)
-        - add strict var strings check $V switch ................ 0.99.1 (FK)
-        - make dec/inc internal.................................. 0.99.6 (PFV)
-        - make length internal................................... 0.99.7 (PFV)
-        - range checking for open arrays......................... 0.99.11 (PFV)
-        - method pointers (procedure of object) ................. 0.99.11 (FK)
-        - open strings, $P....................................... 0.99.10 (PFV)
-        - include/exclude........................................ 0.99.10 (PM)
-- fix all bugs of the bug directory
-- sysutils unit for go32v2 (exceptions!)
-        - initialisation/finalization for units ................. 0.99.11 (PFV)
-- fixed data type
-- add alignment $A switch
-- $B
-
-Future versions
----------------
-1.1
-  - full MT support in rtl
-  - synchronized keyword
-  - interfaces 
-  - lineinfo in the executable which can be showed instead
-    of addresses
-2.0
-  - new code generator
-  - complete inline support

+ 56 - 4
compiler/vis/cpubase.pas

@@ -79,10 +79,11 @@ uses
 
       {# Set type definition for registers }
       tregisterset = set of Toldregister;
+      Tnewregister=word;
       
       tregister=record
         enum:toldregister;
-        number:word;
+        number:Tnewregister;
       end;
 
       { A type to store register locations for 64 Bit values. }
@@ -90,6 +91,11 @@ uses
         reglo,reghi : tregister;
       end;
 
+      Tsuperregister=byte;
+      Tsubregister=byte;
+
+      Tsupregset=set of Tsuperregister;
+
       { alias for compact code }
       treg64 = tregister64;
 
@@ -108,12 +114,28 @@ uses
       NR_R3 = $0400; NR_R4 = $0500; NR_R5 = $0600;
       NR_R6 = $0700; NR_R7 = $0800; NR_R8 = $0900;
       NR_R9 = $0A00; NR_R10 = $0B00; NR_R11 = $0C00;
+      NR_SP = $0D00; NR_FP = $0E00;
+
+    {Super registers:}
+      RS_R0 = $01; RS_R1 = $02; RS_R2 = $03;
+      RS_R3 = $04; RS_R4 = $05; RS_R5 = $06;
+      RS_R6 = $07; RS_R7 = $08; RS_R8 = $09;
+      RS_R9 = $0A; RS_R10 = $0B; RS_R11 = $0C;
+      RS_SP = $0D; RS_FP = $0E;
+
+    {Subregisters:}
+      R_SUBL = $00;
+      R_SUBW = $01;
+      R_SUBD = $02;
 
       {# First register in the tregister enumeration }
       firstreg = low(toldregister);
       {# Last register in the tregister enumeration }
       lastreg  = high(toldregister);
 
+      first_supreg = $01;
+      last_supreg = $0c;
+
 
       std_reg2str : treg2strtable = ('',
         'r0','r1','r2','r3','r4','r5','r6','r7','r8','r9','r10','r11','ccr',
@@ -415,7 +437,7 @@ uses
          routine calls or in assembler blocks.
       }
       max_scratch_regs = 2;
-      scratch_regs: Array[1..max_scratch_regs] of toldregister = (R_R0,R_R1);
+      scratch_regs: Array[1..max_scratch_regs] of Tsuperregister = (RS_R0,RS_R1);
 
 {*****************************************************************************
                           Default generic sizes
@@ -462,17 +484,25 @@ uses
 
       {# Stack pointer register }
       stack_pointer_reg = R_SP;
+      NR_STACK_POINTER_REG = NR_SP;
+      RS_STACK_POINTER_REG = RS_SP;
       {# Frame pointer register }
       frame_pointer_reg = R_FP;
+      NR_FRAME_POINTER_REG = NR_FP;
+      RS_FRAME_POINTER_REG = RS_FP;
       {# Self pointer register : contains the instance address of an
          object or class. }
       self_pointer_reg  = R_R11;
+      NR_SELF_POINTER_REG = NR_R11;
+      RS_SELF_POINTER_REG = RS_R11;
       {# Register for addressing absolute data in a position independant way,
          such as in PIC code. The exact meaning is ABI specific. 
       }
       pic_offset_reg = R_R10;
       {# Results are returned in this register (32-bit values) }
       accumulator   = R_R0;
+      NR_ACCUMULATOR = NR_R0;
+      RS_ACCUMULATOR = RS_R0;
   {the return_result_reg, is used inside the called function to store its return
   value when that is a scalar value otherwise a pointer to the address of the
   result is placed inside it}
@@ -483,6 +513,8 @@ uses
     function_result_reg =   accumulator;
       {# Hi-Results are returned in this register (64-bit value high register) }
       accumulatorhigh = R_R1;
+      NR_ACCUMULATORHIGH = NR_R1;
+      RS_ACCUMULATORHIGH = RS_R1;
       fpu_result_reg = R_FP0;
       mmresultreg = R_NO;
 
@@ -497,7 +529,7 @@ uses
          This value can be deduced from CALLED_USED_REGISTERS array in the
          GCC source.
       }
-      std_saved_registers = [R_R0,R_R1,R_R10,R_R11];
+      std_saved_registers = [RS_R0,RS_R1,RS_R10,RS_R11];
       {# Required parameter alignment when calling a routine declared as
          stdcall and cdecl. The alignment value should be the one defined
          by GCC or the target ABI.
@@ -517,6 +549,7 @@ uses
     procedure inverse_flags(var r : TResFlags);
     function  flags_to_cond(const f: TResFlags) : TAsmCond;
     procedure convert_register_to_enum(var r:Tregister);
+    function cgsize2subreg(s:Tcgsize):Tsubregister;
 
 
 implementation
@@ -592,11 +625,30 @@ implementation
         end;
     end;
 
+    function cgsize2subreg(s:Tcgsize):Tsubregister;
+
+    begin
+      case s of
+        OS_8,OS_S8:
+          cgsize2subreg:=R_SUBL;
+        OS_16,OS_S16:
+          cgsize2subreg:=R_SUBW;
+        OS_32,OS_S32:
+          cgsize2subreg:=R_SUBD;
+        else
+          internalerror(200301231);
+      end;
+    end;
+
 
 end.
 {
   $Log$
-  Revision 1.4  2003-02-02 19:25:54  carl
+  Revision 1.5  2003-02-19 22:00:17  daniel
+    * Code generator converted to new register notation
+    - Horribily outdated todo.txt removed
+
+  Revision 1.4  2003/02/02 19:25:54  carl
     * Several bugfixes for m68k target (register alloc., opcode emission)
     + VIS target
     + Generic add more complete (still not verified)

+ 152 - 128
compiler/x86/cgx86.pas

@@ -120,8 +120,8 @@ unit cgx86;
         procedure g_call_destructor_helper(list : taasmoutput);override;
         procedure g_call_fail_helper(list : taasmoutput);override;
 {$endif}
-        procedure g_save_standard_registers(list : taasmoutput; usedinproc : tregisterset);override;
-        procedure g_restore_standard_registers(list : taasmoutput; usedinproc : tregisterset);override;
+        procedure g_save_standard_registers(list:Taasmoutput;usedinproc:Tsupregset);override;
+        procedure g_restore_standard_registers(list:Taasmoutput;usedinproc:Tsupregset);override;
         procedure g_save_all_registers(list : taasmoutput);override;
         procedure g_restore_all_registers(list : taasmoutput;selfused,accused,acchiused:boolean);override;
 
@@ -322,12 +322,17 @@ unit cgx86;
           OS_16,OS_S16:
             begin
               if target_info.alignment.paraalign = 2 then
-                list.concat(taicpu.op_reg(A_PUSH,S_W,rg.makeregsize(r,OS_16)))
+                r.number:=(r.number and not $ff) or R_SUBW
               else
-                list.concat(taicpu.op_reg(A_PUSH,S_L,rg.makeregsize(r,OS_32)));
+                r.number:=(r.number and not $ff) or R_SUBD;
+              list.concat(taicpu.op_reg(A_PUSH,S_L,r));
             end;
           OS_32,OS_S32:
-            list.concat(taicpu.op_reg(A_PUSH,S_L,r));
+            begin
+              if r.number and $ff<>R_SUBD then
+                internalerror(7843);
+              list.concat(taicpu.op_reg(A_PUSH,S_L,r));
+            end
           else
             internalerror(2002032212);
         end;
@@ -363,12 +368,12 @@ unit cgx86;
           OS_8,OS_S8,
           OS_16,OS_S16:
             begin
-              tmpreg := get_scratch_reg_address(list);
-              a_load_ref_reg(list,size,r,tmpreg);
               if target_info.alignment.paraalign = 2 then
-                list.concat(taicpu.op_reg(A_PUSH,S_W,rg.makeregsize(tmpreg,OS_16)))
+                tmpreg:=get_scratch_reg_int(list,OS_16)
               else
-                list.concat(taicpu.op_reg(A_PUSH,S_L,tmpreg));
+                tmpreg:=get_scratch_reg_int(list,OS_32);
+              a_load_ref_reg(list,size,r,tmpreg);
+              list.concat(taicpu.op_reg(A_PUSH,S_L,tmpreg));
               free_scratch_reg(list,tmpreg);
             end;
           OS_32,OS_S32:
@@ -386,7 +391,7 @@ unit cgx86;
         baseno,indexno:boolean;
 
       begin
-        if r.segment.enum<>R_NO then
+        if not((r.segment.enum=R_NO) or ((r.segment.enum=R_INTREGISTER) and (r.segment.number=NR_NO))) then
           CGMessage(cg_e_cant_use_far_pointer_there);
         baseno:=(r.base.enum=R_NO) or ((r.base.enum=R_INTREGISTER) and (r.base.number=NR_NO));
         indexno:=(r.index.enum=R_NO) or ((r.index.enum=R_INTREGISTER) and (r.index.number=NR_NO));
@@ -455,7 +460,7 @@ unit cgx86;
       begin
         list.concat(taicpu.op_reg_ref(A_MOV,TCGSize2OpSize[size],reg,
           ref));
-      End;
+      end;
 
 
     procedure tcgx86.a_load_ref_reg(list : taasmoutput;size : tcgsize;const ref: treference;reg : tregister);
@@ -465,10 +470,9 @@ unit cgx86;
         o,s: topsize;
 
       begin
-        if reg.enum=R_INTREGISTER then
-          o:=subreg2opsize[reg.number and $ff]
-        else
-          o:=reg2opsize[reg.enum];
+        if reg.enum<>R_INTREGISTER then
+          internalerror(200302058);
+        o:=subreg2opsize[reg.number and $ff];
         sizes2load(size,o,op,s);
         list.concat(taicpu.op_ref_reg(op,s,ref,reg));
       end;
@@ -524,9 +528,13 @@ unit cgx86;
     procedure tcgx86.a_loadaddr_ref_reg(list : taasmoutput;const ref : treference;r : tregister);
 
       begin
+        if ref.base.enum<>R_INTREGISTER then
+          internalerror(200302102);
+        if ref.index.enum<>R_INTREGISTER then
+          internalerror(200302102);
         if assigned(ref.symbol) and
-           (ref.base.enum=R_NO) and
-           (ref.index.enum=R_NO) then
+           (ref.base.number=NR_NO) and
+           (ref.index.number=NR_NO) then
          list.concat(taicpu.op_sym_ofs_reg(A_MOV,S_L,ref.symbol,ref.offset,r))
         else
          list.concat(taicpu.op_ref_reg(A_LEA,S_L,ref,r));
@@ -621,11 +629,11 @@ unit cgx86;
         power: longint;
 
       begin
-        if reg.enum>lastreg then
-          internalerror(200301081);
-        Case Op of
+        if reg.enum<>R_INTREGISTER then
+          internalerror(200302034);
+        case op of
           OP_DIV, OP_IDIV:
-            Begin
+            begin
               if ispowerof2(a,power) then
                 begin
                   case op of
@@ -634,25 +642,25 @@ unit cgx86;
                     OP_IDIV:
                       opcode := A_SAR;
                   end;
-                  list.concat(taicpu.op_const_reg(opcode,reg2opsize[reg.enum],power,
-                    reg));
+                  list.concat(taicpu.op_const_reg(opcode,subreg2opsize[reg.number and $ff],
+                    power,reg));
                   exit;
                 end;
               { the rest should be handled specifically in the code      }
               { generator because of the silly register usage restraints }
               internalerror(200109224);
-            End;
+            end;
           OP_MUL,OP_IMUL:
             begin
               if not(cs_check_overflow in aktlocalswitches) and
                  ispowerof2(a,power) then
                 begin
-                  list.concat(taicpu.op_const_reg(A_SHL,reg2opsize[reg.enum],power,
-                    reg));
+                  list.concat(taicpu.op_const_reg(A_SHL,subreg2opsize[reg.number and $ff],
+                    power,reg));
                   exit;
                 end;
               if op = OP_IMUL then
-                list.concat(taicpu.op_const_reg(A_IMUL,reg2opsize[reg.enum],
+                list.concat(taicpu.op_const_reg(A_IMUL,subreg2opsize[reg.number and $ff],
                   a,reg))
               else
                 { OP_MUL should be handled specifically in the code        }
@@ -664,14 +672,14 @@ unit cgx86;
                (a = 1) and
                (op in [OP_ADD,OP_SUB]) then
               if op = OP_ADD then
-                list.concat(taicpu.op_reg(A_INC,reg2opsize[reg.enum],reg))
+                list.concat(taicpu.op_reg(A_INC,subreg2opsize[reg.number and $ff],reg))
               else
-                list.concat(taicpu.op_reg(A_DEC,reg2opsize[reg.enum],reg))
+                list.concat(taicpu.op_reg(A_DEC,subreg2opsize[reg.number and $ff],reg))
             else if (a = 0) then
               if (op <> OP_AND) then
                 exit
               else
-                list.concat(taicpu.op_const_reg(A_MOV,reg2opsize[reg.enum],0,reg))
+                list.concat(taicpu.op_const_reg(A_MOV,subreg2opsize[reg.number and $ff],0,reg))
             else if (a = high(aword)) and
                     (op in [OP_AND,OP_OR,OP_XOR]) then
                    begin
@@ -679,19 +687,19 @@ unit cgx86;
                        OP_AND:
                          exit;
                        OP_OR:
-                         list.concat(taicpu.op_const_reg(A_MOV,reg2opsize[reg.enum],high(aword),reg));
+                         list.concat(taicpu.op_const_reg(A_MOV,subreg2opsize[reg.number and $ff],high(aword),reg));
                        OP_XOR:
-                         list.concat(taicpu.op_reg(A_NOT,reg2opsize[reg.enum],reg));
+                         list.concat(taicpu.op_reg(A_NOT,subreg2opsize[reg.number and $ff],reg));
                      end
                    end
             else
-              list.concat(taicpu.op_const_reg(TOpCG2AsmOp[op],reg2opsize[reg.enum],
+              list.concat(taicpu.op_const_reg(TOpCG2AsmOp[op],subreg2opsize[reg.number and $ff],
                 a,reg));
           OP_SHL,OP_SHR,OP_SAR:
             begin
               if (a and 31) <> 0 Then
                 list.concat(taicpu.op_const_reg(
-                  TOpCG2AsmOp[op],reg2opsize[reg.enum],a and 31,reg));
+                  TOpCG2AsmOp[op],subreg2opsize[reg.number and $ff],a and 31,reg));
               if (a shr 5) <> 0 Then
                 internalerror(68991);
             end
@@ -773,7 +781,7 @@ unit cgx86;
                 TCgSize2OpSize[size],a,ref));
           OP_SHL,OP_SHR,OP_SAR:
             begin
-              if (a and 31) <> 0 Then
+              if (a and 31) <> 0 then
                 list.concat(taicpu.op_const_ref(
                   TOpCG2AsmOp[op],TCgSize2OpSize[size],a and 31,ref));
               if (a shr 5) <> 0 Then
@@ -794,17 +802,17 @@ unit cgx86;
           r:Tregister;
 
         begin
-          if src.enum>lastreg then
-            internalerror(200301081);
-          if dst.enum>lastreg then
-            internalerror(200301081);
+          if src.enum<>R_INTREGISTER then
+            internalerror(200302025);
+          if dst.enum<>R_INTREGISTER then
+            internalerror(200302025);
           r.enum:=R_INTREGISTER;
           dstsize := tcgsize2opsize[size];
-          dst := rg.makeregsize(dst,size);
+          dst.number:=(dst.number and not $ff) or cgsize2subreg(size);
           case op of
             OP_NEG,OP_NOT:
               begin
-                if src.enum <> R_NO then
+                if src.number <> NR_NO then
                   internalerror(200112291);
                 list.concat(taicpu.op_reg(TOpCG2AsmOp[op],dstsize,dst));
               end;
@@ -814,30 +822,36 @@ unit cgx86;
               internalerror(200109233);
             OP_SHR,OP_SHL,OP_SAR:
               begin
-                tmpreg.enum := R_NO;
+                tmpreg.enum:=R_INTREGISTER;
+                tmpreg.number:=NR_NO;
                 popecx := false;
                 { we need cl to hold the shift count, so if the destination }
                 { is ecx, save it to a temp for now                         }
-                if dst.enum in [R_ECX,R_CX,R_CL] then
+                if dst.number shr 8=RS_ECX then
                   begin
-                    case reg2opsize[dst.enum] of
-                      S_B: regloadsize := OS_8;
-                      S_W: regloadsize := OS_16;
-                      else regloadsize := OS_32;
+                    case dst.number and $ff of
+                      R_SUBL,R_SUBH:
+                        regloadsize:=OS_8;
+                      R_SUBW:
+                        regloadsize:=OS_16;
+                      else
+                        regloadsize:=OS_32;
                     end;
-                    tmpreg := get_scratch_reg_int(list);
+                    tmpreg := get_scratch_reg_int(list,OS_INT);
+                    tmpreg.enum:=R_INTREGISTER;
+                    tmpreg.number:=NR_EDI;
                     a_load_reg_reg(list,regloadsize,regloadsize,src,tmpreg);
                   end;
-                if not(src.enum in [R_ECX,R_CX,R_CL]) then
+                if src.number shr 8<>RS_ECX then
                   begin
                     { is ecx still free (it's also free if it was allocated }
                     { to dst, since we've moved dst somewhere else already) }
                     r.number:=NR_ECX;
-                    if not((dst.enum = R_ECX) or
-                           ((R_ECX in rg.unusedregsint) and
+                    if not((dst.number shr 8=RS_ECX) or
+                           ((RS_ECX in rg.unusedregsint) and
                             { this will always be true, it's just here to }
                             { allocate ecx                                }
-                            (rg.getexplicitregisterint(list,R_ECX).enum = R_ECX))) then
+                            (rg.getexplicitregisterint(list,NR_ECX).number = NR_ECX))) then
                       begin
                         list.concat(taicpu.op_reg(A_PUSH,S_L,r));
                         popecx := true;
@@ -845,10 +859,10 @@ unit cgx86;
                     a_load_reg_reg(list,OS_32,OS_32,rg.makeregsize(src,OS_32),r);
                   end
                 else
-                  src.enum := R_CL;
+                  src.number := NR_CL;
                 { do the shift }
                 r.number:=NR_CL;
-                if tmpreg.enum = R_NO then
+                if tmpreg.number = NR_NO then
                   list.concat(taicpu.op_reg_reg(TOpCG2AsmOp[op],dstsize,
                     r,dst))
                 else
@@ -863,12 +877,12 @@ unit cgx86;
                 r.number:=NR_ECX;
                 if popecx then
                   list.concat(taicpu.op_reg(A_POP,S_L,r))
-                else if not (dst.enum in [R_ECX,R_CX,R_CL]) then
+                else if not (dst.number shr 8=RS_ECX) then
                   rg.ungetregisterint(list,r);
               end;
             else
               begin
-                if reg2opsize[src.enum] <> dstsize then
+                if subreg2opsize[src.number and $ff] <> dstsize then
                   internalerror(200109226);
                 list.concat(taicpu.op_reg_reg(TOpCG2AsmOp[op],dstsize,
                   src,dst));
@@ -903,12 +917,12 @@ unit cgx86;
          opsize: topsize;
 
        begin
-         if reg.enum>lastreg then
-          internalerror(200201081);
+         if reg.enum<>R_INTREGISTER then
+          internalerror(200302036);
          case op of
            OP_NEG,OP_NOT:
              begin
-               if reg.enum <> R_NO then
+               if reg.number<>NR_NO then
                  internalerror(200109237);
                list.concat(taicpu.op_ref(TOpCG2AsmOp[op],tcgsize2opsize[size],ref));
              end;
@@ -937,11 +951,11 @@ unit cgx86;
         power: longint;
         opsize: topsize;
       begin
-        if src.enum>lastreg then
-          internalerror(200201081);
-        if dst.enum>lastreg then
-          internalerror(200201081);
-        opsize := reg2opsize[src.enum];
+        if src.enum<>R_INTREGISTER then
+          internalerror(200302057);
+        if dst.enum<>R_INTREGISTER then
+          internalerror(200302057);
+        opsize := subreg2opsize[src.number and $ff];
         if (opsize <> S_L) or
            not (size in [OS_32,OS_S32]) then
           begin
@@ -949,7 +963,7 @@ unit cgx86;
             exit;
           end;
         { if we get here, we have to do a 32 bit calculation, guaranteed }
-        Case Op of
+        case op of
           OP_DIV, OP_IDIV, OP_MUL, OP_AND, OP_OR, OP_XOR, OP_SHL, OP_SHR,
           OP_SAR:
             { can't do anything special for these }
@@ -1027,12 +1041,20 @@ unit cgx86;
         l : tasmlabel);
 
         begin
-          if reg.enum>lastreg then
-            internalerror(200101081);
-          if (a = 0) then
-            list.concat(taicpu.op_reg_reg(A_TEST,reg2opsize[reg.enum],reg,reg))
+          if reg.enum=R_INTREGISTER then
+            begin
+              if (a = 0) then
+                list.concat(taicpu.op_reg_reg(A_TEST,subreg2opsize[reg.number and $ff],reg,reg))
+              else
+                list.concat(taicpu.op_const_reg(A_CMP,subreg2opsize[reg.number and $ff],a,reg));
+            end
           else
-            list.concat(taicpu.op_const_reg(A_CMP,reg2opsize[reg.enum],a,reg));
+            begin
+              if (a = 0) then
+                list.concat(taicpu.op_reg_reg(A_TEST,reg2opsize[reg.enum],reg,reg))
+              else
+                list.concat(taicpu.op_const_reg(A_CMP,reg2opsize[reg.enum],a,reg));
+            end;
           a_jmp_cond(list,cmp_op,l);
         end;
 
@@ -1062,7 +1084,9 @@ unit cgx86;
 
      procedure tcgx86.a_cmp_ref_reg_label(list : taasmoutput;size : tcgsize;cmp_op : topcmp;const ref: treference; reg : tregister;l : tasmlabel);
         begin
-          reg := rg.makeregsize(reg,size);
+          if reg.enum<>R_INTREGISTER then
+            internalerror(200302059);
+          reg.number:=(reg.number and not $ff) or cgsize2subreg(size);
           list.concat(taicpu.op_ref_reg(A_CMP,tcgsize2opsize[size],ref,reg));
           a_jmp_cond(list,cmp_op,l);
         end;
@@ -1103,11 +1127,12 @@ unit cgx86;
          ai : taicpu;
          hreg : tregister;
        begin
-          if reg.enum>lastreg then
-            internalerror(200201081);
-          hreg := rg.makeregsize(reg,OS_8);
-          ai:=Taicpu.Op_reg(A_Setcc,S_B,hreg);
-          ai.SetCondition(flags_to_cond(f));
+          if reg.enum<>R_INTREGISTER then
+            internalerror(200202031);
+          hreg.enum:=R_INTREGISTER;
+          hreg.number:=(reg.number and not $ff) or R_SUBL;
+          ai:=Taicpu.op_reg(A_SETcc,S_B,hreg);
+          ai.setcondition(flags_to_cond(f));
           list.concat(ai);
           if (reg.enum <> hreg.enum) then
             a_load_reg_reg(list,OS_8,size,hreg,reg);
@@ -1121,8 +1146,8 @@ unit cgx86;
        begin
           if not(size in [OS_8,OS_S8]) then
             a_load_const_ref(list,size,0,ref);
-          ai:=Taicpu.Op_ref(A_Setcc,S_B,ref);
-          ai.SetCondition(flags_to_cond(f));
+          ai:=Taicpu.op_ref(A_SETcc,S_B,ref);
+          ai.setcondition(flags_to_cond(f));
           list.concat(ai);
        end;
 
@@ -1146,12 +1171,12 @@ unit cgx86;
          begin
            r.enum:=R_INTREGISTER;
            r.number:=NR_ECX;
-           if not(R_ECX in rg.unusedregsint) then
+           if not(RS_ECX in rg.unusedregsint) then
              begin
                list.concat(Taicpu.Op_reg(A_PUSH,S_L,r));
                ecxpushed:=true;
              end
-           else rg.getexplicitregisterint(list,R_ECX);
+           else rg.getexplicitregisterint(list,NR_ECX);
          end;
 
       begin
@@ -1161,11 +1186,11 @@ unit cgx86;
            begin
               r.enum:=R_INTREGISTER;
               helpsize:=len shr 2;
-              rg.getexplicitregisterint(list,R_EDI);
               dstref:=dest;
               srcref:=source;
               for i:=1 to helpsize do
                 begin
+                   rg.getexplicitregisterint(list,NR_EDI);
                    r.number:=NR_EDI;
                    a_load_ref_reg(list,OS_32,srcref,r);
                    If (len = 4) and delsource then
@@ -1174,9 +1199,11 @@ unit cgx86;
                    inc(srcref.offset,4);
                    inc(dstref.offset,4);
                    dec(len,4);
+                   rg.ungetregisterint(list,r);
                 end;
               if len>1 then
                 begin
+                   rg.getexplicitregisterint(list,NR_DI);
                    r.number:=NR_DI;
                    a_load_ref_reg(list,OS_16,srcref,r);
                    If (len = 2) and delsource then
@@ -1185,9 +1212,8 @@ unit cgx86;
                    inc(srcref.offset,2);
                    inc(dstref.offset,2);
                    dec(len,2);
+                   rg.ungetregisterint(list,r);
                 end;
-              r.enum:=R_EDI;
-              rg.ungetregisterint(list,r);
               r.enum:=R_INTREGISTER;
               reg8.enum:=R_INTREGISTER;
               reg32.enum:=R_INTREGISTER;
@@ -1195,10 +1221,10 @@ unit cgx86;
                 begin
                    { and now look for an 8 bit register }
                    swap:=false;
-                   if R_EAX in rg.unusedregsint then reg8:=rg.makeregsize(rg.getexplicitregisterint(list,R_EAX),OS_8)
-                   else if R_EDX in rg.unusedregsint then reg8:=rg.makeregsize(rg.getexplicitregisterint(list,R_EDX),OS_8)
-                   else if R_EBX in rg.unusedregsint then reg8:=rg.makeregsize(rg.getexplicitregisterint(list,R_EBX),OS_8)
-                   else if R_ECX in rg.unusedregsint then reg8:=rg.makeregsize(rg.getexplicitregisterint(list,R_ECX),OS_8)
+                   if RS_EAX in rg.unusedregsint then reg8:=rg.getexplicitregisterint(list,NR_AL)
+                   else if RS_EDX in rg.unusedregsint then reg8:=rg.getexplicitregisterint(list,NR_DL)
+                   else if RS_EBX in rg.unusedregsint then reg8:=rg.getexplicitregisterint(list,NR_BL)
+                   else if RS_ECX in rg.unusedregsint then reg8:=rg.getexplicitregisterint(list,NR_CL)
                    else
                       begin
                          swap:=true;
@@ -1223,7 +1249,7 @@ unit cgx86;
                    if swap then
                      { was earlier XCHG, of course nonsense }
                      begin
-                       rg.getexplicitregisterint(list,R_EDI);
+                       rg.getexplicitregisterint(list,NR_EDI);
                        r.number:=NR_EDI;
                        a_load_reg_reg(list,OS_32,OS_32,reg32,r);
                      end;
@@ -1235,26 +1261,17 @@ unit cgx86;
                      begin
                        r.number:=NR_EDI;
                        a_load_reg_reg(list,OS_32,OS_32,r,reg32);
-                       r.enum:=R_EDI;
                        rg.ungetregisterint(list,r);
                      end
                    else
-                     begin
-                        if reg8.number=NR_AL then
-                          reg8.enum:=R_AL
-                        else if reg8.number=NR_BL then
-                          reg8.enum:=R_BL
-                        else if reg8.number=NR_CL then
-                          reg8.enum:=R_CL;
-                        rg.ungetregister(list,reg8);
-                     end;
+                     rg.ungetregisterint(list,reg8);
                 end;
            end
          else
            begin
               r.enum:=R_INTREGISTER;
               r.number:=NR_EDI;
-              rg.getexplicitregisterint(list,R_EDI);
+              rg.getexplicitregisterint(list,NR_EDI);
               a_loadaddr_ref_reg(list,dest,r);
               r.number:=NR_ESI;
               list.concat(tai_regalloc.alloc(r));
@@ -1297,9 +1314,9 @@ unit cgx86;
                    if len=1 then
                      list.concat(Taicpu.Op_none(A_MOVSB,S_NO));
                 end;
-              r.enum:=R_EDI;
-              rg.ungetregisterint(list,r);
               r.enum:=R_INTREGISTER;
+              r.number:=NR_EDI;
+              rg.ungetregisterint(list,r);
               r.number:=NR_ESI;
               list.concat(tai_regalloc.dealloc(r));
               if ecxpushed then
@@ -1309,7 +1326,7 @@ unit cgx86;
                 end
               else
                 begin
-                  r.enum:=R_ECX;
+                  r.number:=NR_ECX;
                   rg.ungetregisterint(list,r);
                 end;
 
@@ -1366,9 +1383,12 @@ unit cgx86;
         lenref:=ref;
         inc(lenref.offset,4);
         { get stack space }
-        r.enum:=R_EDI;
-        rsp.enum:=R_ESP;
-        rg.getexplicitregisterint(list,R_EDI);
+        r.enum:=R_INTREGISTER;
+        r.number:=NR_EDI;
+        rsp.enum:=R_INTREGISTER;
+        rsp.number:=NR_ESP;
+        r2.enum:=R_INTREGISTER;
+        rg.getexplicitregisterint(list,NR_EDI);
         list.concat(Taicpu.op_ref_reg(A_MOV,S_L,lenref,r));
         list.concat(Taicpu.op_reg(A_INC,S_L,r));
         if (elesize<>1) then
@@ -1389,7 +1409,7 @@ unit cgx86;
              list.concat(Taicpu.op_const_reg(A_CMP,S_L,winstackpagesize,r));
              a_jmp_cond(list,OC_B,ok);
              list.concat(Taicpu.op_const_reg(A_SUB,S_L,winstackpagesize-4,rsp));
-             r2.enum:=R_EAX;
+             r2.number:=NR_EAX;
              list.concat(Taicpu.op_reg(A_PUSH,S_L,r));
              list.concat(Taicpu.op_const_reg(A_SUB,S_L,winstackpagesize,r));
              a_jmp_always(list,again);
@@ -1398,7 +1418,7 @@ unit cgx86;
              list.concat(Taicpu.op_reg_reg(A_SUB,S_L,r,rsp));
              rg.ungetregisterint(list,r);
              { now reload EDI }
-             rg.getexplicitregisterint(list,R_EDI);
+             rg.getexplicitregisterint(list,NR_EDI);
              list.concat(Taicpu.op_ref_reg(A_MOV,S_L,lenref,r));
              list.concat(Taicpu.op_reg(A_INC,S_L,r));
 
@@ -1419,21 +1439,21 @@ unit cgx86;
         list.concat(Taicpu.op_reg_reg(A_MOV,S_L,rsp,r));
 
         { don't destroy the registers! }
-        r2.enum:=R_ECX;
+        r2.number:=NR_ECX;
         list.concat(Taicpu.op_reg(A_PUSH,S_L,r2));
-        r2.enum:=R_ESI;
+        r2.number:=NR_ESI;
         list.concat(Taicpu.op_reg(A_PUSH,S_L,r2));
 
         { load count }
-        r2.enum:=R_ECX;
+        r2.number:=NR_ECX;
         list.concat(Taicpu.op_ref_reg(A_MOV,S_L,lenref,r2));
 
         { load source }
-        r2.enum:=R_ESI;
+        r2.number:=NR_ESI;
         list.concat(Taicpu.op_ref_reg(A_MOV,S_L,ref,r2));
 
         { scheduled .... }
-        r2.enum:=R_ECX;
+        r2.number:=NR_ECX;
         list.concat(Taicpu.op_reg(A_INC,S_L,r2));
 
         { calculate size }
@@ -1462,9 +1482,9 @@ unit cgx86;
           S_L : list.concat(Taicpu.Op_none(A_MOVSD,S_NO));
         end;
         rg.ungetregisterint(list,r);
-        r2.enum:=R_ESI;
+        r2.number:=NR_ESI;
         list.concat(Taicpu.op_reg(A_POP,S_L,r2));
-        r2.enum:=R_ECX;
+        r2.number:=NR_ECX;
         list.concat(Taicpu.op_reg(A_POP,S_L,r2));
 
         { patch the new address }
@@ -1481,9 +1501,11 @@ unit cgx86;
         lenref:=ref;
         inc(lenref.offset,4);
         { caluclate size and adjust stack space }
-        rg.getexplicitregisterint(list,R_EDI);
-        r.enum:=R_EDI;
-        rsp.enum:=R_ESP;
+        rg.getexplicitregisterint(list,NR_EDI);
+        r.enum:=R_INTREGISTER;
+        r.number:=NR_EDI;
+        rsp.enum:=R_INTREGISTER;
+        rsp.number:=NR_ESP;
         list.concat(Taicpu.op_ref_reg(A_MOV,S_L,lenref,r));
         list.concat(Taicpu.op_reg(A_INC,S_L,r));
         if (elesize<>1) then
@@ -1649,7 +1671,7 @@ unit cgx86;
                  begin
                     objectlibrary.getlabel(again);
                     r.number:=NR_EDI;
-                    rg.getexplicitregisterint(list,R_EDI);
+                    rg.getexplicitregisterint(list,NR_EDI);
                     list.concat(Taicpu.op_const_reg(A_MOV,S_L,localsize div winstackpagesize,r));
                     a_label(list,again);
                     list.concat(Taicpu.op_const_reg(A_SUB,S_L,winstackpagesize-4,rsp));
@@ -1733,7 +1755,7 @@ unit cgx86;
           end
         else if is_object(procinfo._class) then
           begin
-            rg.getexplicitregisterint(list,R_EDI);
+            rg.getexplicitregisterint(list,NR_EDI);
             a_load_const_reg(list,OS_ADDR,procinfo._class.vmt_offset,r);
             a_call_name(list,'FPC_HELP_CONSTRUCTOR');
             list.concat(Taicpu.Op_cond_sym(A_Jcc,C_Z,S_NO,faillabel));
@@ -1768,10 +1790,9 @@ unit cgx86;
               g_finalize(list,procinfo._class,href,false);
               a_label(list,nofinal);
             end;
-           rg.getexplicitregisterint(list,R_EDI);
+           rg.getexplicitregisterint(list,NR_EDI);
            r.number:=NR_EDI;
            a_load_const_reg(list,OS_ADDR,procinfo._class.vmt_offset,r);
-           r.enum:=R_EDI;
            rg.ungetregisterint(list,r);
            a_call_name(list,'FPC_HELP_DESTRUCTOR')
          end
@@ -1797,11 +1818,10 @@ unit cgx86;
             reference_reset_base(href,procinfo.framepointer,12);
             r.number:=NR_ESI;
             a_load_ref_reg(list,OS_ADDR,href,r);
-            rg.getexplicitregisterint(list,R_EDI);
+            rg.getexplicitregisterint(list,NR_EDI);
             r.number:=NR_EDI;
             a_load_const_reg(list,OS_ADDR,procinfo._class.vmt_offset,r);
             a_call_name(list,'FPC_HELP_FAIL');
-            r.enum:=R_EDI;
             rg.ungetregisterint(list,r);
           end
         else
@@ -1810,14 +1830,14 @@ unit cgx86;
 {$endif}
 
 
-    procedure tcgx86.g_save_standard_registers(list : taasmoutput; usedinproc : tregisterset);
+    procedure tcgx86.g_save_standard_registers(list:Taasmoutput;usedinproc:Tsupregset);
 
     var r:Tregister;
 
     begin
         r.enum:=R_INTREGISTER;
         r.number:=NR_EBX;
-        if (R_EBX in usedinproc) then
+        if (RS_EBX in usedinproc) then
           list.concat(Taicpu.Op_reg(A_PUSH,S_L,r));
         r.number:=NR_ESI;
         list.concat(Taicpu.Op_reg(A_PUSH,S_L,r));
@@ -1826,7 +1846,7 @@ unit cgx86;
     end;
 
 
-    procedure tcgx86.g_restore_standard_registers(list : taasmoutput; usedinproc : tregisterset);
+    procedure tcgx86.g_restore_standard_registers(list:Taasmoutput;usedinproc:Tsupregset);
 
     var r:Tregister;
 
@@ -1837,7 +1857,7 @@ unit cgx86;
         r.number:=NR_ESI;
         list.concat(Taicpu.Op_reg(A_POP,S_L,r));
         r.number:=NR_EBX;
-        if (R_EBX in usedinproc) then
+        if (RS_EBX in usedinproc) then
          list.concat(Taicpu.Op_reg(A_POP,S_L,r));
     end;
 
@@ -1910,7 +1930,11 @@ unit cgx86;
 end.
 {
   $Log$
-  Revision 1.31  2003-01-21 10:41:13  daniel
+  Revision 1.32  2003-02-19 22:00:17  daniel
+    * Code generator converted to new register notation
+    - Horribily outdated todo.txt removed
+
+  Revision 1.31  2003/01/21 10:41:13  daniel
     * Fixed another 200301081
 
   Revision 1.30  2003/01/13 23:00:18  daniel