Browse Source

* generic constructor working for i386
* remove fixed self register
* esi added as address register for i386

peter 22 years ago
parent
commit
c4ddcc78a8

+ 9 - 4
compiler/aoptcs.pas

@@ -99,9 +99,9 @@ End;
 Procedure TRegInfo.Clear;
 Procedure TRegInfo.Clear;
 Begin
 Begin
   RegsLoadedForRef   := [];
   RegsLoadedForRef   := [];
-  NewRegsEncountered := [ProcInfo.FramePointer, STACK_POINTER_REG];
-  OldRegsEncountered := [ProcInfo.FramePointer, STACK_POINTER_REG];
-  New2OldReg[ProcInfo.FramePointer] := ProcInfo.FramePointer;
+  NewRegsEncountered := [FRAME_POINTER_REG, STACK_POINTER_REG];
+  OldRegsEncountered := [FRAME_POINTER_REG, STACK_POINTER_REG];
+  New2OldReg[FRAME_POINTER_REG] := FRAME_POINTER_REG;
   New2OldReg[STACK_POINTER_REG] := STACK_POINTER_REG;
   New2OldReg[STACK_POINTER_REG] := STACK_POINTER_REG;
 End;
 End;
 
 
@@ -850,7 +850,12 @@ End.
 
 
 {
 {
   $Log$
   $Log$
-  Revision 1.7  2002-05-18 13:34:05  peter
+  Revision 1.8  2003-03-28 19:16:56  peter
+    * generic constructor working for i386
+    * remove fixed self register
+    * esi added as address register for i386
+
+  Revision 1.7  2002/05/18 13:34:05  peter
     * readded missing revisions
     * readded missing revisions
 
 
   Revision 1.6  2002/05/16 19:46:34  carl
   Revision 1.6  2002/05/16 19:46:34  carl

+ 6 - 2
compiler/cg64f32.pas

@@ -138,7 +138,6 @@ unit cg64f32;
 
 
     procedure tcg64f32.a_load64_const_ref(list : taasmoutput;value : qword;const ref : treference);
     procedure tcg64f32.a_load64_const_ref(list : taasmoutput;value : qword;const ref : treference);
       var
       var
-        tmpvalue : DWord;
         tmpref: treference;
         tmpref: treference;
       begin
       begin
         if target_info.endian = endian_big then
         if target_info.endian = endian_big then
@@ -752,7 +751,12 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.35  2003-02-19 22:00:14  daniel
+  Revision 1.36  2003-03-28 19:16:56  peter
+    * generic constructor working for i386
+    * remove fixed self register
+    * esi added as address register for i386
+
+  Revision 1.35  2003/02/19 22:00:14  daniel
     * Code generator converted to new register notation
     * Code generator converted to new register notation
     - Horribily outdated todo.txt removed
     - Horribily outdated todo.txt removed
 
 

+ 12 - 1
compiler/cgbase.pas

@@ -76,6 +76,9 @@ unit cgbase;
           framepointer_offset : longint;
           framepointer_offset : longint;
           {# offset from frame pointer to get self reference }
           {# offset from frame pointer to get self reference }
           selfpointer_offset : longint;
           selfpointer_offset : longint;
+          {# offset from frame pointer to get vmt reference (constructors only) }
+          inheritedflag_offset,
+          vmtpointer_offset  : longint;
           {# result value offset in stack (functions only) }
           {# result value offset in stack (functions only) }
           return_offset : longint;
           return_offset : longint;
           {# firsttemp position }
           {# firsttemp position }
@@ -373,11 +376,14 @@ implementation
         procdef:=nil;
         procdef:=nil;
         framepointer_offset:=0;
         framepointer_offset:=0;
         selfpointer_offset:=0;
         selfpointer_offset:=0;
+        vmtpointer_offset:=0;
+        inheritedflag_offset:=0;
         return_offset:=0;
         return_offset:=0;
         firsttemp_offset:=0;
         firsttemp_offset:=0;
         para_offset:=0;
         para_offset:=0;
         flags:=0;
         flags:=0;
         framepointer.enum:=R_NO;
         framepointer.enum:=R_NO;
+        framepointer.number:=NR_NO;
         globalsymbol:=false;
         globalsymbol:=false;
         exported:=false;
         exported:=false;
         no_fast_exit:=false;
         no_fast_exit:=false;
@@ -651,7 +657,12 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.37  2003-03-20 17:51:45  peter
+  Revision 1.38  2003-03-28 19:16:56  peter
+    * generic constructor working for i386
+    * remove fixed self register
+    * esi added as address register for i386
+
+  Revision 1.37  2003/03/20 17:51:45  peter
     * dynamic arrays have size OS_ADDR
     * dynamic arrays have size OS_ADDR
 
 
   Revision 1.36  2003/01/08 18:43:56  daniel
   Revision 1.36  2003/01/08 18:43:56  daniel

+ 118 - 126
compiler/cgobj.pas

@@ -302,8 +302,7 @@ unit cgobj;
           }
           }
          procedure g_exception_reason_load(list : taasmoutput; const href : treference);virtual;
          procedure g_exception_reason_load(list : taasmoutput; const href : treference);virtual;
 
 
-
-          procedure g_maybe_loadself(list : taasmoutput);virtual;
+          function g_load_self(list : taasmoutput):tregister;
           procedure g_maybe_testself(list : taasmoutput;reg:tregister);
           procedure g_maybe_testself(list : taasmoutput;reg:tregister);
           procedure g_maybe_testvmt(list : taasmoutput;reg:tregister;objdef:tobjectdef);
           procedure g_maybe_testvmt(list : taasmoutput;reg:tregister;objdef:tobjectdef);
           {# This should emit the opcode to copy len bytes from the source
           {# This should emit the opcode to copy len bytes from the source
@@ -506,6 +505,11 @@ unit cgobj;
     const
     const
       max_scratch_regs = high(scratch_regs) - low(scratch_regs) + 1;
       max_scratch_regs = high(scratch_regs) - low(scratch_regs) + 1;
 
 
+      { Please leave this here, this module should NOT use
+        exprasmlist, the lists are always passed as arguments.
+        Declaring it as string here results in an error when compiling (PFV) }
+      exprasmlist = 'error';
+
 {*****************************************************************************
 {*****************************************************************************
                             basic functionallity
                             basic functionallity
 ******************************************************************************}
 ******************************************************************************}
@@ -578,7 +582,7 @@ unit cgobj;
     procedure tcg.free_scratch_reg(list : taasmoutput;r : tregister);
     procedure tcg.free_scratch_reg(list : taasmoutput;r : tregister);
 
 
       begin
       begin
-         if r.enum<>R_INTREGISTER then 
+         if r.enum<>R_INTREGISTER then
            internalerror(200302058);
            internalerror(200302058);
          include(unusedscratchregisters,r.number shr 8);
          include(unusedscratchregisters,r.number shr 8);
          a_reg_dealloc(list,r);
          a_reg_dealloc(list,r);
@@ -670,7 +674,6 @@ unit cgobj;
     procedure tcg.a_param_copy_ref(list : taasmoutput;size : qword;const r : treference;const locpara : tparalocation);
     procedure tcg.a_param_copy_ref(list : taasmoutput;size : qword;const r : treference;const locpara : tparalocation);
       var
       var
         ref : treference;
         ref : treference;
-        hr : tregister;
       begin
       begin
          if not(locpara.loc in [LOC_REFERENCE,LOC_CREFERENCE]) then
          if not(locpara.loc in [LOC_REFERENCE,LOC_CREFERENCE]) then
            internalerror(2003010901);
            internalerror(2003010901);
@@ -712,7 +715,7 @@ unit cgobj;
                 internalerror(200302037);
                 internalerror(200302037);
               if (dref.index.enum<>R_NO) and (dref.index.enum<>R_INTREGISTER) then
               if (dref.index.enum<>R_NO) and (dref.index.enum<>R_INTREGISTER) then
                 internalerror(200302037);
                 internalerror(200302037);
-                
+
               if (dref.base.number shr 8<>RS_EBX) and
               if (dref.base.number shr 8<>RS_EBX) and
                  (dref.index.number shr 8<>RS_EBX) then
                  (dref.index.number shr 8<>RS_EBX) then
                 pushed_reg.number:=NR_EBX
                 pushed_reg.number:=NR_EBX
@@ -787,8 +790,6 @@ unit cgobj;
 
 
     procedure tcg.a_load_loc_reg(list : taasmoutput;const loc: tlocation; reg : tregister);
     procedure tcg.a_load_loc_reg(list : taasmoutput;const loc: tlocation; reg : tregister);
 
 
-    var r:Tregister;
-
       begin
       begin
         case loc.loc of
         case loc.loc of
           LOC_REFERENCE,LOC_CREFERENCE:
           LOC_REFERENCE,LOC_CREFERENCE:
@@ -1172,7 +1173,6 @@ unit cgobj;
          reference_release(list,source);
          reference_release(list,source);
         a_param_const(list,OS_INT,len,paramanager.getintparaloc(1));
         a_param_const(list,OS_INT,len,paramanager.getintparaloc(1));
         a_call_name(list,'FPC_SHORTSTR_ASSIGN');
         a_call_name(list,'FPC_SHORTSTR_ASSIGN');
-        g_maybe_loadself(list);
       end;
       end;
 
 
 
 
@@ -1432,52 +1432,49 @@ unit cgobj;
       end;
       end;
 
 
 
 
-    procedure tcg.g_maybe_loadself(list : taasmoutput);
+    function tcg.g_load_self(list : taasmoutput):tregister;
       var
       var
          hp : treference;
          hp : treference;
          p : tprocinfo;
          p : tprocinfo;
          i : longint;
          i : longint;
-         spr : Tregister;
+         self_reg : tregister;
       begin
       begin
-         spr.enum:=R_INTREGISTER;
-         spr.number:=NR_SELF_POINTER_REG;
-         if assigned(procinfo._class) then
+         if not assigned(procinfo._class) then
+           internalerror(200303211);
+         self_reg:=rg.getaddressregister(list);
+         if lexlevel>normal_function_level then
            begin
            begin
-              list.concat(tai_regalloc.Alloc(spr));
-              if lexlevel>normal_function_level then
-                begin
-                   reference_reset_base(hp,procinfo.framepointer,procinfo.framepointer_offset);
-                   a_load_ref_reg(list,OS_ADDR,hp,spr);
-                   p:=procinfo.parent;
-                   for i:=3 to lexlevel-1 do
-                     begin
-                        reference_reset_base(hp,spr,p.framepointer_offset);
-                        a_load_ref_reg(list,OS_ADDR,hp,spr);
-                        p:=p.parent;
-                     end;
-                   reference_reset_base(hp,spr,p.selfpointer_offset);
-                   a_load_ref_reg(list,OS_ADDR,hp,spr);
-                end
-              else
-                begin
-                   reference_reset_base(hp,procinfo.framepointer,procinfo.selfpointer_offset);
-                   a_load_ref_reg(list,OS_ADDR,hp,spr);
-                end;
+             reference_reset_base(hp,procinfo.framepointer,procinfo.framepointer_offset);
+             a_load_ref_reg(list,OS_ADDR,hp,self_reg);
+             p:=procinfo.parent;
+             for i:=3 to lexlevel-1 do
+               begin
+                  reference_reset_base(hp,self_reg,p.framepointer_offset);
+                  a_load_ref_reg(list,OS_ADDR,hp,self_reg);
+                  p:=p.parent;
+               end;
+             reference_reset_base(hp,self_reg,p.selfpointer_offset);
+             a_load_ref_reg(list,OS_ADDR,hp,self_reg);
+           end
+         else
+           begin
+             reference_reset_base(hp,procinfo.framepointer,procinfo.selfpointer_offset);
+             a_load_ref_reg(list,OS_ADDR,hp,self_reg);
            end;
            end;
+        g_load_self:=self_reg;
       end;
       end;
 
 
 
 
     procedure tcg.g_maybe_testself(list : taasmoutput;reg:tregister);
     procedure tcg.g_maybe_testself(list : taasmoutput;reg:tregister);
       var
       var
         OKLabel : tasmlabel;
         OKLabel : tasmlabel;
-        dummyloc : tparalocation;
       begin
       begin
         if (cs_check_object in aktlocalswitches) or
         if (cs_check_object in aktlocalswitches) or
            (cs_check_range in aktlocalswitches) then
            (cs_check_range in aktlocalswitches) then
          begin
          begin
            objectlibrary.getlabel(oklabel);
            objectlibrary.getlabel(oklabel);
            a_cmp_const_reg_label(list,OS_ADDR,OC_NE,0,reg,oklabel);
            a_cmp_const_reg_label(list,OS_ADDR,OC_NE,0,reg,oklabel);
-           a_param_const(list,OS_INT,210,dummyloc);
+           a_param_const(list,OS_INT,210,paramanager.getintparaloc(1));
            a_call_name(list,'FPC_HANDLEERROR');
            a_call_name(list,'FPC_HANDLEERROR');
            a_label(list,oklabel);
            a_label(list,oklabel);
          end;
          end;
@@ -1491,15 +1488,15 @@ unit cgobj;
         if (cs_check_object in aktlocalswitches) then
         if (cs_check_object in aktlocalswitches) then
          begin
          begin
            reference_reset_symbol(hrefvmt,objectlibrary.newasmsymbol(objdef.vmt_mangledname),0);
            reference_reset_symbol(hrefvmt,objectlibrary.newasmsymbol(objdef.vmt_mangledname),0);
-           a_paramaddr_ref(exprasmlist,hrefvmt,paramanager.getintparaloc(2));
-           a_param_reg(exprasmlist,OS_ADDR,reg,paramanager.getintparaloc(1));
-           a_call_name(exprasmlist,'FPC_CHECK_OBJECT_EXT');
+           a_paramaddr_ref(list,hrefvmt,paramanager.getintparaloc(2));
+           a_param_reg(list,OS_ADDR,reg,paramanager.getintparaloc(1));
+           a_call_name(list,'FPC_CHECK_OBJECT_EXT');
          end
          end
         else
         else
          if (cs_check_range in aktlocalswitches) then
          if (cs_check_range in aktlocalswitches) then
           begin
           begin
-            a_param_reg(exprasmlist,OS_ADDR,reg,paramanager.getintparaloc(1));
-            a_call_name(exprasmlist,'FPC_CHECK_OBJECT');
+            a_param_reg(list,OS_ADDR,reg,paramanager.getintparaloc(1));
+            a_call_name(list,'FPC_CHECK_OBJECT');
           end;
           end;
       end;
       end;
 
 
@@ -1510,52 +1507,49 @@ unit cgobj;
 
 
     procedure tcg.g_call_constructor_helper(list : taasmoutput);
     procedure tcg.g_call_constructor_helper(list : taasmoutput);
      var
      var
-      href : treference;
-      hregister : tregister;
-      spr,acc : Tregister;
+       href : treference;
+       acc : Tregister;
      begin
      begin
+        if procinfo.vmtpointer_offset=0 then
+         internalerror(200303251);
+        if procinfo.selfpointer_offset=0 then
+         internalerror(200303252);
         acc.enum:=R_INTREGISTER;
         acc.enum:=R_INTREGISTER;
         acc.number:=NR_ACCUMULATOR;
         acc.number:=NR_ACCUMULATOR;
-        spr.enum:=R_INTREGISTER;
-        spr.number:=NR_SELF_POINTER_REG;
         if is_class(procinfo._class) then
         if is_class(procinfo._class) then
           begin
           begin
             if (cs_implicit_exceptions in aktmoduleswitches) then
             if (cs_implicit_exceptions in aktmoduleswitches) then
               procinfo.flags:=procinfo.flags or pi_needs_implicit_finally;
               procinfo.flags:=procinfo.flags or pi_needs_implicit_finally;
-            { parameter 2 : self pointer / flag }
-            {!! this is a terrible hack, normally the helper should get three params : }
-            {    one with self register, one with flag and one with VMT pointer        }
-            {reference_reset_base(href, procinfo.framepointer,procinfo.selfpointer_offset+POINTER_SIZE);}
-            a_param_reg(list, OS_ADDR, spr, paramanager.getintparaloc(2));
-
-            { parameter 1 : vmt pointer (stored at the selfpointer address on stack)  }
+            { parameter 2 : vmt pointer, 0 when called by inherited }
+            reference_reset_base(href, procinfo.framepointer,procinfo.vmtpointer_offset);
+            a_param_ref(list, OS_ADDR,href,paramanager.getintparaloc(1));
+            { parameter 1 : self pointer }
             reference_reset_base(href, procinfo.framepointer,procinfo.selfpointer_offset);
             reference_reset_base(href, procinfo.framepointer,procinfo.selfpointer_offset);
             a_param_ref(list, OS_ADDR,href,paramanager.getintparaloc(1));
             a_param_ref(list, OS_ADDR,href,paramanager.getintparaloc(1));
             a_call_name(list,'FPC_NEW_CLASS');
             a_call_name(list,'FPC_NEW_CLASS');
-            a_load_reg_reg(list,OS_ADDR,OS_ADDR,acc,spr);
-            { save the self pointer result }
-            a_load_reg_ref(list,OS_ADDR,spr,href);
+            { save the self pointer }
+            reference_reset_base(href, procinfo.framepointer,procinfo.selfpointer_offset);
+            a_load_reg_ref(list,OS_ADDR,acc,href);
+            { fail? }
             a_cmp_const_reg_label(list,OS_ADDR,OC_EQ,0,acc,faillabel);
             a_cmp_const_reg_label(list,OS_ADDR,OC_EQ,0,acc,faillabel);
           end
           end
         else if is_object(procinfo._class) then
         else if is_object(procinfo._class) then
           begin
           begin
-            { parameter 3 :vmt_offset     }
+            { parameter 3 : vmt_offset }
             a_param_const(list, OS_32, procinfo._class.vmt_offset, paramanager.getintparaloc(3));
             a_param_const(list, OS_32, procinfo._class.vmt_offset, paramanager.getintparaloc(3));
-            { parameter 2 : address of pointer to vmt }
-            {  this is the first(?) parameter which was pushed to the constructor }
-            reference_reset_base(href, procinfo.framepointer,procinfo.selfpointer_offset-POINTER_SIZE);
-            hregister:=get_scratch_reg_address(list);
-            a_loadaddr_ref_reg(list, href, hregister);
-            a_param_reg(list, OS_ADDR,hregister,paramanager.getintparaloc(2));
-            free_scratch_reg(list, hregister);
-            { parameter 1 : address of self pointer   }
+            { parameter 2 : address of pointer to vmt,
+              this is required to allow setting the vmt to -1 to indicate
+              that memory was allocated }
+            reference_reset_base(href, procinfo.framepointer,procinfo.vmtpointer_offset);
+            a_paramaddr_ref(list,href,paramanager.getintparaloc(2));
+            { parameter 1 : self pointer }
             reference_reset_base(href, procinfo.framepointer,procinfo.selfpointer_offset);
             reference_reset_base(href, procinfo.framepointer,procinfo.selfpointer_offset);
-            hregister:=get_scratch_reg_address(list);
-            a_loadaddr_ref_reg(list, href, hregister);
-            a_param_reg(list, OS_ADDR,hregister,paramanager.getintparaloc(1));
-            free_scratch_reg(list, hregister);
+            a_param_ref(list,OS_ADDR,href,paramanager.getintparaloc(1));
             a_call_name(list,'FPC_HELP_CONSTRUCTOR');
             a_call_name(list,'FPC_HELP_CONSTRUCTOR');
-            a_load_reg_reg(list,OS_ADDR,OS_ADDR,acc,spr);
+            { save the self pointer }
+            reference_reset_base(href, procinfo.framepointer,procinfo.selfpointer_offset);
+            a_load_reg_ref(list,OS_ADDR,acc,href);
+            { fail? }
             a_cmp_const_reg_label(list,OS_ADDR,OC_EQ,0,acc,faillabel);
             a_cmp_const_reg_label(list,OS_ADDR,OC_EQ,0,acc,faillabel);
           end
           end
         else
         else
@@ -1567,46 +1561,51 @@ unit cgobj;
       var
       var
         nofinal : tasmlabel;
         nofinal : tasmlabel;
         href : treference;
         href : treference;
-      hregister : tregister;
-        spr : Tregister;
-      begin
-        spr.enum:=R_INTREGISTER;
-        spr.number:=NR_SELF_POINTER_REG;
+        reg  : tregister;
+     begin
         if is_class(procinfo._class) then
         if is_class(procinfo._class) then
          begin
          begin
-           { 2nd parameter  : flag }
-           reference_reset_base(href, procinfo.framepointer,procinfo.selfpointer_offset+POINTER_SIZE);
+           if procinfo.selfpointer_offset=0 then
+            internalerror(200303253);
+           { parameter 2 : flag }
+           if procinfo.inheritedflag_offset=0 then
+            internalerror(200303251);
+           reference_reset_base(href, procinfo.framepointer,procinfo.inheritedflag_offset);
            a_param_ref(list, OS_ADDR,href,paramanager.getintparaloc(2));
            a_param_ref(list, OS_ADDR,href,paramanager.getintparaloc(2));
-           { 1st parameter to destructor : self }
+           { parameter 1 : self }
+           if procinfo.selfpointer_offset=0 then
+            internalerror(200303252);
            reference_reset_base(href, procinfo.framepointer,procinfo.selfpointer_offset);
            reference_reset_base(href, procinfo.framepointer,procinfo.selfpointer_offset);
            a_param_ref(list, OS_ADDR,href,paramanager.getintparaloc(1));
            a_param_ref(list, OS_ADDR,href,paramanager.getintparaloc(1));
            a_call_name(list,'FPC_DISPOSE_CLASS')
            a_call_name(list,'FPC_DISPOSE_CLASS')
          end
          end
         else if is_object(procinfo._class) then
         else if is_object(procinfo._class) then
          begin
          begin
-           { must the object be finalized ? }
-           if procinfo._class.needs_inittable then
-            begin
-              objectlibrary.getlabel(nofinal);
-              reference_reset_base(href,procinfo.framepointer,target_info.first_parm_offset);
-              a_cmp_const_ref_label(list,OS_ADDR,OC_EQ,0,href,nofinal);
-              reference_reset_base(href,spr,0);
-              g_finalize(list,procinfo._class,href,false);
-              a_label(list,nofinal);
-            end;
-           { actually call destructor }
-            { parameter 3 :vmt_offset     }
+            if procinfo.selfpointer_offset=0 then
+             internalerror(200303254);
+            if procinfo.vmtpointer_offset=0 then
+             internalerror(200303255);
+            { must the object be finalized ? }
+            if procinfo._class.needs_inittable then
+             begin
+               objectlibrary.getlabel(nofinal);
+               reference_reset_base(href,procinfo.framepointer,target_info.first_parm_offset);
+               a_cmp_const_ref_label(list,OS_ADDR,OC_EQ,0,href,nofinal);
+               reg:=g_load_self(list);
+               reference_reset_base(href,reg,0);
+               g_finalize(list,procinfo._class,href,false);
+               reference_release(list,href);
+               a_label(list,nofinal);
+             end;
+            { actually call destructor }
+            { parameter 3 : vmt_offset }
             a_param_const(list, OS_32, procinfo._class.vmt_offset, paramanager.getintparaloc(3));
             a_param_const(list, OS_32, procinfo._class.vmt_offset, paramanager.getintparaloc(3));
             { parameter 2 : pointer to vmt }
             { parameter 2 : pointer to vmt }
-            {  this is the first parameter which was pushed to the destructor }
-            reference_reset_base(href, procinfo.framepointer,procinfo.selfpointer_offset-POINTER_SIZE);
+            reference_reset_base(href, procinfo.framepointer,procinfo.vmtpointer_offset);
             a_param_ref(list, OS_ADDR, href ,paramanager.getintparaloc(2));
             a_param_ref(list, OS_ADDR, href ,paramanager.getintparaloc(2));
-            { parameter 1 : address of self pointer   }
+            { parameter 1 : address of self pointer }
             reference_reset_base(href, procinfo.framepointer,procinfo.selfpointer_offset);
             reference_reset_base(href, procinfo.framepointer,procinfo.selfpointer_offset);
-            hregister:=get_scratch_reg_address(list);
-            a_loadaddr_ref_reg(list, href, hregister);
-            a_param_reg(list, OS_ADDR,hregister,paramanager.getintparaloc(1));
-            free_scratch_reg(list, hregister);
+            a_param_ref(list, OS_ADDR, href ,paramanager.getintparaloc(1));
             a_call_name(list,'FPC_HELP_DESTRUCTOR');
             a_call_name(list,'FPC_HELP_DESTRUCTOR');
          end
          end
         else
         else
@@ -1617,51 +1616,39 @@ unit cgobj;
     procedure tcg.g_call_fail_helper(list : taasmoutput);
     procedure tcg.g_call_fail_helper(list : taasmoutput);
       var
       var
         href : treference;
         href : treference;
-        hregister : tregister;
-        spr : Tregister;
-      begin
-        spr.enum:=R_INTREGISTER;
-        spr.number:=NR_SELF_POINTER_REG;
+     begin
         if is_class(procinfo._class) then
         if is_class(procinfo._class) then
           begin
           begin
-            {
-              Dispose of the class then set self_pointer to nil
-              both in stack and in self register.
-            }
-            { 2nd parameter  : flag }
+            if procinfo.selfpointer_offset=0 then
+             internalerror(200303256);
+            { parameter 2 : flag, 0 -> inherited call (=no dispose) }
             a_param_const(list,OS_32,1,paramanager.getintparaloc(2));
             a_param_const(list,OS_32,1,paramanager.getintparaloc(2));
-            { 1st parameter to destructor : self }
+            { parameter 1 : self }
             reference_reset_base(href, procinfo.framepointer,procinfo.selfpointer_offset);
             reference_reset_base(href, procinfo.framepointer,procinfo.selfpointer_offset);
             a_param_ref(list, OS_ADDR,href,paramanager.getintparaloc(1));
             a_param_ref(list, OS_ADDR,href,paramanager.getintparaloc(1));
             a_call_name(list,'FPC_DISPOSE_CLASS');
             a_call_name(list,'FPC_DISPOSE_CLASS');
-            { SET SELF TO NIL }
-            a_load_const_reg(list,OS_ADDR,0,spr);
-            { set the self pointer in the stack to nil }
-            a_load_reg_ref(list,OS_ADDR,spr,href);
           end
           end
         else if is_object(procinfo._class) then
         else if is_object(procinfo._class) then
           begin
           begin
-            { parameter 3 :vmt_offset     }
+            if procinfo.selfpointer_offset=0 then
+             internalerror(200303257);
+            if procinfo.vmtpointer_offset=0 then
+             internalerror(200303258);
+            { parameter 3 : vmt_offset }
             a_param_const(list, OS_32, procinfo._class.vmt_offset, paramanager.getintparaloc(3));
             a_param_const(list, OS_32, procinfo._class.vmt_offset, paramanager.getintparaloc(3));
-            { parameter 2 : address of pointer to vmt }
-            {  this is the first(?) parameter which was pushed to the constructor }
-            reference_reset_base(href, procinfo.framepointer,procinfo.selfpointer_offset-POINTER_SIZE);
-            hregister:=get_scratch_reg_address(list);
-            a_loadaddr_ref_reg(list, href, hregister);
-            a_param_reg(list, OS_ADDR,hregister,paramanager.getintparaloc(2));
-            free_scratch_reg(list, hregister);
+            { parameter 2 : address of pointer to vmt, will be reset to 0 when freed }
+            reference_reset_base(href, procinfo.framepointer,procinfo.vmtpointer_offset);
+            a_paramaddr_ref(list,href,paramanager.getintparaloc(2));
             { parameter 1 : address of self pointer   }
             { parameter 1 : address of self pointer   }
             reference_reset_base(href, procinfo.framepointer,procinfo.selfpointer_offset);
             reference_reset_base(href, procinfo.framepointer,procinfo.selfpointer_offset);
-            hregister:=get_scratch_reg_address(list);
-            a_loadaddr_ref_reg(list, href, hregister);
-            a_param_reg(list, OS_ADDR,hregister,paramanager.getintparaloc(1));
-            free_scratch_reg(list, hregister);
+            a_paramaddr_ref(list,href,paramanager.getintparaloc(1));
             a_call_name(list,'FPC_HELP_FAIL');
             a_call_name(list,'FPC_HELP_FAIL');
-            { SET SELF TO NIL }
-            a_load_const_reg(list,OS_ADDR,0,spr);
           end
           end
         else
         else
           internalerror(200006163);
           internalerror(200006163);
+        { set self to nil }
+        reference_reset_base(href, procinfo.framepointer,procinfo.selfpointer_offset);
+        a_load_const_ref(list,OS_ADDR,0,href);
       end;
       end;
 
 
 
 
@@ -1732,7 +1719,12 @@ finalization
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.79  2003-03-22 18:07:18  jonas
+  Revision 1.80  2003-03-28 19:16:56  peter
+    * generic constructor working for i386
+    * remove fixed self register
+    * esi added as address register for i386
+
+  Revision 1.79  2003/03/22 18:07:18  jonas
     + add used scratch registers to usedintbyproc for non-i386
     + add used scratch registers to usedintbyproc for non-i386
 
 
   Revision 1.78  2003/03/11 21:46:24  jonas
   Revision 1.78  2003/03/11 21:46:24  jonas

+ 9 - 14
compiler/i386/cpubase.pas

@@ -517,9 +517,9 @@ uses
 {$ifdef newra}
 {$ifdef newra}
       usableregsint = [first_imreg..last_imreg];
       usableregsint = [first_imreg..last_imreg];
 {$else}
 {$else}
-      usableregsint = [RS_EAX,RS_EBX,RS_ECX,RS_EDX];
+      usableregsint = [RS_EAX,RS_EBX,RS_ECX,RS_EDX,RS_ESI];
 {$endif}
 {$endif}
-      c_countusableregsint = 4;
+      c_countusableregsint = 5;
 
 
       maxfpuregs = 8;
       maxfpuregs = 8;
       fpuregs = [R_ST0..R_ST7];
       fpuregs = [R_ST0..R_ST7];
@@ -537,7 +537,7 @@ uses
 
 
 
 
       firstsaveintreg = RS_EAX;
       firstsaveintreg = RS_EAX;
-      lastsaveintreg  = RS_EDX;
+      lastsaveintreg  = RS_ESI;
       firstsavefpureg = R_NO;
       firstsavefpureg = R_NO;
       lastsavefpureg  = R_NO;
       lastsavefpureg  = R_NO;
       firstsavemmreg  = R_MM0;
       firstsavemmreg  = R_MM0;
@@ -604,16 +604,6 @@ uses
       {# Frame pointer register }
       {# Frame pointer register }
       frame_pointer_reg = R_EBP;
       frame_pointer_reg = R_EBP;
       NR_FRAME_POINTER_REG = NR_EBP;
       NR_FRAME_POINTER_REG = NR_EBP;
-      {# Self pointer register : contains the instance address of an
-         object or class. }
-      self_pointer_reg  = R_ESI;
-{$ifdef newra}
-      RS_SELF_POINTER_REG  = $11;
-      NR_SELF_POINTER_REG  = $1103;
-{$else}
-      RS_SELF_POINTER_REG  = RS_ESI;
-      NR_SELF_POINTER_REG  = NR_ESI;
-{$endif}
       {# Register for addressing absolute data in a position independant way,
       {# Register for addressing absolute data in a position independant way,
          such as in PIC code. The exact meaning is ABI specific. For
          such as in PIC code. The exact meaning is ABI specific. For
          further information look at GCC source : PIC_OFFSET_TABLE_REGNUM
          further information look at GCC source : PIC_OFFSET_TABLE_REGNUM
@@ -824,7 +814,12 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.44  2003-03-18 18:15:53  peter
+  Revision 1.45  2003-03-28 19:16:57  peter
+    * generic constructor working for i386
+    * remove fixed self register
+    * esi added as address register for i386
+
+  Revision 1.44  2003/03/18 18:15:53  peter
     * changed reg2opsize to function
     * changed reg2opsize to function
 
 
   Revision 1.43  2003/03/08 08:59:07  daniel
   Revision 1.43  2003/03/08 08:59:07  daniel

+ 14 - 11
compiler/i386/csopt386.pas

@@ -193,7 +193,7 @@ begin
     not(ref.base.enum in (rg.usableregsint+[R_EDI]));}
     not(ref.base.enum in (rg.usableregsint+[R_EDI]));}
   isSimpleMemLoc :=
   isSimpleMemLoc :=
     (ref.index.enum = R_NO) and
     (ref.index.enum = R_NO) and
-    not(ref.base.enum in [R_EAX,R_EBX,R_ECX,R_EDX,R_EDI]);
+    not(ref.base.enum in [R_EAX,R_EBX,R_ECX,R_EDX,R_ESI,R_EDI]);
 end;
 end;
 
 
 {checks whether the current instruction sequence (starting with p) and the
 {checks whether the current instruction sequence (starting with p) and the
@@ -277,7 +277,7 @@ var
 {    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
        not getLastInstruction(currentPrev,hp) then
       exit;}
       exit;}
-    if (passedJump and not(reg.enum in [R_EAX,R_EBX,R_ECX,R_EDX,R_EDI])) or
+    if (passedJump and not(reg.enum in [R_EAX,R_EBX,R_ECX,R_EDX,R_ESI,R_EDI])) or
        not getLastInstruction(currentPrev,hp) then
        not getLastInstruction(currentPrev,hp) then
       exit;
       exit;
 
 
@@ -305,7 +305,7 @@ var
            { jump with a new value, since if the jump is taken, the old value }
            { jump with a new value, since if the jump is taken, the old value }
            { is (probably) still necessary                                    }
            { 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_EAX,R_EBX,R_ECX,R_EDX,R_EDI])) or
+           (passedJump and not(reg.enum in [R_EAX,R_EBX,R_ECX,R_EDX,R_ESI,R_EDI])) or
            not getLastInstruction(hp,hp) then
            not getLastInstruction(hp,hp) then
           break;
           break;
       end;
       end;
@@ -363,8 +363,8 @@ Begin {CheckSequence}
   OrgRegResult := False;
   OrgRegResult := False;
   with startRegInfo do
   with startRegInfo do
     begin
     begin
-      newRegsEncountered := [procinfo.FramePointer.enum, STACK_POINTER_REG];
-      new2OldReg[procinfo.FramePointer.enum] := procinfo.FramePointer;
+      newRegsEncountered := [FRAME_POINTER_REG, STACK_POINTER_REG];
+      new2OldReg[FRAME_POINTER_REG].enum := FRAME_POINTER_REG;
       new2OldReg[STACK_POINTER_REG].enum := STACK_POINTER_REG;
       new2OldReg[STACK_POINTER_REG].enum := STACK_POINTER_REG;
       oldRegsEncountered := newRegsEncountered;
       oldRegsEncountered := newRegsEncountered;
     end;
     end;
@@ -411,11 +411,9 @@ Begin {CheckSequence}
                     if (found <> 0) and
                     if (found <> 0) and
                        ((base.enum = R_NO) or
                        ((base.enum = R_NO) or
                         regModified[base.enum] or
                         regModified[base.enum] or
-                        (base.enum = procinfo.framepointer.enum) or
-                        (assigned(procinfo._class) and (base.enum = R_ESI))) and
+                        (base.enum = procinfo.framepointer.enum)) and
                        ((index.enum = R_NO) or
                        ((index.enum = R_NO) or
-                        regModified[index.enum] or
-                        (assigned(procinfo._class) and (index.enum = R_ESI))) and
+                        regModified[index.enum]) and
                         not(regInRef(tmpReg,Taicpu(hp3).oper[0].ref^)) then
                         not(regInRef(tmpReg,Taicpu(hp3).oper[0].ref^)) then
                       with pTaiprop(hp3.optinfo)^.regs[tmpreg.enum] do
                       with pTaiprop(hp3.optinfo)^.regs[tmpreg.enum] do
                         if nrOfMods > (oldNrOfMods - found) then
                         if nrOfMods > (oldNrOfMods - found) then
@@ -1695,7 +1693,7 @@ Begin
                         if (Taicpu(p).oper[0].typ = top_reg) and
                         if (Taicpu(p).oper[0].typ = top_reg) and
                            (Taicpu(p).oper[1].typ = top_reg) and
                            (Taicpu(p).oper[1].typ = top_reg) and
                            { only remove if we're not storing something in a regvar }
                            { only remove if we're not storing something in a regvar }
-                           (Taicpu(p).oper[1].reg.enum in [R_EAX,R_EBX,R_ECX,R_EDX,R_EDI]) and
+                           (Taicpu(p).oper[1].reg.enum in [R_EAX,R_EBX,R_ECX,R_EDX,R_ESI,R_EDI]) and
 {                           (Taicpu(p).oper[1].reg.enum in (rg.usableregsint+[R_EDI])) and}
 {                           (Taicpu(p).oper[1].reg.enum in (rg.usableregsint+[R_EDI])) and}
                            (Taicpu(p).opcode = A_MOV) and
                            (Taicpu(p).opcode = A_MOV) and
                            getLastInstruction(p,hp4) and
                            getLastInstruction(p,hp4) and
@@ -1999,7 +1997,12 @@ End.
 
 
 {
 {
   $Log$
   $Log$
-  Revision 1.42  2003-03-18 18:15:53  peter
+  Revision 1.43  2003-03-28 19:16:57  peter
+    * generic constructor working for i386
+    * remove fixed self register
+    * esi added as address register for i386
+
+  Revision 1.42  2003/03/18 18:15:53  peter
     * changed reg2opsize to function
     * changed reg2opsize to function
 
 
   Revision 1.41  2003/02/26 21:15:43  daniel
   Revision 1.41  2003/02/26 21:15:43  daniel

+ 12 - 9
compiler/i386/daopt386.pas

@@ -448,12 +448,12 @@ begin
     internalerror(200301081);
     internalerror(200301081);
 { if not(reg.enum in rg.usableregsint) then
 { if not(reg.enum in rg.usableregsint) then
     exit;}
     exit;}
- if not(reg.enum in [R_ESI,R_EDI]) then
+ if not(reg.enum in [R_EDI]) then
     exit;
     exit;
   getNoDeallocRegs(funcResRegs);
   getNoDeallocRegs(funcResRegs);
 {  funcResRegs := funcResRegs - rg.usableregsint;}
 {  funcResRegs := funcResRegs - rg.usableregsint;}
-{  funcResRegs := funcResRegs - [R_ESI,R_EDI];}
-  funcResRegs := funcResRegs - [R_EAX,R_EBX,R_ECX,R_EDX];
+{  funcResRegs := funcResRegs - [R_EDI];}
+  funcResRegs := funcResRegs - [R_EAX,R_EBX,R_ECX,R_EDX,R_ESI];
   funcResReg := reg.enum in funcResRegs;
   funcResReg := reg.enum in funcResRegs;
   hp1 := p;
   hp1 := p;
   while not(funcResReg and
   while not(funcResReg and
@@ -499,7 +499,7 @@ Begin
             LabelTable^[Tai_Label(p).l.labelnr-LowLabel].TaiObj := p;
             LabelTable^[Tai_Label(p).l.labelnr-LowLabel].TaiObj := p;
         ait_regAlloc:
         ait_regAlloc:
           { ESI and EDI are (de)allocated manually, don't mess with them }
           { ESI and EDI are (de)allocated manually, don't mess with them }
-          if not(tai_regalloc(p).Reg.enum in [R_EDI,R_ESI]) then
+          if not(tai_regalloc(p).Reg.enum in [R_EDI]) then
             begin
             begin
               if tai_regalloc(p).Allocation then
               if tai_regalloc(p).Allocation then
                 Begin
                 Begin
@@ -618,7 +618,7 @@ Begin
             prev.next := new_one;
             prev.next := new_one;
             foll.previous := new_one;
             foll.previous := new_one;
             { shgould we update line information }
             { shgould we update line information }
-            if (not (Tai(new_one).typ in SkipLineInfo)) and 
+            if (not (Tai(new_one).typ in SkipLineInfo)) and
                (not (Tai(foll).typ in SkipLineInfo)) then
                (not (Tai(foll).typ in SkipLineInfo)) then
             Tailineinfo(new_one).fileinfo := Tailineinfo(foll).fileinfo;
             Tailineinfo(new_one).fileinfo := Tailineinfo(foll).fileinfo;
           End;
           End;
@@ -1738,9 +1738,7 @@ function isSimpleRef(const ref: treference): boolean;
 begin
 begin
   isSimpleRef :=
   isSimpleRef :=
     assigned(ref.symbol) or
     assigned(ref.symbol) or
-    (ref.base.enum = procinfo.framepointer.enum) or
-    (assigned(procinfo._class) and
-     (ref.base.enum = R_ESI));
+    (ref.base.enum = procinfo.framepointer.enum);
 end;
 end;
 
 
 function containsPointerRef(p: Tai): boolean;
 function containsPointerRef(p: Tai): boolean;
@@ -2671,7 +2669,12 @@ End.
 
 
 {
 {
   $Log$
   $Log$
-  Revision 1.47  2003-02-26 21:15:43  daniel
+  Revision 1.48  2003-03-28 19:16:57  peter
+    * generic constructor working for i386
+    * remove fixed self register
+    * esi added as address register for i386
+
+  Revision 1.47  2003/02/26 21:15:43  daniel
     * Fixed the optimizer
     * Fixed the optimizer
 
 
   Revision 1.46  2003/02/19 22:00:15  daniel
   Revision 1.46  2003/02/19 22:00:15  daniel

+ 8 - 7
compiler/i386/n386add.pas

@@ -195,8 +195,7 @@ interface
       var
       var
         power : longint;
         power : longint;
         hl4   : tasmlabel;
         hl4   : tasmlabel;
-        r:Tregister;
-        nr:Tnewregister;
+        r     : Tregister;
       begin
       begin
         { at this point, left.location.loc should be LOC_REGISTER }
         { at this point, left.location.loc should be LOC_REGISTER }
         if right.location.loc=LOC_REGISTER then
         if right.location.loc=LOC_REGISTER then
@@ -399,7 +398,6 @@ interface
                         rg.saveintregvars(exprasmlist,regstopush);
                         rg.saveintregvars(exprasmlist,regstopush);
                         cg.a_call_name(exprasmlist,'FPC_SHORTSTR_CONCAT');
                         cg.a_call_name(exprasmlist,'FPC_SHORTSTR_CONCAT');
                         tg.ungetiftemp(exprasmlist,right.location.reference);
                         tg.ungetiftemp(exprasmlist,right.location.reference);
-                        cg.g_maybe_loadself(exprasmlist);
                         rg.restoreusedintregisters(exprasmlist,pushed);
                         rg.restoreusedintregisters(exprasmlist,pushed);
                         location_copy(location,left.location);
                         location_copy(location,left.location);
                      end;
                      end;
@@ -415,7 +413,6 @@ interface
                        cg.a_paramaddr_ref(exprasmlist,right.location.reference,paramanager.getintparaloc(1));
                        cg.a_paramaddr_ref(exprasmlist,right.location.reference,paramanager.getintparaloc(1));
                        rg.saveintregvars(exprasmlist,all_intregisters);
                        rg.saveintregvars(exprasmlist,all_intregisters);
                        cg.a_call_name(exprasmlist,'FPC_SHORTSTR_COMPARE');
                        cg.a_call_name(exprasmlist,'FPC_SHORTSTR_COMPARE');
-                       cg.g_maybe_loadself(exprasmlist);
                        rg.restoreusedintregisters(exprasmlist,pushed);
                        rg.restoreusedintregisters(exprasmlist,pushed);
                        location_freetemp(exprasmlist,left.location);
                        location_freetemp(exprasmlist,left.location);
                        location_freetemp(exprasmlist,right.location);
                        location_freetemp(exprasmlist,right.location);
@@ -1040,7 +1037,7 @@ interface
               rg.getexplicitregisterint(exprasmlist,NR_EDI);
               rg.getexplicitregisterint(exprasmlist,NR_EDI);
               r.enum:=R_INTREGISTER;
               r.enum:=R_INTREGISTER;
               r.number:=NR_EDI;
               r.number:=NR_EDI;
-{$endif}            
+{$endif}
               cg64.a_load64low_loc_reg(exprasmlist,right.location,r);
               cg64.a_load64low_loc_reg(exprasmlist,right.location,r);
               emit_reg_reg(op1,opsize,left.location.registerlow,r);
               emit_reg_reg(op1,opsize,left.location.registerlow,r);
               emit_reg_reg(A_MOV,opsize,r,left.location.registerlow);
               emit_reg_reg(A_MOV,opsize,r,left.location.registerlow);
@@ -1459,7 +1456,6 @@ interface
          pushedfpu,
          pushedfpu,
          mboverflow,cmpop : boolean;
          mboverflow,cmpop : boolean;
          op : tasmop;
          op : tasmop;
-         power : longint;
          opsize : topsize;
          opsize : topsize;
 
 
          { true, if unsigned types are compared }
          { true, if unsigned types are compared }
@@ -1645,7 +1641,12 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.59  2003-03-13 19:52:23  jonas
+  Revision 1.60  2003-03-28 19:16:57  peter
+    * generic constructor working for i386
+    * remove fixed self register
+    * esi added as address register for i386
+
+  Revision 1.59  2003/03/13 19:52:23  jonas
     * and more new register allocator fixes (in the i386 code generator this
     * and more new register allocator fixes (in the i386 code generator this
       time). At least now the ppc cross compiler can compile the linux
       time). At least now the ppc cross compiler can compile the linux
       system unit again, but I haven't tested it.
       system unit again, but I haven't tested it.

File diff suppressed because it is too large
+ 381 - 468
compiler/i386/n386cal.pas


+ 12 - 5
compiler/i386/n386mat.pas

@@ -555,7 +555,7 @@ implementation
           { load left operators in a register }
           { load left operators in a register }
           location_copy(location,left.location);
           location_copy(location,left.location);
           location_force_reg(exprasmlist,location,OS_INT,false);
           location_force_reg(exprasmlist,location,OS_INT,false);
-             
+
           r2.enum:=R_INTREGISTER;
           r2.enum:=R_INTREGISTER;
           r2.number:=NR_CL;
           r2.number:=NR_CL;
 
 
@@ -784,7 +784,7 @@ implementation
               { load left operators in a register }
               { load left operators in a register }
               location_copy(location,left.location);
               location_copy(location,left.location);
               location_force_reg(exprasmlist,location,OS_INT,false);
               location_force_reg(exprasmlist,location,OS_INT,false);
-              
+
               r.enum:=R_INTREGISTER;
               r.enum:=R_INTREGISTER;
               r.number:=NR_ECX;
               r.number:=NR_ECX;
               r2.enum:=R_INTREGISTER;
               r2.enum:=R_INTREGISTER;
@@ -905,7 +905,7 @@ implementation
 
 
 
 
     procedure ti386unaryminusnode.pass_2;
     procedure ti386unaryminusnode.pass_2;
-    
+
     var r:Tregister;
     var r:Tregister;
 
 
 {$ifdef SUPPORT_MMX}
 {$ifdef SUPPORT_MMX}
@@ -1054,7 +1054,9 @@ implementation
       var
       var
          hl : tasmlabel;
          hl : tasmlabel;
          opsize : topsize;
          opsize : topsize;
-         r,r2:Tregister;
+{$ifdef SUPPORT_MMX}
+         r,r2 : tregister;
+{$endif SUPPORT_MMX}
       begin
       begin
          if is_boolean(resulttype.def) then
          if is_boolean(resulttype.def) then
           begin
           begin
@@ -1169,7 +1171,12 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.47  2003-03-08 20:36:41  daniel
+  Revision 1.48  2003-03-28 19:16:57  peter
+    * generic constructor working for i386
+    * remove fixed self register
+    * esi added as address register for i386
+
+  Revision 1.47  2003/03/08 20:36:41  daniel
     + Added newra version of Ti386shlshrnode
     + Added newra version of Ti386shlshrnode
     + Added interference graph construction code
     + Added interference graph construction code
 
 

+ 6 - 3
compiler/i386/n386mem.pas

@@ -77,8 +77,6 @@ implementation
 *****************************************************************************}
 *****************************************************************************}
 
 
     procedure ti386derefnode.pass_2;
     procedure ti386derefnode.pass_2;
-      var
-        oldglobalswitches : tglobalswitches;
       begin
       begin
          inherited pass_2;
          inherited pass_2;
          if tpointerdef(left.resulttype.def).is_far then
          if tpointerdef(left.resulttype.def).is_far then
@@ -156,7 +154,12 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.50  2003-02-19 22:00:15  daniel
+  Revision 1.51  2003-03-28 19:16:57  peter
+    * generic constructor working for i386
+    * remove fixed self register
+    * esi added as address register for i386
+
+  Revision 1.50  2003/02/19 22:00:15  daniel
     * Code generator converted to new register notation
     * Code generator converted to new register notation
     - Horribily outdated todo.txt removed
     - Horribily outdated todo.txt removed
 
 

+ 6 - 2
compiler/i386/n386opt.pas

@@ -238,7 +238,6 @@ begin
   rg.saveintregvars(exprasmlist,regstopush);
   rg.saveintregvars(exprasmlist,regstopush);
   cg.a_call_name(exprasmlist,'FPC_SHORTSTR_CONCAT');
   cg.a_call_name(exprasmlist,'FPC_SHORTSTR_CONCAT');
   tg.ungetiftemp(exprasmlist,right.location.reference);
   tg.ungetiftemp(exprasmlist,right.location.reference);
-  cg.g_maybe_loadself(exprasmlist);
   rg.restoreusedintregisters(exprasmlist,pushedregs);
   rg.restoreusedintregisters(exprasmlist,pushedregs);
   location_copy(location,left.location);
   location_copy(location,left.location);
 end;
 end;
@@ -250,7 +249,12 @@ end.
 
 
 {
 {
   $Log$
   $Log$
-  Revision 1.28  2003-02-19 22:00:15  daniel
+  Revision 1.29  2003-03-28 19:16:57  peter
+    * generic constructor working for i386
+    * remove fixed self register
+    * esi added as address register for i386
+
+  Revision 1.28  2003/02/19 22:00:15  daniel
     * Code generator converted to new register notation
     * Code generator converted to new register notation
     - Horribily outdated todo.txt removed
     - Horribily outdated todo.txt removed
 
 

+ 9 - 4
compiler/i386/popt386.pas

@@ -898,7 +898,7 @@ Begin
                 Begin
                 Begin
                   TmpUsedRegs := UsedRegs;
                   TmpUsedRegs := UsedRegs;
                   If (Taicpu(p).oper[1].typ = top_reg) And
                   If (Taicpu(p).oper[1].typ = top_reg) And
-                     (Taicpu(p).oper[1].reg.enum In [R_EAX, R_EBX, R_EDX, R_EDI]) And
+                     (Taicpu(p).oper[1].reg.enum In [R_EAX, R_EBX, R_ECX, R_EDX, R_ESI, R_EDI]) And
                      GetNextInstruction(p, hp1) And
                      GetNextInstruction(p, hp1) And
                      (Tai(hp1).typ = ait_instruction) And
                      (Tai(hp1).typ = ait_instruction) And
                      (Taicpu(hp1).opcode = A_MOV) And
                      (Taicpu(hp1).opcode = A_MOV) And
@@ -1135,9 +1135,9 @@ Begin
                                             allocRegBetween(asmL,Taicpu(p).oper[0].ref^.base,p,hp2);
                                             allocRegBetween(asmL,Taicpu(p).oper[0].ref^.base,p,hp2);
                                           if (Taicpu(p).oper[0].ref^.index.enum in (rg.usableregsint+[R_EDI])) then
                                           if (Taicpu(p).oper[0].ref^.index.enum in (rg.usableregsint+[R_EDI])) then
                                             allocRegBetween(asmL,Taicpu(p).oper[0].ref^.index,p,hp2);}
                                             allocRegBetween(asmL,Taicpu(p).oper[0].ref^.index,p,hp2);}
-                                          if (Taicpu(p).oper[0].ref^.base.enum in [R_ESI,R_EDI]) then
+                                          if (Taicpu(p).oper[0].ref^.base.enum in [R_EDI]) then
                                             allocRegBetween(asmL,Taicpu(p).oper[0].ref^.base,p,hp2);
                                             allocRegBetween(asmL,Taicpu(p).oper[0].ref^.base,p,hp2);
-                                          if (Taicpu(p).oper[0].ref^.index.enum in [R_ESI,R_EDI]) then
+                                          if (Taicpu(p).oper[0].ref^.index.enum in [R_EDI]) then
                                             allocRegBetween(asmL,Taicpu(p).oper[0].ref^.index,p,hp2);
                                             allocRegBetween(asmL,Taicpu(p).oper[0].ref^.index,p,hp2);
                                         End
                                         End
                                       Else
                                       Else
@@ -2058,7 +2058,12 @@ End.
 
 
 {
 {
   $Log$
   $Log$
-  Revision 1.41  2003-02-26 13:24:59  daniel
+  Revision 1.42  2003-03-28 19:16:57  peter
+    * generic constructor working for i386
+    * remove fixed self register
+    * esi added as address register for i386
+
+  Revision 1.41  2003/02/26 13:24:59  daniel
     * Disabled mov reg,0 -> xor reg,reg optimization
     * Disabled mov reg,0 -> xor reg,reg optimization
 
 
   Revision 1.40  2003/02/25 07:41:54  daniel
   Revision 1.40  2003/02/25 07:41:54  daniel

+ 6 - 10
compiler/i386/ra386int.pas

@@ -1134,15 +1134,6 @@ Begin
                 { check if we can move the old base to the index register }
                 { check if we can move the old base to the index register }
                 if (opr.ref.index.number<>NR_NO) then
                 if (opr.ref.index.number<>NR_NO) then
                  Message(asmr_e_wrong_base_index)
                  Message(asmr_e_wrong_base_index)
-                else if assigned(procinfo._class) and
-                  (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
-                      caninvent in assembler ! }
-                    opr.ref.index:=oldbase;
-                  end
                 else
                 else
                  opr.ref.index:=oldbase;
                  opr.ref.index:=oldbase;
               end
               end
@@ -1980,7 +1971,12 @@ finalization
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.43  2003-03-18 18:15:53  peter
+  Revision 1.44  2003-03-28 19:16:57  peter
+    * generic constructor working for i386
+    * remove fixed self register
+    * esi added as address register for i386
+
+  Revision 1.43  2003/03/18 18:15:53  peter
     * changed reg2opsize to function
     * changed reg2opsize to function
 
 
   Revision 1.42  2003/03/17 21:32:52  peter
   Revision 1.42  2003/03/17 21:32:52  peter

+ 57 - 18
compiler/i386/rgcpu.pas

@@ -41,6 +41,7 @@ unit rgcpu;
           { to keep the same allocation order as with the old routines }
           { to keep the same allocation order as with the old routines }
 {$ifndef newra}
 {$ifndef newra}
           function getregisterint(list:Taasmoutput;size:Tcgsize):Tregister;override;
           function getregisterint(list:Taasmoutput;size:Tcgsize):Tregister;override;
+          function getaddressregister(list:Taasmoutput):Tregister;override;
           procedure ungetregisterint(list:Taasmoutput;r:Tregister); override;
           procedure ungetregisterint(list:Taasmoutput;r:Tregister); override;
           function getexplicitregisterint(list:Taasmoutput;r:Tnewregister):Tregister;override;
           function getexplicitregisterint(list:Taasmoutput;r:Tnewregister):Tregister;override;
 {$endif newra}
 {$endif newra}
@@ -176,7 +177,7 @@ unit rgcpu;
 
 
       if countunusedregsint=0 then
       if countunusedregsint=0 then
         internalerror(10);
         internalerror(10);
-      getregisterint.enum:=R_INTREGISTER;
+      result.enum:=R_INTREGISTER;
 {$ifdef TEMPREGDEBUG}
 {$ifdef TEMPREGDEBUG}
       if curptree^.usableregsint-countunusedregsint>curptree^.registers32 then
       if curptree^.usableregsint-countunusedregsint>curptree^.registers32 then
         internalerror(10);
         internalerror(10);
@@ -185,53 +186,87 @@ unit rgcpu;
       if curptree^.usableregs-countunusedregistersint>curptree^^.reallyusedregs then
       if curptree^.usableregs-countunusedregistersint>curptree^^.reallyusedregs then
         curptree^.reallyusedregs:=curptree^^.usableregs-countunusedregistersint;
         curptree^.reallyusedregs:=curptree^^.usableregs-countunusedregistersint;
 {$endif EXTTEMPREGDEBUG}
 {$endif EXTTEMPREGDEBUG}
-      dec(countunusedregsint);
       if RS_EAX in unusedregsint then
       if RS_EAX in unusedregsint then
         begin
         begin
+          dec(countunusedregsint);
           exclude(unusedregsint,RS_EAX);
           exclude(unusedregsint,RS_EAX);
           include(usedintinproc,RS_EAX);
           include(usedintinproc,RS_EAX);
-          getregisterint.number:=RS_EAX shl 8 or subreg;
+          result.number:=RS_EAX shl 8 or subreg;
 {$ifdef TEMPREGDEBUG}
 {$ifdef TEMPREGDEBUG}
           reg_user[R_EAX]:=curptree^;
           reg_user[R_EAX]:=curptree^;
 {$endif TEMPREGDEBUG}
 {$endif TEMPREGDEBUG}
-          exprasmlist.concat(tai_regalloc.alloc(getregisterint));
+          exprasmlist.concat(tai_regalloc.alloc(result));
         end
         end
       else if RS_EDX in unusedregsint then
       else if RS_EDX in unusedregsint then
         begin
         begin
+          dec(countunusedregsint);
           exclude(unusedregsint,RS_EDX);
           exclude(unusedregsint,RS_EDX);
           include(usedintinproc,RS_EDX);
           include(usedintinproc,RS_EDX);
-          getregisterint.number:=RS_EDX shl 8 or subreg;
+          result.number:=RS_EDX shl 8 or subreg;
 {$ifdef TEMPREGDEBUG}
 {$ifdef TEMPREGDEBUG}
           reg_user[R_EDX]:=curptree^;
           reg_user[R_EDX]:=curptree^;
 {$endif TEMPREGDEBUG}
 {$endif TEMPREGDEBUG}
-          exprasmlist.concat(tai_regalloc.alloc(getregisterint));
+          exprasmlist.concat(tai_regalloc.alloc(result));
         end
         end
       else if RS_EBX in unusedregsint then
       else if RS_EBX in unusedregsint then
         begin
         begin
+          dec(countunusedregsint);
           exclude(unusedregsint,RS_EBX);
           exclude(unusedregsint,RS_EBX);
           include(usedintinproc,RS_EBX);
           include(usedintinproc,RS_EBX);
-          getregisterint.number:=RS_EBX shl 8 or subreg;
+          result.number:=RS_EBX shl 8 or subreg;
 {$ifdef TEMPREGDEBUG}
 {$ifdef TEMPREGDEBUG}
           reg_user[R_EBX]:=curptree^;
           reg_user[R_EBX]:=curptree^;
 {$endif TEMPREGDEBUG}
 {$endif TEMPREGDEBUG}
-          exprasmlist.concat(tai_regalloc.alloc(getregisterint));
+          exprasmlist.concat(tai_regalloc.alloc(result));
         end
         end
       else if RS_ECX in unusedregsint then
       else if RS_ECX in unusedregsint then
         begin
         begin
+          dec(countunusedregsint);
           exclude(unusedregsint,RS_ECX);
           exclude(unusedregsint,RS_ECX);
           include(usedintinproc,RS_ECX);
           include(usedintinproc,RS_ECX);
-          getregisterint.number:=RS_ECX shl 8 or subreg;
+          result.number:=RS_ECX shl 8 or subreg;
 {$ifdef TEMPREGDEBUG}
 {$ifdef TEMPREGDEBUG}
           reg_user[R_ECX]:=curptree^;
           reg_user[R_ECX]:=curptree^;
 {$endif TEMPREGDEBUG}
 {$endif TEMPREGDEBUG}
-          exprasmlist.concat(tai_regalloc.alloc(getregisterint));
+          exprasmlist.concat(tai_regalloc.alloc(result));
         end
         end
-      else internalerror(10);
+      else
+        internalerror(10);
 {$ifdef TEMPREGDEBUG}
 {$ifdef TEMPREGDEBUG}
       testregisters;
       testregisters;
 {$endif TEMPREGDEBUG}
 {$endif TEMPREGDEBUG}
     end;
     end;
 
 
+
+    function trgcpu.getaddressregister(list:Taasmoutput):Tregister;
+    begin
+      if countunusedregsint=0 then
+        internalerror(10);
+      result.enum:=R_INTREGISTER;
+{$ifdef TEMPREGDEBUG}
+      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;
+{$endif EXTTEMPREGDEBUG}
+      if RS_ESI in unusedregsint then
+        begin
+          dec(countunusedregsint);
+          exclude(unusedregsint,RS_ESI);
+          include(usedintinproc,RS_ESI);
+          result.number:=NR_ESI;
+{$ifdef TEMPREGDEBUG}
+          reg_user[R_ESI]:=curptree^;
+{$endif TEMPREGDEBUG}
+          exprasmlist.concat(tai_regalloc.alloc(result));
+        end
+      else
+        result:=getregisterint(list,OS_ADDR);
+    end;
+
+
     procedure trgcpu.ungetregisterint(list: taasmoutput; r : tregister);
     procedure trgcpu.ungetregisterint(list: taasmoutput; r : tregister);
 
 
     var supreg:Tsuperregister;
     var supreg:Tsuperregister;
@@ -242,13 +277,12 @@ unit rgcpu;
          if r.enum<>R_INTREGISTER then
          if r.enum<>R_INTREGISTER then
             internalerror(200301234);
             internalerror(200301234);
          supreg:=r.number shr 8;
          supreg:=r.number shr 8;
-         if (supreg = RS_EDI) or
-            ((not assigned(procinfo._class)) and (supreg = RS_ESI)) then
+         if (supreg in [RS_EDI]) then
            begin
            begin
              list.concat(tai_regalloc.DeAlloc(r));
              list.concat(tai_regalloc.DeAlloc(r));
              exit;
              exit;
            end;
            end;
-         if not(supreg in [RS_EAX,RS_EBX,RS_ECX,RS_EDX]) then
+         if not(supreg in [RS_EAX,RS_EBX,RS_ECX,RS_EDX,RS_ESI]) then
            exit;
            exit;
          inherited ungetregisterint(list,r);
          inherited ungetregisterint(list,r);
       end;
       end;
@@ -259,7 +293,7 @@ unit rgcpu;
    var r2:Tregister;
    var r2:Tregister;
 
 
     begin
     begin
-      if (r shr 8) in [RS_ESI,RS_EDI] then
+      if (r shr 8) in [RS_EDI] then
         begin
         begin
           r2.enum:=R_INTREGISTER;
           r2.enum:=R_INTREGISTER;
           r2.number:=r;
           r2.number:=r;
@@ -308,7 +342,7 @@ unit rgcpu;
 
 
     begin
     begin
       usedintinproc:=usedintinproc+s;
       usedintinproc:=usedintinproc+s;
-      for r:=RS_EAX to RS_EDX do
+      for r:=firstsaveintreg to lastsaveintreg do
         begin
         begin
           r2.enum:=R_INTREGISTER;
           r2.enum:=R_INTREGISTER;
           r2.number:=r shl 8 or R_SUBWHOLE;
           r2.number:=r shl 8 or R_SUBWHOLE;
@@ -373,7 +407,7 @@ unit rgcpu;
         r2:Tregister;
         r2:Tregister;
     begin
     begin
       { restore in reverse order: }
       { restore in reverse order: }
-      for r:=RS_EDX downto RS_EAX do
+      for r:=lastsaveintreg downto firstsaveintreg do
         if pushed[r].pushed then
         if pushed[r].pushed then
           begin
           begin
             r2.enum:=R_INTREGISTER;
             r2.enum:=R_INTREGISTER;
@@ -525,7 +559,12 @@ end.
 
 
 {
 {
   $Log$
   $Log$
-  Revision 1.16  2003-03-17 15:52:57  peter
+  Revision 1.17  2003-03-28 19:16:57  peter
+    * generic constructor working for i386
+    * remove fixed self register
+    * esi added as address register for i386
+
+  Revision 1.16  2003/03/17 15:52:57  peter
     * SUPPORT_MMX define compile fix
     * SUPPORT_MMX define compile fix
 
 
   Revision 1.15  2003/03/08 13:59:17  daniel
   Revision 1.15  2003/03/08 13:59:17  daniel

+ 8 - 3
compiler/i386/rropt386.pas

@@ -333,8 +333,8 @@ begin
                      (Taicpu(p).opsize = S_L) and
                      (Taicpu(p).opsize = S_L) and
 {                     (Taicpu(p).oper[0].reg.enum in (rg.usableregsint+[R_EDI])) 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[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
+                     (Taicpu(p).oper[0].reg.enum in ([R_EDI])) and
+                     (Taicpu(p).oper[1].reg.enum in ([R_EDI])) then
                     if switchRegs(asml,Taicpu(p).oper[0].reg,
                     if switchRegs(asml,Taicpu(p).oper[0].reg,
                          Taicpu(p).oper[1].reg,p) then
                          Taicpu(p).oper[1].reg,p) then
                       begin
                       begin
@@ -358,7 +358,12 @@ End.
 
 
 {
 {
   $Log$
   $Log$
-  Revision 1.20  2003-02-19 22:00:16  daniel
+  Revision 1.21  2003-03-28 19:16:57  peter
+    * generic constructor working for i386
+    * remove fixed self register
+    * esi added as address register for i386
+
+  Revision 1.20  2003/02/19 22:00:16  daniel
     * Code generator converted to new register notation
     * Code generator converted to new register notation
     - Horribily outdated todo.txt removed
     - Horribily outdated todo.txt removed
 
 

+ 6 - 3
compiler/ncgbas.pas

@@ -209,8 +209,6 @@ interface
              else
              else
                exprasmList.concatlist(p_asm);
                exprasmList.concatlist(p_asm);
            end;
            end;
-         if not (nf_object_preserved in flags) then
-           cg.g_maybe_loadself(exprasmlist);
        end;
        end;
 
 
 
 
@@ -290,7 +288,12 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.28  2002-11-27 15:33:19  peter
+  Revision 1.29  2003-03-28 19:16:56  peter
+    * generic constructor working for i386
+    * remove fixed self register
+    * esi added as address register for i386
+
+  Revision 1.28  2002/11/27 15:33:19  peter
     * fixed relabeling to relabel only tasmlabel (formerly proclocal)
     * fixed relabeling to relabel only tasmlabel (formerly proclocal)
 
 
   Revision 1.27  2002/11/27 02:37:13  peter
   Revision 1.27  2002/11/27 02:37:13  peter

+ 23 - 31
compiler/ncgcal.pas

@@ -44,11 +44,11 @@ interface
           funcretref : treference;
           funcretref : treference;
           refcountedtemp : treference;
           refcountedtemp : treference;
           procedure handle_return_value(inlined,extended_new:boolean);
           procedure handle_return_value(inlined,extended_new:boolean);
-          {# This routine is used to push the current frame pointer 
+          {# This routine is used to push the current frame pointer
              on the stack. This is used in nested routines where the
              on the stack. This is used in nested routines where the
              value of the frame pointer is always pushed as an extra
              value of the frame pointer is always pushed as an extra
              parameter.
              parameter.
-             
+
              The default handling is the standard handling used on
              The default handling is the standard handling used on
              most stack based machines, where the frame pointer is
              most stack based machines, where the frame pointer is
              the first invisible parameter.
              the first invisible parameter.
@@ -104,7 +104,7 @@ implementation
             begin
             begin
               secondpass(hightree);
               secondpass(hightree);
               { this is a longint anyway ! }
               { this is a longint anyway ! }
-              push_value_para(hightree,calloption,para_offset,4,paraitem.paraloc);
+              push_value_para(exprasmlist,hightree,calloption,para_offset,4,paraitem.paraloc);
             end;
             end;
         end;
         end;
 {$endif VS_HIDDEN}
 {$endif VS_HIDDEN}
@@ -143,7 +143,7 @@ implementation
                  location_release(exprasmlist,left.location);
                  location_release(exprasmlist,left.location);
                end
                end
              else
              else
-               push_value_para(left,calloption,para_offset,para_alignment,paraitem.paraloc);
+               push_value_para(exprasmlist,left,calloption,para_offset,para_alignment,paraitem.paraloc);
            end
            end
          { filter array constructor with c styled args }
          { filter array constructor with c styled args }
          else if is_array_constructor(left.resulttype.def) and (nf_cargs in left.flags) then
          else if is_array_constructor(left.resulttype.def) and (nf_cargs in left.flags) then
@@ -296,7 +296,7 @@ implementation
                 end
                 end
               else
               else
                 begin
                 begin
-                   push_value_para(left,calloption,
+                   push_value_para(exprasmlist,left,calloption,
                      para_offset,para_alignment,paraitem.paraloc);
                      para_offset,para_alignment,paraitem.paraloc);
                 end;
                 end;
            end;
            end;
@@ -331,12 +331,12 @@ implementation
          emit_reg(A_PUSH,S_L,r);
          emit_reg(A_PUSH,S_L,r);
 {$endif i386}
 {$endif i386}
       end;
       end;
-      
-      
+
+
       procedure tcgcallnode.load_framepointer;
       procedure tcgcallnode.load_framepointer;
         var href : treference;
         var href : treference;
             hregister : tregister;
             hregister : tregister;
-            i: integer; 
+            i: integer;
         begin
         begin
           { this routine is itself not nested }
           { this routine is itself not nested }
           if lexlevel=(tprocdef(procdefinition).parast.symtablelevel) then
           if lexlevel=(tprocdef(procdefinition).parast.symtablelevel) then
@@ -349,7 +349,7 @@ implementation
             begin
             begin
               cg.a_param_reg(exprasmlist,OS_ADDR,procinfo.framepointer,paramanager.getintparaloc(1));
               cg.a_param_reg(exprasmlist,OS_ADDR,procinfo.framepointer,paramanager.getintparaloc(1));
             end
             end
-          { very complex nesting level ... }  
+          { very complex nesting level ... }
           else if (lexlevel>(tprocdef(procdefinition).parast.symtablelevel)) then
           else if (lexlevel>(tprocdef(procdefinition).parast.symtablelevel)) then
             begin
             begin
               hregister:=rg.getaddressregister(exprasmlist);
               hregister:=rg.getaddressregister(exprasmlist);
@@ -364,7 +364,7 @@ implementation
               rg.ungetaddressregister(exprasmlist,hregister);
               rg.ungetaddressregister(exprasmlist,hregister);
             end;
             end;
         end;
         end;
-      
+
 
 
 
 
 
 
@@ -403,24 +403,11 @@ implementation
               orddef :
               orddef :
                 begin
                 begin
                   cgsize:=def_cgsize(resulttype.def);
                   cgsize:=def_cgsize(resulttype.def);
-                  { an object constructor is a function with boolean result }
+
+                  { an object constructor is a function with pointer result }
                   if (inlined or (right=nil)) and
                   if (inlined or (right=nil)) and
                      (procdefinition.proctypeoption=potype_constructor) then
                      (procdefinition.proctypeoption=potype_constructor) then
-                   begin
-{$ifdef x86}
-                     if extended_new then
-                      cgsize:=OS_INT
-                     else
-                      begin
-                        cgsize:=OS_NO;
-                        { this fails if popsize > 0 PM }
-                        location_reset(location,LOC_FLAGS,OS_NO);
-                        location.resflags:=F_NE;
-                      end;
-{$else x86}
-                     cgsize:=OS_INT
-{$endif x86}
-                   end;
+                    cgsize:=OS_ADDR;
 
 
                   if cgsize<>OS_NO then
                   if cgsize<>OS_NO then
                    begin
                    begin
@@ -1130,7 +1117,6 @@ implementation
                           Internalerror(200006165);
                           Internalerror(200006165);
                      end;
                      end;
                 end;
                 end;
-{$endif dummy}
 
 
                 { call to BeforeDestruction? }
                 { call to BeforeDestruction? }
                 if (procdefinition.proctypeoption=potype_destructor) and
                 if (procdefinition.proctypeoption=potype_destructor) and
@@ -1150,6 +1136,8 @@ implementation
                      cg.a_call_ref(exprasmlist,href);
                      cg.a_call_ref(exprasmlist,href);
                      cg.free_scratch_reg(exprasmlist,tmpreg);
                      cg.free_scratch_reg(exprasmlist,tmpreg);
                   end;
                   end;
+{$endif dummy}
+
 {$ifndef SPARC}{We don't need that on SPARC arch!}
 {$ifndef SPARC}{We don't need that on SPARC arch!}
               { push base pointer ?}
               { push base pointer ?}
               { never when inlining, since if necessary, the base pointer }
               { never when inlining, since if necessary, the base pointer }
@@ -1364,6 +1352,7 @@ implementation
               cg.a_cmp_const_reg_label(exprasmlist,OS_ADDR,OC_EQ,0,r,faillabel);
               cg.a_cmp_const_reg_label(exprasmlist,OS_ADDR,OC_EQ,0,r,faillabel);
            end;
            end;
 
 
+{$ifdef dummy}
          { call to AfterConstruction? }
          { call to AfterConstruction? }
          if is_class(resulttype.def) and
          if is_class(resulttype.def) and
            (inlined or
            (inlined or
@@ -1389,6 +1378,7 @@ implementation
               cg.a_label(exprasmlist,constructorfailed);
               cg.a_label(exprasmlist,constructorfailed);
               cg.a_load_reg_reg(exprasmlist,OS_ADDR,OS_ADDR,r,r2);
               cg.a_load_reg_reg(exprasmlist,OS_ADDR,OS_ADDR,r,r2);
            end;
            end;
+{$endif dummy}
 
 
          { handle function results }
          { handle function results }
          if (not is_void(resulttype.def)) then
          if (not is_void(resulttype.def)) then
@@ -1413,9 +1403,6 @@ implementation
          rg.restoreusedotherregisters(exprasmlist,pushed);
          rg.restoreusedotherregisters(exprasmlist,pushed);
          rg.restoreusedintregisters(exprasmlist,pushedint);
          rg.restoreusedintregisters(exprasmlist,pushedint);
 
 
-         { at last, restore instance pointer (SELF) }
-         if loadesi then
-           cg.g_maybe_loadself(exprasmlist);
          pp:=tbinarynode(params);
          pp:=tbinarynode(params);
          while assigned(pp) do
          while assigned(pp) do
            begin
            begin
@@ -1666,7 +1653,12 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.40  2003-03-06 11:35:50  daniel
+  Revision 1.41  2003-03-28 19:16:56  peter
+    * generic constructor working for i386
+    * remove fixed self register
+    * esi added as address register for i386
+
+  Revision 1.40  2003/03/06 11:35:50  daniel
     * Fixed internalerror 7843 issue
     * Fixed internalerror 7843 issue
 
 
   Revision 1.39  2003/02/19 22:00:14  daniel
   Revision 1.39  2003/02/19 22:00:14  daniel

+ 8 - 2
compiler/ncgcnv.pas

@@ -76,7 +76,8 @@ interface
     procedure tcgtypeconvnode.second_int_to_int;
     procedure tcgtypeconvnode.second_int_to_int;
       var
       var
         newsize : tcgsize;
         newsize : tcgsize;
-        ressize, leftsize: cardinal;
+        ressize,
+        leftsize : longint;
       begin
       begin
         newsize:=def_cgsize(resulttype.def);
         newsize:=def_cgsize(resulttype.def);
 
 
@@ -510,7 +511,12 @@ end.
 
 
 {
 {
   $Log$
   $Log$
-  Revision 1.36  2003-02-19 22:00:14  daniel
+  Revision 1.37  2003-03-28 19:16:56  peter
+    * generic constructor working for i386
+    * remove fixed self register
+    * esi added as address register for i386
+
+  Revision 1.36  2003/02/19 22:00:14  daniel
     * Code generator converted to new register notation
     * Code generator converted to new register notation
     - Horribily outdated todo.txt removed
     - Horribily outdated todo.txt removed
 
 

+ 11 - 11
compiler/ncgflw.pas

@@ -327,9 +327,9 @@ implementation
          { first set the to value
          { first set the to value
            because the count var can be in the expression !! }
            because the count var can be in the expression !! }
          rg.cleartempgen;
          rg.cleartempgen;
-         
+
          do_loopvar_at_end:=lnf_dont_mind_loopvar_on_exit in loopflags;
          do_loopvar_at_end:=lnf_dont_mind_loopvar_on_exit in loopflags;
-         
+
          secondpass(right);
          secondpass(right);
          { calculate pointer value and check if changeable and if so }
          { calculate pointer value and check if changeable and if so }
          { load into temporary variable                       }
          { load into temporary variable                       }
@@ -384,7 +384,7 @@ implementation
                    t2.location,aktbreaklabel);
                    t2.location,aktbreaklabel);
                end;
                end;
            end;
            end;
-           
+
          {If the loopvar doesn't mind on exit, we avoid this ugly
          {If the loopvar doesn't mind on exit, we avoid this ugly
           dec instruction and do the loopvar inc/dec after the loop
           dec instruction and do the loopvar inc/dec after the loop
           body.}
           body.}
@@ -718,10 +718,10 @@ implementation
                         { get an 8-bit register }
                         { get an 8-bit register }
                         allocated_acc := true;
                         allocated_acc := true;
                         cg.a_label(exprasmlist,truelabel);
                         cg.a_label(exprasmlist,truelabel);
-                        cg.a_load_const_reg(exprasmlist,OS_8,1,hreg);
+                        cg.a_load_const_reg(exprasmlist,OS_8,1,r);
                         cg.a_jmp_always(exprasmlist,aktexit2label);
                         cg.a_jmp_always(exprasmlist,aktexit2label);
                         cg.a_label(exprasmlist,falselabel);
                         cg.a_label(exprasmlist,falselabel);
-                        cg.a_load_const_reg(exprasmlist,OS_8,0,hreg);
+                        cg.a_load_const_reg(exprasmlist,OS_8,0,r);
                         goto do_jmp;
                         goto do_jmp;
                       end;
                       end;
                   end;
                   end;
@@ -880,7 +880,6 @@ implementation
 
 
       var
       var
          a : tasmlabel;
          a : tasmlabel;
-         href : treference;
          href2: treference;
          href2: treference;
          r:Tregister;
          r:Tregister;
       begin
       begin
@@ -974,7 +973,6 @@ implementation
          r.number:=NR_ACCUMULATOR;
          r.number:=NR_ACCUMULATOR;
          cg.a_param_reg(exprasmlist,OS_ADDR,r,paramanager.getintparaloc(1));
          cg.a_param_reg(exprasmlist,OS_ADDR,r,paramanager.getintparaloc(1));
          cg.a_call_name(exprasmlist,'FPC_DESTROYEXCEPTION');
          cg.a_call_name(exprasmlist,'FPC_DESTROYEXCEPTION');
-         cg.g_maybe_loadself(exprasmlist);
       end;
       end;
 
 
 
 
@@ -1084,7 +1082,6 @@ implementation
               }
               }
               cg.a_param_const(exprasmlist,OS_ADDR,aword(-1),paramanager.getintparaloc(1));
               cg.a_param_const(exprasmlist,OS_ADDR,aword(-1),paramanager.getintparaloc(1));
               cg.a_call_name(exprasmlist,'FPC_CATCHES');
               cg.a_call_name(exprasmlist,'FPC_CATCHES');
-              cg.g_maybe_loadself(exprasmlist);
 
 
               { the destruction of the exception object must be also }
               { the destruction of the exception object must be also }
               { guarded by an exception frame                        }
               { guarded by an exception frame                        }
@@ -1267,8 +1264,6 @@ implementation
                  aktbreaklabel:=breakonlabel;
                  aktbreaklabel:=breakonlabel;
                end;
                end;
 
 
-              { esi is destroyed by FPC_CATCHES }
-              cg.g_maybe_loadself(exprasmlist);
               secondpass(right);
               secondpass(right);
            end;
            end;
          objectlibrary.getlabel(doobjectdestroy);
          objectlibrary.getlabel(doobjectdestroy);
@@ -1488,7 +1483,12 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.51  2003-02-19 22:00:14  daniel
+  Revision 1.52  2003-03-28 19:16:56  peter
+    * generic constructor working for i386
+    * remove fixed self register
+    * esi added as address register for i386
+
+  Revision 1.51  2003/02/19 22:00:14  daniel
     * Code generator converted to new register notation
     * Code generator converted to new register notation
     - Horribily outdated todo.txt removed
     - Horribily outdated todo.txt removed
 
 

+ 6 - 5
compiler/ncginl.pas

@@ -73,8 +73,6 @@ implementation
 
 
     procedure tcginlinenode.pass_2;
     procedure tcginlinenode.pass_2;
        var
        var
-         asmop : tasmop;
-         l : longint;
          oldpushedparasize : longint;
          oldpushedparasize : longint;
       begin
       begin
          { save & reset pushedparasize }
          { save & reset pushedparasize }
@@ -456,9 +454,7 @@ implementation
 *****************************************************************************}
 *****************************************************************************}
       procedure tcginlinenode.second_IncludeExclude;
       procedure tcginlinenode.second_IncludeExclude;
         var
         var
-         scratch_reg : boolean;
          hregister : tregister;
          hregister : tregister;
-         asmop : tasmop;
          L : longint;
          L : longint;
          pushedregs : TMaybesave;
          pushedregs : TMaybesave;
          cgop : topcg;
          cgop : topcg;
@@ -650,7 +646,12 @@ end.
 
 
 {
 {
   $Log$
   $Log$
-  Revision 1.21  2003-02-19 22:00:14  daniel
+  Revision 1.22  2003-03-28 19:16:56  peter
+    * generic constructor working for i386
+    * remove fixed self register
+    * esi added as address register for i386
+
+  Revision 1.21  2003/02/19 22:00:14  daniel
     * Code generator converted to new register notation
     * Code generator converted to new register notation
     - Horribily outdated todo.txt removed
     - Horribily outdated todo.txt removed
 
 

+ 9 - 6
compiler/ncgld.pas

@@ -66,7 +66,6 @@ implementation
 
 
     procedure tcgloadnode.pass_2;
     procedure tcgloadnode.pass_2;
       var
       var
-        intreg,
         r,hregister : tregister;
         r,hregister : tregister;
         supreg:Tsuperregister;
         supreg:Tsuperregister;
         symtabletype : tsymtabletype;
         symtabletype : tsymtabletype;
@@ -252,9 +251,7 @@ implementation
                                      location.reference.symbol:=objectlibrary.newasmsymbol(tvarsym(symtableentry).mangledname)
                                      location.reference.symbol:=objectlibrary.newasmsymbol(tvarsym(symtableentry).mangledname)
                                    else
                                    else
                                      begin
                                      begin
-                                        rg.getexplicitregisterint(exprasmlist,NR_SELF_POINTER_REG);
-                                        location.reference.base.enum:=R_INTREGISTER;
-                                        location.reference.base.number:=NR_SELF_POINTER_REG;
+                                        location.reference.base:=cg.g_load_self(exprasmlist);
                                         location.reference.offset:=tvarsym(symtableentry).address;
                                         location.reference.offset:=tvarsym(symtableentry).address;
                                      end;
                                      end;
                                 end;
                                 end;
@@ -427,6 +424,7 @@ implementation
         { Try to determine which side to calculate first,  }
         { Try to determine which side to calculate first,  }
         if (right.location.loc<>LOC_FLAGS) and
         if (right.location.loc<>LOC_FLAGS) and
            ((right.location.loc=LOC_JUMP) or
            ((right.location.loc=LOC_JUMP) or
+            (right.nodetype=calln) or
             (right.registers32>=left.registers32)) then
             (right.registers32>=left.registers32)) then
          begin
          begin
            secondpass(right);
            secondpass(right);
@@ -898,7 +896,7 @@ implementation
                      end
                      end
                     else
                     else
                       if vtype in [vtInt64,vtQword,vtExtended] then
                       if vtype in [vtInt64,vtQword,vtExtended] then
-                        push_value_para(hp.left,pocall_cdecl,0,4,paralocdummy)
+                        push_value_para(exprasmlist,hp.left,pocall_cdecl,0,4,paralocdummy)
                     else
                     else
                       begin
                       begin
                         cg.a_param_loc(exprasmlist,hp.left.location,paralocdummy);
                         cg.a_param_loc(exprasmlist,hp.left.location,paralocdummy);
@@ -972,7 +970,12 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.45  2003-02-19 22:00:14  daniel
+  Revision 1.46  2003-03-28 19:16:56  peter
+    * generic constructor working for i386
+    * remove fixed self register
+    * esi added as address register for i386
+
+  Revision 1.45  2003/02/19 22:00:14  daniel
     * Code generator converted to new register notation
     * Code generator converted to new register notation
     - Horribily outdated todo.txt removed
     - Horribily outdated todo.txt removed
 
 

+ 7 - 6
compiler/ncgmat.pas

@@ -249,13 +249,11 @@ implementation
     procedure tcgmoddivnode.pass_2;
     procedure tcgmoddivnode.pass_2;
       var
       var
          hreg1 : tregister;
          hreg1 : tregister;
-         hdenom,hnumerator : tregister;
-         shrdiv,popeax,popedx : boolean;
+         hdenom : tregister;
          power : longint;
          power : longint;
          hl : tasmlabel;
          hl : tasmlabel;
          pushedregs : tmaybesave;
          pushedregs : tmaybesave;
       begin
       begin
-         shrdiv := false;
          secondpass(left);
          secondpass(left);
          if codegenerror then
          if codegenerror then
           exit;
           exit;
@@ -288,7 +286,6 @@ implementation
                  (right.nodetype=ordconstn) and
                  (right.nodetype=ordconstn) and
                  ispowerof2(tordconstnode(right).value,power) then
                  ispowerof2(tordconstnode(right).value,power) then
                 Begin
                 Begin
-                  shrdiv := true;
                   { for signed numbers, the numerator must be adjusted before the
                   { for signed numbers, the numerator must be adjusted before the
                     shift instruction, but not wih unsigned numbers! Otherwise,
                     shift instruction, but not wih unsigned numbers! Otherwise,
                     "Cardinal($ffffffff) div 16" overflows! (JM) }
                     "Cardinal($ffffffff) div 16" overflows! (JM) }
@@ -348,7 +345,6 @@ implementation
       var
       var
          hcountreg : tregister;
          hcountreg : tregister;
          op : topcg;
          op : topcg;
-         l1,l2,l3 : tasmlabel;
          pushedregs : tmaybesave;
          pushedregs : tmaybesave;
          freescratch : boolean;
          freescratch : boolean;
       begin
       begin
@@ -454,7 +450,12 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.6  2003-02-19 22:00:14  daniel
+  Revision 1.7  2003-03-28 19:16:56  peter
+    * generic constructor working for i386
+    * remove fixed self register
+    * esi added as address register for i386
+
+  Revision 1.6  2003/02/19 22:00:14  daniel
     * Code generator converted to new register notation
     * Code generator converted to new register notation
     - Horribily outdated todo.txt removed
     - Horribily outdated todo.txt removed
 
 

+ 9 - 10
compiler/ncgmem.pas

@@ -347,18 +347,17 @@ implementation
 
 
     procedure tcgselfnode.pass_2;
     procedure tcgselfnode.pass_2;
       begin
       begin
-         rg.getexplicitregisterint(exprasmlist,NR_SELF_POINTER_REG);
          if (resulttype.def.deftype=classrefdef) or
          if (resulttype.def.deftype=classrefdef) or
             (is_class(resulttype.def) or
             (is_class(resulttype.def) or
              (po_staticmethod in aktprocdef.procoptions)) then
              (po_staticmethod in aktprocdef.procoptions)) then
           begin
           begin
-            location_reset(location,LOC_CREGISTER,OS_ADDR);
-            location.register.number:=NR_SELF_POINTER_REG;
+            location_reset(location,LOC_REGISTER,OS_ADDR);
+            location.register:=cg.g_load_self(exprasmlist);
           end
           end
          else
          else
            begin
            begin
              location_reset(location,LOC_CREFERENCE,OS_ADDR);
              location_reset(location,LOC_CREFERENCE,OS_ADDR);
-             location.reference.base.number:=NR_SELF_POINTER_REG;
+             location.reference.base:=cg.g_load_self(exprasmlist);
            end;
            end;
       end;
       end;
 
 
@@ -608,7 +607,6 @@ implementation
                rg.saveintregvars(exprasmlist,all_intregisters);
                rg.saveintregvars(exprasmlist,all_intregisters);
                cg.a_call_name(exprasmlist,'FPC_DYNARRAY_RANGECHECK');
                cg.a_call_name(exprasmlist,'FPC_DYNARRAY_RANGECHECK');
                rg.restoreusedintregisters(exprasmlist,pushed);
                rg.restoreusedintregisters(exprasmlist,pushed);
-               cg.g_maybe_loadself(exprasmlist);
             end
             end
          else
          else
            cg.g_rangecheck(exprasmlist,right,left.resulttype.def);
            cg.g_rangecheck(exprasmlist,right,left.resulttype.def);
@@ -648,7 +646,6 @@ implementation
                    cg.a_paramaddr_ref(exprasmlist,left.location.reference,paramanager.getintparaloc(1));
                    cg.a_paramaddr_ref(exprasmlist,left.location.reference,paramanager.getintparaloc(1));
                    rg.saveintregvars(exprasmlist,all_intregisters);
                    rg.saveintregvars(exprasmlist,all_intregisters);
                    cg.a_call_name(exprasmlist,'FPC_'+upper(tstringdef(left.resulttype.def).stringtypname)+'_UNIQUE');
                    cg.a_call_name(exprasmlist,'FPC_'+upper(tstringdef(left.resulttype.def).stringtypname)+'_UNIQUE');
-                   cg.g_maybe_loadself(exprasmlist);
                    rg.restoreusedintregisters(exprasmlist,pushed);
                    rg.restoreusedintregisters(exprasmlist,pushed);
                 end;
                 end;
 
 
@@ -675,7 +672,6 @@ implementation
                    cg.a_param_reg(exprasmlist,OS_ADDR,location.reference.base,paramanager.getintparaloc(1));
                    cg.a_param_reg(exprasmlist,OS_ADDR,location.reference.base,paramanager.getintparaloc(1));
                    rg.saveintregvars(exprasmlist,all_intregisters);
                    rg.saveintregvars(exprasmlist,all_intregisters);
                    cg.a_call_name(exprasmlist,'FPC_'+Upper(tstringdef(left.resulttype.def).stringtypname)+'_CHECKZERO');
                    cg.a_call_name(exprasmlist,'FPC_'+Upper(tstringdef(left.resulttype.def).stringtypname)+'_CHECKZERO');
-                   cg.g_maybe_loadself(exprasmlist);
                    rg.restoreusedintregisters(exprasmlist,pushed);
                    rg.restoreusedintregisters(exprasmlist,pushed);
                 end;
                 end;
 
 
@@ -756,7 +752,6 @@ implementation
                               rg.saveintregvars(exprasmlist,all_intregisters);
                               rg.saveintregvars(exprasmlist,all_intregisters);
                               cg.a_call_name(exprasmlist,'FPC_'+upper(tstringdef(left.resulttype.def).stringtypname)+'_RANGECHECK');
                               cg.a_call_name(exprasmlist,'FPC_'+upper(tstringdef(left.resulttype.def).stringtypname)+'_RANGECHECK');
                               rg.restoreusedintregisters(exprasmlist,pushed);
                               rg.restoreusedintregisters(exprasmlist,pushed);
-                              cg.g_maybe_loadself(exprasmlist);
                            end;
                            end;
 
 
                          st_shortstring:
                          st_shortstring:
@@ -888,7 +883,6 @@ implementation
                               rg.saveintregvars(exprasmlist,all_intregisters);
                               rg.saveintregvars(exprasmlist,all_intregisters);
                               cg.a_call_name(exprasmlist,'FPC_'+upper(tstringdef(left.resulttype.def).stringtypname)+'_RANGECHECK');
                               cg.a_call_name(exprasmlist,'FPC_'+upper(tstringdef(left.resulttype.def).stringtypname)+'_RANGECHECK');
                               rg.restoreusedintregisters(exprasmlist,pushed);
                               rg.restoreusedintregisters(exprasmlist,pushed);
-                              cg.g_maybe_loadself(exprasmlist);
                            end;
                            end;
                          st_shortstring:
                          st_shortstring:
                            begin
                            begin
@@ -925,7 +919,12 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.43  2003-03-12 22:43:38  jonas
+  Revision 1.44  2003-03-28 19:16:56  peter
+    * generic constructor working for i386
+    * remove fixed self register
+    * esi added as address register for i386
+
+  Revision 1.43  2003/03/12 22:43:38  jonas
     * more powerpc and generic fixes related to the new register allocator
     * more powerpc and generic fixes related to the new register allocator
 
 
   Revision 1.42  2003/02/19 22:00:14  daniel
   Revision 1.42  2003/02/19 22:00:14  daniel

+ 77 - 103
compiler/ncgutil.pas

@@ -56,7 +56,7 @@ interface
     procedure maybe_restore(list:taasmoutput;var l:tlocation;const s:tmaybesave);
     procedure maybe_restore(list:taasmoutput;var l:tlocation;const s:tmaybesave);
     function  maybe_pushfpu(list:taasmoutput;needed : byte;var l:tlocation) : boolean;
     function  maybe_pushfpu(list:taasmoutput;needed : byte;var l:tlocation) : boolean;
 
 
-    procedure push_value_para(p:tnode;calloption:tproccalloption;
+    procedure push_value_para(list:taasmoutput;p:tnode;calloption:tproccalloption;
                               para_offset:longint;alignment : longint;
                               para_offset:longint;alignment : longint;
                               const locpara : tparalocation);
                               const locpara : tparalocation);
 
 
@@ -109,6 +109,13 @@ implementation
     tgobj,cgobj,cgcpu;
     tgobj,cgobj,cgcpu;
 
 
 
 
+  const
+    { Please leave this here, this module should NOT use
+      exprasmlist, the lists are always passed as arguments.
+      Declaring it as string here results in an error when compiling (PFV) }
+    exprasmlist = 'error';
+
+
 {*****************************************************************************
 {*****************************************************************************
                                   Misc Helpers
                                   Misc Helpers
 *****************************************************************************}
 *****************************************************************************}
@@ -570,7 +577,7 @@ implementation
             begin
             begin
               tg.GetTemp(list,TCGSize2Size[l.size],tt_normal,r);
               tg.GetTemp(list,TCGSize2Size[l.size],tt_normal,r);
               cg.a_loadfpu_reg_ref(list,l.size,l.register,r);
               cg.a_loadfpu_reg_ref(list,l.size,l.register,r);
-              location_release(exprasmlist,l);
+              location_release(list,l);
               location_reset(l,LOC_REFERENCE,l.size);
               location_reset(l,LOC_REFERENCE,l.size);
               l.reference:=r;
               l.reference:=r;
             end;
             end;
@@ -583,7 +590,7 @@ implementation
                cg64.a_load64_loc_ref(list,l,r)
                cg64.a_load64_loc_ref(list,l,r)
               else
               else
                cg.a_load_loc_ref(list,l,r);
                cg.a_load_loc_ref(list,l,r);
-              location_release(exprasmlist,l);
+              location_release(list,l);
               location_reset(l,LOC_REFERENCE,l.size);
               location_reset(l,LOC_REFERENCE,l.size);
               l.reference:=r;
               l.reference:=r;
 
 
@@ -616,16 +623,16 @@ implementation
 {$ifndef cpu64bit}
 {$ifndef cpu64bit}
                  if l.size in [OS_64,OS_S64] then
                  if l.size in [OS_64,OS_S64] then
                   begin
                   begin
-                    tg.GetTemp(exprasmlist,8,tt_normal,s.ref);
-                    cg64.a_load64_reg_ref(exprasmlist,joinreg64(l.registerlow,l.registerhigh),s.ref);
+                    tg.GetTemp(list,8,tt_normal,s.ref);
+                    cg64.a_load64_reg_ref(list,joinreg64(l.registerlow,l.registerhigh),s.ref);
                   end
                   end
                  else
                  else
 {$endif cpu64bit}
 {$endif cpu64bit}
                   begin
                   begin
-                    tg.GetTemp(exprasmlist,TCGSize2Size[l.size],tt_normal,s.ref);
-                    cg.a_load_reg_ref(exprasmlist,l.size,l.register,s.ref);
+                    tg.GetTemp(list,TCGSize2Size[l.size],tt_normal,s.ref);
+                    cg.a_load_reg_ref(list,l.size,l.register,s.ref);
                   end;
                   end;
-                 location_release(exprasmlist,l);
+                 location_release(list,l);
                  s.saved:=true;
                  s.saved:=true;
                end;
                end;
              LOC_REFERENCE,
              LOC_REFERENCE,
@@ -652,10 +659,10 @@ implementation
                        reference_reset_base(l.reference,l.reference.base,0);
                        reference_reset_base(l.reference,l.reference.base,0);
                      end;
                      end;
                     { save base register }
                     { save base register }
-                    tg.GetTemp(exprasmlist,TCGSize2Size[OS_ADDR],tt_normal,s.ref);
-                    cg.a_load_reg_ref(exprasmlist,OS_ADDR,l.reference.base,s.ref);
+                    tg.GetTemp(list,TCGSize2Size[OS_ADDR],tt_normal,s.ref);
+                    cg.a_load_reg_ref(list,OS_ADDR,l.reference.base,s.ref);
                     { release }
                     { release }
-                    location_release(exprasmlist,l);
+                    location_release(list,l);
                     s.saved:=true;
                     s.saved:=true;
                   end;
                   end;
                end;
                end;
@@ -679,26 +686,26 @@ implementation
 {$ifndef cpu64bit}
 {$ifndef cpu64bit}
               if l.size in [OS_64,OS_S64] then
               if l.size in [OS_64,OS_S64] then
                begin
                begin
-                 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));
+                 l.registerlow:=rg.getregisterint(list,OS_INT);
+                 l.registerhigh:=rg.getregisterint(list,OS_INT);
+                 cg64.a_load64_ref_reg(list,s.ref,joinreg64(l.registerlow,l.registerhigh));
                end
                end
               else
               else
 {$endif cpu64bit}
 {$endif cpu64bit}
                begin
                begin
-                 l.register:=rg.getregisterint(exprasmlist,OS_INT);
-                 cg.a_load_ref_reg(exprasmlist,OS_INT,s.ref,l.register);
+                 l.register:=rg.getregisterint(list,OS_INT);
+                 cg.a_load_ref_reg(list,OS_INT,s.ref,l.register);
                end;
                end;
             end;
             end;
           LOC_CREFERENCE,
           LOC_CREFERENCE,
           LOC_REFERENCE :
           LOC_REFERENCE :
             begin
             begin
               reference_reset(l.reference);
               reference_reset(l.reference);
-              l.reference.base:=rg.getaddressregister(exprasmlist);
-              cg.a_load_ref_reg(exprasmlist,OS_ADDR,s.ref,l.reference.base);
+              l.reference.base:=rg.getaddressregister(list);
+              cg.a_load_ref_reg(list,OS_ADDR,s.ref,l.reference.base);
             end;
             end;
         end;
         end;
-        tg.ungetiftemp(exprasmlist,s.ref);
+        tg.ungetiftemp(list,s.ref);
       end;
       end;
 
 
 
 
@@ -719,7 +726,7 @@ implementation
                                 Push Value Para
                                 Push Value Para
 *****************************************************************************}
 *****************************************************************************}
 
 
-    procedure push_value_para(p:tnode;calloption:tproccalloption;
+    procedure push_value_para(list:taasmoutput;p:tnode;calloption:tproccalloption;
                               para_offset:longint;alignment : longint;
                               para_offset:longint;alignment : longint;
                               const locpara : tparalocation);
                               const locpara : tparalocation);
       var
       var
@@ -737,7 +744,7 @@ implementation
 
 
         { Move flags and jump in register to make it less complex }
         { Move flags and jump in register to make it less complex }
         if p.location.loc in [LOC_FLAGS,LOC_JUMP] then
         if p.location.loc in [LOC_FLAGS,LOC_JUMP] then
-         location_force_reg(exprasmlist,p.location,def_cgsize(p.resulttype.def),false);
+         location_force_reg(list,p.location,def_cgsize(p.resulttype.def),false);
 
 
         { Handle Floating point types differently }
         { Handle Floating point types differently }
         if p.resulttype.def.deftype=floatdef then
         if p.resulttype.def.deftype=floatdef then
@@ -751,11 +758,11 @@ implementation
                   inc(pushedparasize,size);
                   inc(pushedparasize,size);
 
 
                   if calloption<>pocall_inline then
                   if calloption<>pocall_inline then
-                   cg.g_stackpointer_alloc(exprasmlist,size);
+                   cg.g_stackpointer_alloc(list,size);
 {$ifdef GDB}
 {$ifdef GDB}
                   if (cs_debuginfo in aktmoduleswitches) and
                   if (cs_debuginfo in aktmoduleswitches) and
-                     (exprasmList.first=exprasmList.last) then
-                    exprasmList.concat(Tai_force_line.Create);
+                     (list.first=list.last) then
+                    list.concat(Tai_force_line.Create);
 {$endif GDB}
 {$endif GDB}
 
 
                   { this is the easiest case for inlined !! }
                   { this is the easiest case for inlined !! }
@@ -765,10 +772,10 @@ implementation
                   else
                   else
                    reference_reset_base(href,r,0);
                    reference_reset_base(href,r,0);
 
 
-                  cg.a_loadfpu_reg_ref(exprasmlist,
+                  cg.a_loadfpu_reg_ref(list,
                     def_cgsize(p.resulttype.def),p.location.register,href);
                     def_cgsize(p.resulttype.def),p.location.register,href);
 {$else i386}
 {$else i386}
-                  cg.a_paramfpu_reg(exprasmlist,def_cgsize(p.resulttype.def),p.location.register,locpara);
+                  cg.a_paramfpu_reg(list,def_cgsize(p.resulttype.def),p.location.register,locpara);
 {$endif i386}
 {$endif i386}
 
 
                end;
                end;
@@ -797,16 +804,16 @@ implementation
                     if calloption=pocall_inline then
                     if calloption=pocall_inline then
                      begin
                      begin
                        reference_reset_base(href,procinfo.framepointer,para_offset-pushedparasize);
                        reference_reset_base(href,procinfo.framepointer,para_offset-pushedparasize);
-                       cg.a_load_ref_ref(exprasmlist,cgsize,tempreference,href);
+                       cg.a_load_ref_ref(list,cgsize,tempreference,href);
                      end
                      end
                     else
                     else
-                     cg.a_param_ref(exprasmlist,cgsize,tempreference,locpara);
+                     cg.a_param_ref(list,cgsize,tempreference,locpara);
                   end;
                   end;
                end;
                end;
              else
              else
                internalerror(200204243);
                internalerror(200204243);
            end;
            end;
-           location_release(exprasmlist,p.location);
+           location_release(list,p.location);
          end
          end
         else
         else
          begin
          begin
@@ -819,13 +826,13 @@ implementation
               { push on stack }
               { push on stack }
               size:=align(p.resulttype.def.size,alignment);
               size:=align(p.resulttype.def.size,alignment);
               inc(pushedparasize,size);
               inc(pushedparasize,size);
-              cg.g_stackpointer_alloc(exprasmlist,size);
+              cg.g_stackpointer_alloc(list,size);
               r.enum:=R_INTREGISTER;
               r.enum:=R_INTREGISTER;
               r.number:=NR_STACK_POINTER_REG;
               r.number:=NR_STACK_POINTER_REG;
               reference_reset_base(href,r,0);
               reference_reset_base(href,r,0);
-              cg.g_concatcopy(exprasmlist,p.location.reference,href,size,false,false);
+              cg.g_concatcopy(list,p.location.reference,href,size,false,false);
 {$else i386}
 {$else i386}
-              cg.a_param_copy_ref(exprasmlist,p.resulttype.def.size,p.location.reference,locpara);
+              cg.a_param_copy_ref(list,p.resulttype.def.size,p.location.reference,locpara);
 {$endif i386}
 {$endif i386}
             end
             end
            else
            else
@@ -847,13 +854,13 @@ implementation
                           if p.location.loc in [LOC_REFERENCE,LOC_CREFERENCE] then
                           if p.location.loc in [LOC_REFERENCE,LOC_CREFERENCE] then
                             begin
                             begin
                               size:=align(p.resulttype.def.size,alignment);
                               size:=align(p.resulttype.def.size,alignment);
-                              cg.g_concatcopy(exprasmlist,p.location.reference,href,size,false,false)
+                              cg.g_concatcopy(list,p.location.reference,href,size,false,false)
                             end
                             end
                           else
                           else
-                            cg64.a_load64_loc_ref(exprasmlist,p.location,href);
+                            cg64.a_load64_loc_ref(list,p.location,href);
                         end
                         end
                        else
                        else
-                        cg64.a_param64_loc(exprasmlist,p.location,locpara);
+                        cg64.a_param64_loc(list,p.location,locpara);
                      end
                      end
                     else
                     else
                      begin
                      begin
@@ -886,18 +893,18 @@ implementation
                           if p.location.loc in [LOC_REFERENCE,LOC_CREFERENCE] then
                           if p.location.loc in [LOC_REFERENCE,LOC_CREFERENCE] then
                             begin
                             begin
                               size:=align(p.resulttype.def.size,alignment);
                               size:=align(p.resulttype.def.size,alignment);
-                              cg.g_concatcopy(exprasmlist,p.location.reference,href,size,false,false)
+                              cg.g_concatcopy(list,p.location.reference,href,size,false,false)
                             end
                             end
                           else
                           else
-                            cg.a_load_loc_ref(exprasmlist,p.location,href);
+                            cg.a_load_loc_ref(list,p.location,href);
                         end
                         end
                        else
                        else
-                        cg.a_param_loc(exprasmlist,p.location,locpara);
+                        cg.a_param_loc(list,p.location,locpara);
                        { restore old register }
                        { restore old register }
                        if p.location.loc in [LOC_REGISTER,LOC_CREGISTER] then
                        if p.location.loc in [LOC_REGISTER,LOC_CREGISTER] then
                          p.location.register:=hreg;
                          p.location.register:=hreg;
                      end;
                      end;
-                    location_release(exprasmlist,p.location);
+                    location_release(list,p.location);
                   end;
                   end;
 {$ifdef SUPPORT_MMX}
 {$ifdef SUPPORT_MMX}
                 LOC_MMXREGISTER,
                 LOC_MMXREGISTER,
@@ -907,10 +914,10 @@ implementation
                      if calloption=pocall_inline then
                      if calloption=pocall_inline then
                        begin
                        begin
                           reference_reset_base(href,procinfo.framepointer,para_offset-pushedparasize);
                           reference_reset_base(href,procinfo.framepointer,para_offset-pushedparasize);
-                          cg.a_loadmm_reg_ref(exprasmlist,p.location.register,href);
+                          cg.a_loadmm_reg_ref(list,p.location.register,href);
                        end
                        end
                      else
                      else
-                      cg.a_parammm_reg(exprasmlist,p.location.register);
+                      cg.a_parammm_reg(list,p.location.register);
                   end;
                   end;
 {$endif SUPPORT_MMX}
 {$endif SUPPORT_MMX}
                 else
                 else
@@ -1302,8 +1309,6 @@ function returns in a register and the caller receives it in an other one}
         stackalloclist : taasmoutput;
         stackalloclist : taasmoutput;
         hp : tparaitem;
         hp : tparaitem;
         paraloc : tparalocation;
         paraloc : tparalocation;
-        r:Tregister;
-
       begin
       begin
         if not inlined then
         if not inlined then
            stackalloclist:=taasmoutput.Create;
            stackalloclist:=taasmoutput.Create;
@@ -1313,7 +1318,6 @@ function returns in a register and the caller receives it in an other one}
           code, since temp. allocation might occur before - carl
           code, since temp. allocation might occur before - carl
         }
         }
 
 
-
         { for the save all registers we can simply use a pusha,popa which
         { for the save all registers we can simply use a pusha,popa which
           push edi,esi,ebp,esp(ignored),ebx,edx,ecx,eax }
           push edi,esi,ebp,esp(ignored),ebx,edx,ecx,eax }
         if (po_saveregisters in aktprocdef.procoptions) then
         if (po_saveregisters in aktprocdef.procoptions) then
@@ -1327,9 +1331,9 @@ function returns in a register and the caller receives it in an other one}
           therefore if the context must be saved, do it before
           therefore if the context must be saved, do it before
           the actual call to the profile code
           the actual call to the profile code
         }
         }
-        if (cs_profile in aktmoduleswitches)
-         and not(po_assembler in aktprocdef.procoptions)
-         and not(inlined) then
+        if (cs_profile in aktmoduleswitches) and
+           not(po_assembler in aktprocdef.procoptions) and
+           not(inlined) then
           begin
           begin
             { non-win32 can call mcout even in main }
             { non-win32 can call mcout even in main }
             if not (target_info.system in [system_i386_win32,system_i386_wdosx])  then
             if not (target_info.system in [system_i386_win32,system_i386_wdosx])  then
@@ -1340,30 +1344,11 @@ function returns in a register and the caller receives it in an other one}
               cg.g_profilecode(list);
               cg.g_profilecode(list);
           end;
           end;
 
 
-
         { a constructor needs a help procedure }
         { a constructor needs a help procedure }
         if (aktprocdef.proctypeoption=potype_constructor) then
         if (aktprocdef.proctypeoption=potype_constructor) then
-          cg.g_call_constructor_helper(list);
-
-        { don't load ESI, does the caller }
-        { we must do it for local function }
-        { that can be called from a foreach_static }
-        { of another object than self !! PM }
-        if assigned(procinfo._class) and  { !!!!! shouldn't we load ESI always? }
-           (lexlevel>normal_function_level) then
-         cg.g_maybe_loadself(list);
-
-        { When message method contains self as a parameter,
-          we must load it into ESI }
-        If (po_containsself in aktprocdef.procoptions) then
-          begin
-             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);
-          end;
-
+         begin
+           cg.g_call_constructor_helper(list);
+         end;
 
 
         if not is_void(aktprocdef.rettype.def) then
         if not is_void(aktprocdef.rettype.def) then
           begin
           begin
@@ -1398,7 +1383,7 @@ function returns in a register and the caller receives it in an other one}
                end;
                end;
           end;
           end;
 
 
-        { initialisize local data like ansistrings }
+        { initialize local data like ansistrings }
         case aktprocdef.proctypeoption of
         case aktprocdef.proctypeoption of
            potype_unitinit:
            potype_unitinit:
              begin
              begin
@@ -1502,8 +1487,6 @@ function returns in a register and the caller receives it in an other one}
               new_exception(list,procinfo.exception_jmp_ref,
               new_exception(list,procinfo.exception_jmp_ref,
                   procinfo.exception_env_ref,
                   procinfo.exception_env_ref,
                   procinfo.exception_result_ref,1,aktexitlabel);
                   procinfo.exception_result_ref,1,aktexitlabel);
-              { probably we've to reload self here }
-              cg.g_maybe_loadself(list);
             end;
             end;
 
 
 {$ifdef GDB}
 {$ifdef GDB}
@@ -1615,13 +1598,12 @@ function returns in a register and the caller receives it in an other one}
 {$endif GDB}
 {$endif GDB}
         okexitlabel,
         okexitlabel,
         noreraiselabel,nodestroycall : tasmlabel;
         noreraiselabel,nodestroycall : tasmlabel;
-        tmpreg : tregister;
         href : treference;
         href : treference;
         usesacc,
         usesacc,
         usesacchi,
         usesacchi,
         usesself,usesfpu : boolean;
         usesself,usesfpu : boolean;
         pd : tprocdef;
         pd : tprocdef;
-        r,r2:Tregister;
+        r  : Tregister;
       begin
       begin
         if aktexit2label.is_used and
         if aktexit2label.is_used and
            ((procinfo.flags and (pi_needs_implicit_finally or pi_uses_exceptions)) <> 0) then
            ((procinfo.flags and (pi_needs_implicit_finally or pi_uses_exceptions)) <> 0) then
@@ -1694,8 +1676,7 @@ function returns in a register and the caller receives it in an other one}
                             objectlibrary.getlabel(nodestroycall);
                             objectlibrary.getlabel(nodestroycall);
                             reference_reset_base(href,procinfo.framepointer,procinfo.selfpointer_offset);
                             reference_reset_base(href,procinfo.framepointer,procinfo.selfpointer_offset);
                             cg.a_cmp_const_ref_label(list,OS_ADDR,OC_EQ,0,href,nodestroycall);
                             cg.a_cmp_const_ref_label(list,OS_ADDR,OC_EQ,0,href,nodestroycall);
-                            r.enum:=R_INTREGISTER;
-                            r.number:=NR_SELF_POINTER_REG;
+                            r:=cg.g_load_self(list);
                             if is_class(procinfo._class) then
                             if is_class(procinfo._class) then
                              begin
                              begin
                                cg.a_param_const(list,OS_INT,1,paramanager.getintparaloc(2));
                                cg.a_param_const(list,OS_INT,1,paramanager.getintparaloc(2));
@@ -1712,14 +1693,13 @@ function returns in a register and the caller receives it in an other one}
                             if (po_virtualmethod in pd.procoptions) then
                             if (po_virtualmethod in pd.procoptions) then
                              begin
                              begin
                                reference_reset_base(href,r,0);
                                reference_reset_base(href,r,0);
-                               tmpreg:=cg.get_scratch_reg_address(list);
-                               cg.a_load_ref_reg(list,OS_ADDR,href,tmpreg);
-                               reference_reset_base(href,tmpreg,procinfo._class.vmtmethodoffset(pd.extnumber));
-                               cg.free_scratch_reg(list,tmpreg);
+                               cg.a_load_ref_reg(list,OS_ADDR,href,r);
+                               reference_reset_base(href,r,procinfo._class.vmtmethodoffset(pd.extnumber));
                                cg.a_call_ref(list,href);
                                cg.a_call_ref(list,href);
                              end
                              end
                             else
                             else
                              cg.a_call_name(list,pd.mangledname);
                              cg.a_call_name(list,pd.mangledname);
+                            rg.ungetregisterint(list,r);
                             { not necessary because the result is never assigned in the
                             { not necessary because the result is never assigned in the
                               case of an exception (FK) }
                               case of an exception (FK) }
                             cg.a_label(list,nodestroycall);
                             cg.a_label(list,nodestroycall);
@@ -1770,30 +1750,18 @@ function returns in a register and the caller receives it in an other one}
                 { eax must be set to zero if the allocation failed !!! }
                 { eax must be set to zero if the allocation failed !!! }
                 objectlibrary.getlabel(okexitlabel);
                 objectlibrary.getlabel(okexitlabel);
                 cg.a_jmp_always(list,okexitlabel);
                 cg.a_jmp_always(list,okexitlabel);
+                { fail }
                 cg.a_label(list,faillabel);
                 cg.a_label(list,faillabel);
                 cg.g_call_fail_helper(list);
                 cg.g_call_fail_helper(list);
+                { return the self pointer }
                 cg.a_label(list,okexitlabel);
                 cg.a_label(list,okexitlabel);
-
-                { for classes this is done after the call to }
-                { AfterConstruction                          }
-                if is_object(procinfo._class) then
-                  begin
-                    r.enum:=R_INTREGISTER;
-                    r.number:=NR_SELF_POINTER_REG;
-                    r2.enum:=R_INTREGISTER;
-                    r2.number:=NR_ACCUMULATOR;
-                    cg.a_reg_alloc(list,r2);
-                    cg.a_load_reg_reg(list,OS_ADDR,OS_ADDR,r,r2);
-                    usesacc:=true;
-                  end;
-{$ifdef i386}
                 r.enum:=R_INTREGISTER;
                 r.enum:=R_INTREGISTER;
-                r.number:=NR_SELF_POINTER_REG;
-                list.concat(taicpu.op_reg_reg(A_TEST,S_L,r,r));
-{$else}
-{$warning constructor returns in flags for i386}
-{$endif i386}
-                usesself:=true;
+                r.number:=NR_ACCUMULATOR;
+                cg.a_reg_alloc(list,r);
+                reference_reset_base(href, procinfo.framepointer,procinfo.selfpointer_offset);
+                cg.a_load_ref_reg(list,OS_ADDR,href,r);
+                rg.ungetregisterint(list,r);
+                usesacc:=true;
               end;
               end;
           end;
           end;
 
 
@@ -1891,9 +1859,10 @@ function returns in a register and the caller receives it in an other one}
                     st:='*'
                     st:='*'
                   else
                   else
                     st:='';
                     st:='';
-                  list.concat(Tai_stabs.Create(strpnew(
+{$warning GDB self}
+                  {list.concat(Tai_stabs.Create(strpnew(
                    '"$t:r'+st+procinfo._class.numberstring+'",'+
                    '"$t:r'+st+procinfo._class.numberstring+'",'+
-                   tostr(N_RSYM)+',0,0,'+tostr(stab_regindex[SELF_POINTER_REG]))));
+                   tostr(N_RSYM)+',0,0,'+tostr(stab_regindex[SELF_POINTER_REG]))));}
                 end;
                 end;
 
 
             { define calling EBP as pseudo local var PM }
             { define calling EBP as pseudo local var PM }
@@ -1996,7 +1965,12 @@ function returns in a register and the caller receives it in an other one}
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.80  2003-03-17 15:52:20  peter
+  Revision 1.81  2003-03-28 19:16:56  peter
+    * generic constructor working for i386
+    * remove fixed self register
+    * esi added as address register for i386
+
+  Revision 1.80  2003/03/17 15:52:20  peter
     * fix range error
     * fix range error
 
 
   Revision 1.79  2003/03/11 21:46:24  jonas
   Revision 1.79  2003/03/11 21:46:24  jonas

+ 7 - 2
compiler/nld.pas

@@ -446,7 +446,7 @@ implementation
                       { call by value open arrays are also indirect addressed }
                       { call by value open arrays are also indirect addressed }
                       is_open_array(tvarsym(symtableentry).vartype.def) then
                       is_open_array(tvarsym(symtableentry).vartype.def) then
                      registers32:=1;
                      registers32:=1;
-                   if symtable.symtabletype=withsymtable then
+                   if symtable.symtabletype in [withsymtable,objectsymtable] then
                      inc(registers32);
                      inc(registers32);
 
 
                    if ([vo_is_thread_var,vo_is_dll_var]*tvarsym(symtableentry).varoptions)<>[] then
                    if ([vo_is_thread_var,vo_is_dll_var]*tvarsym(symtableentry).varoptions)<>[] then
@@ -1257,7 +1257,12 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.81  2003-03-11 21:46:24  jonas
+  Revision 1.82  2003-03-28 19:16:56  peter
+    * generic constructor working for i386
+    * remove fixed self register
+    * esi added as address register for i386
+
+  Revision 1.81  2003/03/11 21:46:24  jonas
     * lots of new regallocator fixes, both in generic and ppc-specific code
     * lots of new regallocator fixes, both in generic and ppc-specific code
       (ppc compiler still can't compile the linux system unit though)
       (ppc compiler still can't compile the linux system unit though)
 
 

+ 6 - 4
compiler/node.pas

@@ -265,9 +265,6 @@ interface
          nf_isproperty,
          nf_isproperty,
          nf_varstateset,
          nf_varstateset,
 
 
-         { tasmnode }
-         nf_object_preserved,   { 30th }
-
          { taddnode }
          { taddnode }
          nf_use_strconcat
          nf_use_strconcat
        );
        );
@@ -976,7 +973,12 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.50  2003-03-17 16:54:41  peter
+  Revision 1.51  2003-03-28 19:16:56  peter
+    * generic constructor working for i386
+    * remove fixed self register
+    * esi added as address register for i386
+
+  Revision 1.50  2003/03/17 16:54:41  peter
     * support DefaultHandler and anonymous inheritance fixed
     * support DefaultHandler and anonymous inheritance fixed
       for message methods
       for message methods
 
 

+ 7 - 1
compiler/options.pas

@@ -1643,6 +1643,7 @@ begin
   def_symbol('VALUEFREEMEM');
   def_symbol('VALUEFREEMEM');
   def_symbol('HASCURRENCY');
   def_symbol('HASCURRENCY');
   def_symbol('HASTHREADVAR');
   def_symbol('HASTHREADVAR');
+  def_symbol('HAS_GENERICCONSTRUCTOR');
 
 
 { using a case is pretty useless here (FK) }
 { using a case is pretty useless here (FK) }
 { some stuff for TP compatibility }
 { some stuff for TP compatibility }
@@ -1898,7 +1899,12 @@ finalization
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.93  2003-03-23 23:20:38  hajny
+  Revision 1.94  2003-03-28 19:16:56  peter
+    * generic constructor working for i386
+    * remove fixed self register
+    * esi added as address register for i386
+
+  Revision 1.93  2003/03/23 23:20:38  hajny
     + emx target added
     + emx target added
 
 
   Revision 1.92  2003/03/08 08:59:07  daniel
   Revision 1.92  2003/03/08 08:59:07  daniel

+ 45 - 20
compiler/pdecsub.pas

@@ -659,26 +659,46 @@ implementation
             aktprocdef.parast.symtablelevel:=lexlevel;
             aktprocdef.parast.symtablelevel:=lexlevel;
           end;
           end;
 
 
-        if assigned (procinfo._Class)  and
-           is_object(procinfo._Class) and
-           (aktprocdef.proctypeoption in [potype_constructor,potype_destructor]) then
-          inc(paramoffset,pointer_size);
-
-        { self pointer offset, must be done after parsing the parameters }
-        { self isn't pushed in nested procedure of methods }
-        if assigned(procinfo._class) and (lexlevel=normal_function_level) then
-          begin
-            procinfo.selfpointer_offset:=paramoffset;
-            if assigned(aktprocdef) and
-               not(po_containsself in aktprocdef.procoptions) then
-              inc(paramoffset,pointer_size);
-          end;
+        { Get self, vmt offsets }
+        if assigned (procinfo._Class) then
+         begin
+           { self pointer offset, must be done after parsing the parameters }
+           { self isn't pushed in nested procedure of methods }
+           if (lexlevel=normal_function_level) then
+            begin
+              if assigned(aktprocdef) and
+                 not(po_containsself in aktprocdef.procoptions) then
+                begin
+                  procinfo.selfpointer_offset:=paramoffset;
+                  inc(paramoffset,POINTER_SIZE);
+                end;
+            end;
 
 
-        { con/-destructor flag ? }
-        if assigned (procinfo._Class) and
-           is_class(procinfo._class) and
-           (aktprocdef.proctypeoption in [potype_destructor,potype_constructor]) then
-          inc(paramoffset,pointer_size);
+           { Special parameters for de-/constructors }
+           case aktprocdef.proctypeoption of
+             potype_constructor :
+               begin
+                 procinfo.vmtpointer_offset:=paramoffset;
+                 inc(paramoffset,POINTER_SIZE);
+               end;
+             potype_destructor :
+               begin
+                 if is_object(procinfo._class) then
+                  begin
+                    procinfo.vmtpointer_offset:=paramoffset;
+                    inc(paramoffset,POINTER_SIZE);
+                  end
+                 else
+                  if is_class(procinfo._class) then
+                   begin
+                     procinfo.inheritedflag_offset:=paramoffset;
+                     inc(paramoffset,POINTER_SIZE);
+                   end
+                 else
+                  internalerror(200303261);
+               end;
+           end;
+         end;
 
 
         procinfo.para_offset:=paramoffset;
         procinfo.para_offset:=paramoffset;
 
 
@@ -2123,7 +2143,12 @@ const
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.109  2003-03-23 23:21:42  hajny
+  Revision 1.110  2003-03-28 19:16:56  peter
+    * generic constructor working for i386
+    * remove fixed self register
+    * esi added as address register for i386
+
+  Revision 1.109  2003/03/23 23:21:42  hajny
     + emx target added
     + emx target added
 
 
   Revision 1.108  2003/03/19 17:34:04  peter
   Revision 1.108  2003/03/19 17:34:04  peter

+ 6 - 4
compiler/pstatmnt.pas

@@ -758,14 +758,11 @@ implementation
               begin
               begin
                 repeat
                 repeat
                   { it's possible to specify the modified registers }
                   { it's possible to specify the modified registers }
-                  include(asmstat.flags,nf_object_preserved);
                   hs:=upper(pattern);
                   hs:=upper(pattern);
                   found:=false;
                   found:=false;
                   for r.enum:=firstreg to lastreg do
                   for r.enum:=firstreg to lastreg do
                    if hs=upper(std_reg2str[r.enum]) then
                    if hs=upper(std_reg2str[r.enum]) then
                     begin
                     begin
-                      if r.enum = SELF_POINTER_REG then
-                        exclude(asmstat.flags,nf_object_preserved);
                       include(rg.usedinproc,r.enum);
                       include(rg.usedinproc,r.enum);
                       include(rg.usedbyproc,r.enum);
                       include(rg.usedbyproc,r.enum);
                       found:=true;
                       found:=true;
@@ -1126,7 +1123,12 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.87  2003-03-17 18:55:30  peter
+  Revision 1.88  2003-03-28 19:16:57  peter
+    * generic constructor working for i386
+    * remove fixed self register
+    * esi added as address register for i386
+
+  Revision 1.87  2003/03/17 18:55:30  peter
     * allow more tokens instead of only semicolon after inherited
     * allow more tokens instead of only semicolon after inherited
 
 
   Revision 1.86  2003/02/19 22:00:14  daniel
   Revision 1.86  2003/02/19 22:00:14  daniel

+ 9 - 19
compiler/rautils.pas

@@ -811,24 +811,9 @@ Begin
         case tvarsym(sym).owner.symtabletype of
         case tvarsym(sym).owner.symtabletype of
           objectsymtable :
           objectsymtable :
             begin
             begin
-              { this is not allowed, because we don't know if the self
-                register is still free, and loading it first is also
-                not possible, because this could break code }
-              { Be TP/Delphi compatible in Delphi or TP modes }
-              if (m_tp7 in aktmodeswitches) or
-                 (m_delphi in aktmodeswitches) then
-                begin
-                  opr.typ:=OPR_CONSTANT;
-                  opr.val:=tvarsym(sym).address;
-                end
-              { I do not agree here people using method vars should ensure
-                that %esi is valid there }
-              else
-                begin
-                  opr.ref.base.enum:=R_INTREGISTER;
-                  opr.ref.base.number:=NR_SELF_POINTER_REG;
-                  opr.ref.offset:=tvarsym(sym).address;
-                end;
+              { We return the address of the field, just like Delphi/TP }
+              opr.typ:=OPR_CONSTANT;
+              opr.val:=tvarsym(sym).address;
               hasvar:=true;
               hasvar:=true;
               SetupVar:=true;
               SetupVar:=true;
               Exit;
               Exit;
@@ -1597,7 +1582,12 @@ end;
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.53  2003-02-19 22:00:14  daniel
+  Revision 1.54  2003-03-28 19:16:57  peter
+    * generic constructor working for i386
+    * remove fixed self register
+    * esi added as address register for i386
+
+  Revision 1.53  2003/02/19 22:00:14  daniel
     * Code generator converted to new register notation
     * Code generator converted to new register notation
     - Horribily outdated todo.txt removed
     - Horribily outdated todo.txt removed
 
 

+ 7 - 2
compiler/regvars.pas

@@ -274,7 +274,7 @@ implementation
 
 
 
 
     procedure store_regvar_int(asml:Taasmoutput;reg:Tsuperregister);
     procedure store_regvar_int(asml:Taasmoutput;reg:Tsuperregister);
-    
+
     begin
     begin
       internalerror(200301104);
       internalerror(200301104);
     end;
     end;
@@ -497,7 +497,12 @@ end.
 
 
 {
 {
   $Log$
   $Log$
-  Revision 1.45  2003-02-19 22:00:14  daniel
+  Revision 1.46  2003-03-28 19:16:57  peter
+    * generic constructor working for i386
+    * remove fixed self register
+    * esi added as address register for i386
+
+  Revision 1.45  2003/02/19 22:00:14  daniel
     * Code generator converted to new register notation
     * Code generator converted to new register notation
     - Horribily outdated todo.txt removed
     - Horribily outdated todo.txt removed
 
 

+ 10 - 12
compiler/rgobj.pas

@@ -606,22 +606,13 @@ unit rgobj;
           r2.enum:=R_INTREGISTER;
           r2.enum:=R_INTREGISTER;
           r2.number:=r;
           r2.number:=r;
           list.concat(tai_regalloc.alloc(r2));
           list.concat(tai_regalloc.alloc(r2));
-          getexplicitregisterint:=r2;
 {$ifdef TEMPREGDEBUG}
 {$ifdef TEMPREGDEBUG}
           testregisters32;
           testregisters32;
 {$endif TEMPREGDEBUG}
 {$endif TEMPREGDEBUG}
          end
          end
        else
        else
-{         getexplicitregisterint:=getregisterint(list,r and $ff);}
-{$ifndef i386}
-          // not very cleanm I know :/ The self pointer is allocated a lot
-          // more than necessary (in tcgselfnode.pass_2), but a lot of those
-          // allocations are necessary for the optimizer.
-          // The i386 doesn't care, probably because esi isn't a normal
-          // allocatable register (JM)
-          if (r <> NR_SELF_POINTER_REG) then
-{$endif i386}
-            internalerror(200301103);
+         internalerror(200301103);
+       getexplicitregisterint:=r2;
     end;
     end;
 
 
 
 
@@ -727,7 +718,9 @@ unit rgobj;
 
 
     procedure Trgobj.cleartempgen;
     procedure Trgobj.cleartempgen;
 
 
+   {$ifdef newra}
     var i:Tsuperregister;
     var i:Tsuperregister;
+   {$endif newra}
 
 
     begin
     begin
       countunusedregsint:=countusableregsint;
       countunusedregsint:=countusableregsint;
@@ -1350,7 +1343,12 @@ end.
 
 
 {
 {
   $Log$
   $Log$
-  Revision 1.31  2003-03-11 21:46:24  jonas
+  Revision 1.32  2003-03-28 19:16:57  peter
+    * generic constructor working for i386
+    * remove fixed self register
+    * esi added as address register for i386
+
+  Revision 1.31  2003/03/11 21:46:24  jonas
     * lots of new regallocator fixes, both in generic and ppc-specific code
     * lots of new regallocator fixes, both in generic and ppc-specific code
       (ppc compiler still can't compile the linux system unit though)
       (ppc compiler still can't compile the linux system unit though)
 
 

+ 67 - 137
compiler/x86/cgx86.pas

@@ -28,6 +28,8 @@ unit cgx86;
 
 
   interface
   interface
 
 
+{$define TEST_GENERIC}
+
     uses
     uses
        cginfo,cgbase,cgobj,
        cginfo,cgbase,cgobj,
        aasmbase,aasmtai,aasmcpu,
        aasmbase,aasmtai,aasmcpu,
@@ -115,11 +117,6 @@ unit cgx86;
         procedure g_stackframe_entry(list : taasmoutput;localsize : longint);override;
         procedure g_stackframe_entry(list : taasmoutput;localsize : longint);override;
         procedure g_restore_frame_pointer(list : taasmoutput);override;
         procedure g_restore_frame_pointer(list : taasmoutput);override;
         procedure g_return_from_proc(list : taasmoutput;parasize : aword);override;
         procedure g_return_from_proc(list : taasmoutput;parasize : aword);override;
-{$ifndef TEST_GENERIC}
-        procedure g_call_constructor_helper(list : taasmoutput);override;
-        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:Tsupregset);override;
         procedure g_save_standard_registers(list:Taasmoutput;usedinproc:Tsupregset);override;
         procedure g_restore_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_save_all_registers(list : taasmoutput);override;
@@ -1145,42 +1142,41 @@ unit cgx86;
 
 
     procedure tcgx86.g_concatcopy(list : taasmoutput;const source,dest : treference;len : aword; delsource,loadref : boolean);
     procedure tcgx86.g_concatcopy(list : taasmoutput;const source,dest : treference;len : aword; delsource,loadref : boolean);
       var
       var
-         ecxpushed : boolean;
+         ecxpushed,esipushed : boolean;
          helpsize : longint;
          helpsize : longint;
          i : byte;
          i : byte;
          reg8,reg32 : tregister;
          reg8,reg32 : tregister;
          srcref,dstref : treference;
          srcref,dstref : treference;
          swap : boolean;
          swap : boolean;
-         r : Tregister;
-
-         procedure maybepushecx;
-
-         var r:Tregister;
+         srcreg,destreg,r : Tregister;
 
 
+         function maybepush(r:tnewregister;var pushed:boolean):tregister;
          begin
          begin
-           r.enum:=R_INTREGISTER;
-           r.number:=NR_ECX;
-           if not(RS_ECX in rg.unusedregsint) then
+           pushed:=false;
+           result.enum:=R_INTREGISTER;
+           result.number:=r;
+           if not((r shr 8) in rg.unusedregsint) then
              begin
              begin
-               list.concat(Taicpu.Op_reg(A_PUSH,S_L,r));
-               ecxpushed:=true;
+               list.concat(Taicpu.Op_reg(A_PUSH,S_L,result));
+               pushed:=true;
              end
              end
-           else rg.getexplicitregisterint(list,NR_ECX);
+           else
+             rg.getexplicitregisterint(list,r);
          end;
          end;
 
 
       begin
       begin
+         ecxpushed:=false;
+         esipushed:=false;
          if (not loadref) and
          if (not loadref) and
             ((len<=8) or
             ((len<=8) or
              (not(cs_littlesize in aktglobalswitches ) and (len<=12))) then
              (not(cs_littlesize in aktglobalswitches ) and (len<=12))) then
            begin
            begin
-              r.enum:=R_INTREGISTER;
               helpsize:=len shr 2;
               helpsize:=len shr 2;
               dstref:=dest;
               dstref:=dest;
               srcref:=source;
               srcref:=source;
               for i:=1 to helpsize do
               for i:=1 to helpsize do
                 begin
                 begin
-                   rg.getexplicitregisterint(list,NR_EDI);
-                   r.number:=NR_EDI;
+                   r:=rg.getexplicitregisterint(list,NR_EDI);
                    a_load_ref_reg(list,OS_32,srcref,r);
                    a_load_ref_reg(list,OS_32,srcref,r);
                    If (len = 4) and delsource then
                    If (len = 4) and delsource then
                      reference_release(list,source);
                      reference_release(list,source);
@@ -1192,8 +1188,7 @@ unit cgx86;
                 end;
                 end;
               if len>1 then
               if len>1 then
                 begin
                 begin
-                   rg.getexplicitregisterint(list,NR_DI);
-                   r.number:=NR_DI;
+                   r:=rg.getexplicitregisterint(list,NR_DI);
                    a_load_ref_reg(list,OS_16,srcref,r);
                    a_load_ref_reg(list,OS_16,srcref,r);
                    If (len = 2) and delsource then
                    If (len = 2) and delsource then
                      reference_release(list,source);
                      reference_release(list,source);
@@ -1238,8 +1233,7 @@ unit cgx86;
                    if swap then
                    if swap then
                      { was earlier XCHG, of course nonsense }
                      { was earlier XCHG, of course nonsense }
                      begin
                      begin
-                       rg.getexplicitregisterint(list,NR_EDI);
-                       r.number:=NR_EDI;
+                       r:=rg.getexplicitregisterint(list,NR_EDI);
                        a_load_reg_reg(list,OS_32,OS_32,reg32,r);
                        a_load_reg_reg(list,OS_32,OS_32,reg32,r);
                      end;
                      end;
                    a_load_ref_reg(list,OS_8,srcref,reg8);
                    a_load_ref_reg(list,OS_8,srcref,reg8);
@@ -1258,27 +1252,45 @@ unit cgx86;
            end
            end
          else
          else
            begin
            begin
-              r.enum:=R_INTREGISTER;
-              r.number:=NR_EDI;
-              rg.getexplicitregisterint(list,NR_EDI);
-              a_loadaddr_ref_reg(list,dest,r);
-              r.number:=NR_ESI;
-              list.concat(tai_regalloc.alloc(r));
+              destreg:=rg.getexplicitregisterint(list,NR_EDI);
+              a_loadaddr_ref_reg(list,dest,destreg);
               if loadref then
               if loadref then
-                a_load_ref_reg(list,OS_ADDR,source,r)
+                begin
+                  srcreg:=maybepush(NR_ESI,esipushed);
+                  a_load_ref_reg(list,OS_ADDR,source,srcreg)
+                end
               else
               else
                 begin
                 begin
-                  a_loadaddr_ref_reg(list,source,r);
                   if delsource then
                   if delsource then
-                    reference_release(list,source);
+                    begin
+                      if (source.base.number=NR_ESI) then
+                        srcreg:=source.base
+                      else if (source.index.number=NR_ESI) then
+                        srcreg:=source.index
+                      else
+                        srcreg:=maybepush(NR_ESI,esipushed);
+                    end
+                  else
+                    srcreg:=maybepush(NR_ESI,esipushed);
+                  a_loadaddr_ref_reg(list,source,srcreg);
+                  if delsource then
+                   begin
+                     srcref:=source;
+                     { Don't release ESI register yet, it's needed
+                       by the movsl }
+                     if (srcref.base.number=NR_ESI) then
+                       srcref.base.number:=NR_NO
+                     else if (srcref.index.number=NR_ESI) then
+                       srcref.index.number:=NR_NO;
+                     reference_release(list,srcref);
+                   end;
                 end;
                 end;
 
 
               list.concat(Taicpu.Op_none(A_CLD,S_NO));
               list.concat(Taicpu.Op_none(A_CLD,S_NO));
               ecxpushed:=false;
               ecxpushed:=false;
-              r.number:=NR_ECX;
               if cs_littlesize in aktglobalswitches  then
               if cs_littlesize in aktglobalswitches  then
                 begin
                 begin
-                   maybepushecx;
+                   r:=maybepush(NR_ECX,ecxpushed);
                    a_load_const_reg(list,OS_INT,len,r);
                    a_load_const_reg(list,OS_INT,len,r);
                    list.concat(Taicpu.Op_none(A_REP,S_NO));
                    list.concat(Taicpu.Op_none(A_REP,S_NO));
                    list.concat(Taicpu.Op_none(A_MOVSB,S_NO));
                    list.concat(Taicpu.Op_none(A_MOVSB,S_NO));
@@ -1289,7 +1301,7 @@ unit cgx86;
                    len:=len and 3;
                    len:=len and 3;
                    if helpsize>1 then
                    if helpsize>1 then
                     begin
                     begin
-                      maybepushecx;
+                      r:=maybepush(NR_ECX,ecxpushed);
                       a_load_const_reg(list,OS_INT,helpsize,r);
                       a_load_const_reg(list,OS_INT,helpsize,r);
                       list.concat(Taicpu.Op_none(A_REP,S_NO));
                       list.concat(Taicpu.Op_none(A_REP,S_NO));
                     end;
                     end;
@@ -1304,10 +1316,6 @@ unit cgx86;
                      list.concat(Taicpu.Op_none(A_MOVSB,S_NO));
                      list.concat(Taicpu.Op_none(A_MOVSB,S_NO));
                 end;
                 end;
               r.enum:=R_INTREGISTER;
               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
               if ecxpushed then
                 begin
                 begin
                   r.number:=NR_ECX;
                   r.number:=NR_ECX;
@@ -1318,9 +1326,17 @@ unit cgx86;
                   r.number:=NR_ECX;
                   r.number:=NR_ECX;
                   rg.ungetregisterint(list,r);
                   rg.ungetregisterint(list,r);
                 end;
                 end;
-
-              { loading SELF-reference again }
-              g_maybe_loadself(list);
+              if esipushed then
+                begin
+                  r.number:=NR_ESI;
+                  list.concat(Taicpu.Op_reg(A_POP,S_L,r))
+                end
+              else
+                begin
+                  r.number:=NR_ESI;
+                  rg.ungetregisterint(list,r);
+                end;
+              rg.ungetregisterint(list,destreg);
            end;
            end;
          if delsource then
          if delsource then
           tg.ungetiftemp(list,source);
           tg.ungetiftemp(list,source);
@@ -1484,8 +1500,8 @@ unit cgx86;
     procedure tcgx86.g_removevaluepara_openarray(list : taasmoutput;const ref:treference;elesize:integer);
     procedure tcgx86.g_removevaluepara_openarray(list : taasmoutput;const ref:treference;elesize:integer);
       var
       var
         lenref : treference;
         lenref : treference;
-        power,len  : longint;
-        r,rsp:Tregister;
+        power  : longint;
+        r,rsp  : Tregister;
       begin
       begin
         lenref:=ref;
         lenref:=ref;
         inc(lenref.offset,4);
         inc(lenref.offset,4);
@@ -1726,97 +1742,6 @@ unit cgx86;
          end;
          end;
       end;
       end;
 
 
-{$ifndef TEST_GENERIC}
-    procedure tcgx86.g_call_constructor_helper(list : taasmoutput);
-
-    var r:Tregister;
-
-      begin
-        r.enum:=R_INTREGISTER;
-        r.number:=NR_EDI;
-        if is_class(procinfo._class) then
-          begin
-            if (cs_implicit_exceptions in aktmoduleswitches) then
-              procinfo.flags:=procinfo.flags or pi_needs_implicit_finally;
-            a_call_name(list,'FPC_NEW_CLASS');
-            list.concat(Taicpu.Op_cond_sym(A_Jcc,C_Z,S_NO,faillabel));
-          end
-        else if is_object(procinfo._class) then
-          begin
-            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));
-          end
-        else
-          internalerror(200006161);
-      end;
-
-    procedure tcgx86.g_call_destructor_helper(list : taasmoutput);
-      var
-        nofinal : tasmlabel;
-        href : treference;
-        r : Tregister;
-
-      begin
-        r.enum:=R_INTREGISTER;
-        if is_class(procinfo._class) then
-         begin
-           a_call_name(list,'FPC_DISPOSE_CLASS')
-         end
-        else if is_object(procinfo._class) then
-         begin
-           { must the object be finalized ? }
-           if procinfo._class.needs_inittable then
-            begin
-              objectlibrary.getlabel(nofinal);
-              r.number:=NR_EBP;
-              reference_reset_base(href,r,8);
-              a_cmp_const_ref_label(list,OS_ADDR,OC_EQ,0,href,nofinal);
-              r.number:=NR_ESI;
-              reference_reset_base(href,r,0);
-              g_finalize(list,procinfo._class,href,false);
-              a_label(list,nofinal);
-            end;
-           rg.getexplicitregisterint(list,NR_EDI);
-           r.number:=NR_EDI;
-           a_load_const_reg(list,OS_ADDR,procinfo._class.vmt_offset,r);
-           rg.ungetregisterint(list,r);
-           a_call_name(list,'FPC_HELP_DESTRUCTOR')
-         end
-        else
-         internalerror(200006162);
-      end;
-
-    procedure tcgx86.g_call_fail_helper(list : taasmoutput);
-      var
-        href : treference;
-        r : Tregister;
-      begin
-        r.enum:=R_INTREGISTER;
-        if is_class(procinfo._class) then
-          begin
-            reference_reset_base(href,procinfo.framepointer,8);
-            r.number:=NR_ESI;
-            a_load_ref_reg(list,OS_ADDR,href,r);
-            a_call_name(list,'FPC_HELP_FAIL_CLASS');
-          end
-        else if is_object(procinfo._class) then
-          begin
-            reference_reset_base(href,procinfo.framepointer,12);
-            r.number:=NR_ESI;
-            a_load_ref_reg(list,OS_ADDR,href,r);
-            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');
-            rg.ungetregisterint(list,r);
-          end
-        else
-          internalerror(200006163);
-      end;
-{$endif}
-
 
 
     procedure tcgx86.g_save_standard_registers(list:Taasmoutput;usedinproc:Tsupregset);
     procedure tcgx86.g_save_standard_registers(list:Taasmoutput;usedinproc:Tsupregset);
 
 
@@ -1918,7 +1843,12 @@ unit cgx86;
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.36  2003-03-18 18:17:46  peter
+  Revision 1.37  2003-03-28 19:16:57  peter
+    * generic constructor working for i386
+    * remove fixed self register
+    * esi added as address register for i386
+
+  Revision 1.36  2003/03/18 18:17:46  peter
     * reg2opsize()
     * reg2opsize()
 
 
   Revision 1.35  2003/03/13 19:52:23  jonas
   Revision 1.35  2003/03/13 19:52:23  jonas

Some files were not shown because too many files changed in this diff