2
0
Эх сурвалжийг харах

* moved entry and exitcode to ncgutil and cgobj
* foreach gets extra argument for passing local data to the
iterator function
* -CR checks also class typecasts at runtime by changing them
into as
* fixed compiler to cycle with the -CR option
* fixed stabs with elf writer, finally the global variables can
be watched
* removed a lot of routines from cga unit and replaced them by
calls to cgobj
* u32bit-s32bit updates for and,or,xor nodes. When one element is
u32bit then the other is typecasted also to u32bit without giving
a rangecheck warning/error.
* fixed pascal calling method with reversing also the high tree in
the parast, detected by tcalcst3 test

peter 23 жил өмнө
parent
commit
4dcd96747e
77 өөрчлөгдсөн 4621 нэмэгдсэн , 4585 устгасан
  1. 43 26
      compiler/cclasses.pas
  2. 21 4
      compiler/cg64f32.pas
  3. 91 634
      compiler/cgobj.pas
  4. 19 2
      compiler/compiler.pas
  5. 21 4
      compiler/fppu.pas
  6. 22 3
      compiler/globtype.pas
  7. 23 20
      compiler/i386/ag386att.pas
  8. 22 5
      compiler/i386/ag386int.pas
  9. 25 8
      compiler/i386/ag386nsm.pas
  10. 18 1766
      compiler/i386/cga.pas
  11. 768 207
      compiler/i386/cgcpu.pas
  12. 20 20
      compiler/i386/cpuasm.pas
  13. 35 19
      compiler/i386/cpubase.pas
  14. 18 2
      compiler/i386/cputarg.pas
  15. 27 6
      compiler/i386/daopt386.pas
  16. 52 35
      compiler/i386/n386add.pas
  17. 148 139
      compiler/i386/n386cal.pas
  18. 73 63
      compiler/i386/n386cnv.pas
  19. 114 94
      compiler/i386/n386flw.pas
  20. 45 28
      compiler/i386/n386inl.pas
  21. 27 10
      compiler/i386/n386ld.pas
  22. 37 20
      compiler/i386/n386mat.pas
  23. 56 43
      compiler/i386/n386mem.pas
  24. 21 6
      compiler/i386/n386obj.pas
  25. 43 20
      compiler/i386/n386opt.pas
  26. 41 24
      compiler/i386/n386set.pas
  27. 48 7
      compiler/i386/n386util.pas
  28. 21 4
      compiler/i386/optbase.pas
  29. 45 25
      compiler/i386/popt386.pas
  30. 19 2
      compiler/i386/ra386.pas
  31. 19 2
      compiler/i386/ra386dir.pas
  32. 23 6
      compiler/i386/rgcpu.pas
  33. 19 2
      compiler/i386/rropt386.pas
  34. 3 0
      compiler/msg/errore.msg
  35. 5 2
      compiler/msgidx.inc
  36. 178 176
      compiler/msgtxt.inc
  37. 52 19
      compiler/nadd.pas
  38. 26 4
      compiler/ncal.pas
  39. 83 139
      compiler/ncgbas.pas
  40. 50 6
      compiler/ncgcnv.pas
  41. 22 5
      compiler/ncgflw.pas
  42. 23 6
      compiler/ncgld.pas
  43. 25 9
      compiler/ncgmem.pas
  44. 963 81
      compiler/ncgutil.pas
  45. 122 88
      compiler/ncnv.pas
  46. 20 6
      compiler/ncon.pas
  47. 19 2
      compiler/nflw.pas
  48. 192 286
      compiler/ninl.pas
  49. 22 6
      compiler/nld.pas
  50. 28 10
      compiler/nmem.pas
  51. 36 20
      compiler/nobj.pas
  52. 19 2
      compiler/nset.pas
  53. 22 17
      compiler/ogelf.pas
  54. 26 3
      compiler/options.pas
  55. 21 4
      compiler/pass_2.pas
  56. 22 5
      compiler/pdecl.pas
  57. 19 2
      compiler/pdecobj.pas
  58. 50 14
      compiler/pdecsub.pas
  59. 35 18
      compiler/pexpr.pas
  60. 11 162
      compiler/pinline.pas
  61. 45 37
      compiler/pmodules.pas
  62. 29 18
      compiler/psub.pas
  63. 19 3
      compiler/psystem.pas
  64. 20 3
      compiler/ptconst.pas
  65. 19 2
      compiler/ptype.pas
  66. 20 3
      compiler/rautils.pas
  67. 29 10
      compiler/regvars.pas
  68. 24 7
      compiler/symbase.pas
  69. 22 1
      compiler/symconst.pas
  70. 75 61
      compiler/symdef.pas
  71. 21 4
      compiler/symppu.pas
  72. 32 11
      compiler/symsym.pas
  73. 61 47
      compiler/symtable.pas
  74. 28 11
      compiler/symtype.pas
  75. 21 15
      compiler/targets/t_wdosx.pas
  76. 19 2
      compiler/types.pas
  77. 19 2
      compiler/utils/ppudump.pp

+ 43 - 26
compiler/cclasses.pas

@@ -177,8 +177,8 @@ interface
        Pdictionaryhasharray=^Tdictionaryhasharray;
        Tdictionaryhasharray=array[0..hasharraysize-1] of TNamedIndexItem;
 
-       TnamedIndexCallback = procedure(p:TNamedIndexItem) of object;
-       TnamedIndexStaticCallback = procedure(p:TNamedIndexItem);
+       TnamedIndexCallback = procedure(p:TNamedIndexItem;arg:pointer) of object;
+       TnamedIndexStaticCallback = procedure(p:TNamedIndexItem;arg:pointer);
 
        Tdictionary=class
        private
@@ -197,8 +197,8 @@ interface
          procedure clear;
          function  delete(const s:string):TNamedIndexItem;
          function  empty:boolean;
-         procedure foreach(proc2call:TNamedIndexcallback);
-         procedure foreach_static(proc2call:TNamedIndexStaticCallback);
+         procedure foreach(proc2call:TNamedIndexcallback;arg:pointer);
+         procedure foreach_static(proc2call:TNamedIndexStaticCallback;arg:pointer);
          function  insert(obj:TNamedIndexItem):TNamedIndexItem;
          function  rename(const olds,News : string):TNamedIndexItem;
          function  search(const s:string):TNamedIndexItem;
@@ -225,8 +225,8 @@ interface
         constructor Create(Agrowsize:integer);
         destructor  destroy;override;
         procedure clear;
-        procedure foreach(proc2call : Tnamedindexcallback);
-        procedure foreach_static(proc2call : Tnamedindexstaticcallback);
+        procedure foreach(proc2call : Tnamedindexcallback;arg:pointer);
+        procedure foreach_static(proc2call : Tnamedindexstaticcallback;arg:pointer);
         procedure deleteindex(p:TNamedIndexItem);
         procedure delete(var p:TNamedIndexItem);
         procedure insert(p:TNamedIndexItem);
@@ -851,7 +851,7 @@ end;
 {$ifdef hashdebug}
       var
         i, unused, slots_with_col, collissions, treecount, maxcol: longint;
-{$endif hashdebug}        
+{$endif hashdebug}
       begin
         if not noclear then
          clear;
@@ -1046,15 +1046,15 @@ end;
       end;
 
 
-    procedure Tdictionary.foreach(proc2call:TNamedIndexcallback);
+    procedure Tdictionary.foreach(proc2call:TNamedIndexcallback;arg:pointer);
 
-        procedure a(p:TNamedIndexItem);
+        procedure a(p:TNamedIndexItem;arg:pointer);
         begin
-          proc2call(p);
+          proc2call(p,arg);
           if assigned(p.FLeft) then
-           a(p.FLeft);
+           a(p.FLeft,arg);
           if assigned(p.FRight) then
-           a(p.FRight);
+           a(p.FRight,arg);
         end;
 
       var
@@ -1064,23 +1064,23 @@ end;
          begin
            for i:=low(FHashArray^) to high(FHashArray^) do
             if assigned(FHashArray^[i]) then
-             a(FHashArray^[i]);
+             a(FHashArray^[i],arg);
          end
         else
          if assigned(FRoot) then
-          a(FRoot);
+          a(FRoot,arg);
       end;
 
 
-    procedure Tdictionary.foreach_static(proc2call:TNamedIndexStaticCallback);
+    procedure Tdictionary.foreach_static(proc2call:TNamedIndexStaticCallback;arg:pointer);
 
-        procedure a(p:TNamedIndexItem);
+        procedure a(p:TNamedIndexItem;arg:pointer);
         begin
-          proc2call(p);
+          proc2call(p,arg);
           if assigned(p.FLeft) then
-           a(p.FLeft);
+           a(p.FLeft,arg);
           if assigned(p.FRight) then
-           a(p.FRight);
+           a(p.FRight,arg);
         end;
 
       var
@@ -1090,11 +1090,11 @@ end;
          begin
            for i:=low(FHashArray^) to high(FHashArray^) do
             if assigned(FHashArray^[i]) then
-             a(FHashArray^[i]);
+             a(FHashArray^[i],arg);
          end
         else
          if assigned(FRoot) then
-          a(FRoot);
+          a(FRoot,arg);
       end;
 
 
@@ -1382,23 +1382,23 @@ end;
       end;
 
 
-    procedure tindexarray.foreach(proc2call : Tnamedindexcallback);
+    procedure tindexarray.foreach(proc2call : Tnamedindexcallback;arg:pointer);
       var
         i : integer;
       begin
         for i:=1 to count do
          if assigned(data^[i]) then
-          proc2call(data^[i]);
+          proc2call(data^[i],arg);
       end;
 
 
-    procedure tindexarray.foreach_static(proc2call : Tnamedindexstaticcallback);
+    procedure tindexarray.foreach_static(proc2call : Tnamedindexstaticcallback;arg:pointer);
       var
         i : integer;
       begin
         for i:=1 to count do
          if assigned(data^[i]) then
-          proc2call(data^[i]);
+          proc2call(data^[i],arg);
       end;
 
 
@@ -1728,7 +1728,24 @@ end;
 end.
 {
   $Log$
-  Revision 1.9  2001-11-18 18:43:13  peter
+  Revision 1.10  2002-05-12 16:53:04  peter
+    * moved entry and exitcode to ncgutil and cgobj
+    * foreach gets extra argument for passing local data to the
+      iterator function
+    * -CR checks also class typecasts at runtime by changing them
+      into as
+    * fixed compiler to cycle with the -CR option
+    * fixed stabs with elf writer, finally the global variables can
+      be watched
+    * removed a lot of routines from cga unit and replaced them by
+      calls to cgobj
+    * u32bit-s32bit updates for and,or,xor nodes. When one element is
+      u32bit then the other is typecasted also to u32bit without giving
+      a rangecheck warning/error.
+    * fixed pascal calling method with reversing also the high tree in
+      the parast, detected by tcalcst3 test
+
+  Revision 1.9  2001/11/18 18:43:13  peter
     * overloading supported in child classes
     * fixed parsing of classes with private and virtual and overloaded
       so it is compatible with delphi

+ 21 - 4
compiler/cg64f32.pas

@@ -475,7 +475,7 @@ unit cg64f32;
              if got_scratch then
                free_scratch_reg(list,hreg);
              { For all other values we have a range check error }
-             a_call_name(list,'FPC_RANGEERROR',0);
+             a_call_name(list,'FPC_RANGEERROR');
 
              { if the high dword = 0, the low dword can be considered a }
              { simple cardinal                                          }
@@ -515,7 +515,7 @@ unit cg64f32;
                  if got_scratch then
                    free_scratch_reg(list,hreg);
 
-                 a_call_name(list,'FPC_RANGEERROR',0);
+                 a_call_name(list,'FPC_RANGEERROR');
 
                  { if we get here, the 64bit value lies between }
                  { longint($80000000) and -1 (JM)               }
@@ -573,7 +573,7 @@ unit cg64f32;
                { !!! freeing of register should happen directly after compare! (JM) }
                if got_scratch then
                  free_scratch_reg(list,hreg);
-               a_call_name(list,'FPC_RANGEERROR',0);
+               a_call_name(list,'FPC_RANGEERROR');
                a_label(list,poslabel);
              end;
       end;
@@ -591,7 +591,24 @@ begin
 end.
 {
   $Log$
-  Revision 1.9  2002-04-25 20:16:38  peter
+  Revision 1.10  2002-05-12 16:53:04  peter
+    * moved entry and exitcode to ncgutil and cgobj
+    * foreach gets extra argument for passing local data to the
+      iterator function
+    * -CR checks also class typecasts at runtime by changing them
+      into as
+    * fixed compiler to cycle with the -CR option
+    * fixed stabs with elf writer, finally the global variables can
+      be watched
+    * removed a lot of routines from cga unit and replaced them by
+      calls to cgobj
+    * u32bit-s32bit updates for and,or,xor nodes. When one element is
+      u32bit then the other is typecasted also to u32bit without giving
+      a rangecheck warning/error.
+    * fixed pascal calling method with reversing also the high tree in
+      the parast, detected by tcalcst3 test
+
+  Revision 1.9  2002/04/25 20:16:38  peter
     * moved more routines from cga/n386util
 
   Revision 1.8  2002/04/21 15:28:51  carl

+ 91 - 634
compiler/cgobj.pas

@@ -58,6 +58,9 @@ unit cgobj;
           {                 basic routines                 }
           constructor create;
 
+          { returns the tcgsize corresponding with the size of reg }
+          class function reg_cgsize(const reg: tregister) : tcgsize; virtual;
+
           {# Emit a label to the instruction stream. }
           procedure a_label(list : taasmoutput;l : tasmlabel);virtual;
 
@@ -82,23 +85,6 @@ unit cgobj;
           }
           procedure free_scratch_reg(list : taasmoutput;r : tregister);
 
-          {************************************************}
-          { code generation for subroutine entry/exit code }
-
-          { helper routines }
-          procedure g_initialize_data(list : taasmoutput;p : tsym);
-          procedure g_incr_data(list : taasmoutput;p : tsym);
-          procedure g_finalize_data(list : taasmoutput;p : tnamedindexitem);
-          procedure g_copyvalueparas(list : taasmoutput;p : tnamedindexitem);
-
-          procedure g_entrycode(alist : TAAsmoutput;make_global:boolean;
-                           stackframe:longint;
-                           var parasize:longint;var nostackframe:boolean;
-                           inlined : boolean);
-
-          procedure g_exitcode(list : taasmoutput;parasize : longint;
-            nostackframe,inlined : boolean);
-
           { passing parameters, per default the parameter is pushed }
           { nr gives the number of the parameter (enumerated from   }
           { left to right), this allows to move the parameter to    }
@@ -172,11 +158,11 @@ unit cgobj;
               second the destination
           }
 
-          {# Emits instruction to call the method specified by symbol name @var(s) with offset
-             to symbol in @var(offset). This routine must be overriden for each new target cpu.
+          {# Emits instruction to call the method specified by symbol name.
+             This routine must be overriden for each new target cpu.
           }
-          procedure a_call_name(list : taasmoutput;const s : string;
-            offset : longint);virtual; abstract;
+          procedure a_call_name(list : taasmoutput;const s : string);virtual; abstract;
+          procedure a_call_ref(list : taasmoutput;const ref : treference);virtual; abstract;
 
           { move instructions }
           procedure a_load_const_reg(list : taasmoutput;size : tcgsize;a : aword;register : tregister);virtual; abstract;
@@ -190,6 +176,7 @@ unit cgobj;
           procedure a_load_loc_reg(list : taasmoutput;const loc: tlocation; reg : tregister);
           procedure a_load_loc_ref(list : taasmoutput;const loc: tlocation; const ref : treference);
           procedure a_load_sym_ofs_reg(list: taasmoutput; const sym: tasmsymbol; ofs: longint; reg: tregister);virtual; abstract;
+          procedure a_loadaddr_ref_reg(list : taasmoutput;const ref : treference;r : tregister);virtual; abstract;
 
           { fpu move instructions }
           procedure a_loadfpu_reg_reg(list: taasmoutput; reg1, reg2: tregister); virtual; abstract;
@@ -244,42 +231,13 @@ unit cgobj;
 
           procedure g_flags2reg(list: taasmoutput; const f: tresflags; reg: TRegister); virtual; abstract;
 
-          procedure a_loadaddr_ref_reg(list : taasmoutput;const ref : treference;r : tregister);virtual; abstract;
-          procedure g_stackframe_entry(list : taasmoutput;localsize : longint);virtual; abstract;
-          { restores the frame pointer at procedure exit, for the }
-          { i386 it generates a simple leave                      }
-          procedure g_restore_frame_pointer(list : taasmoutput);virtual; abstract;
-
           { some processors like the PPC doesn't allow to change the stack in }
           { a procedure, so we need to maintain an extra stack for the        }
           { result values of setjmp in exception code                         }
           { this two procedures are for pushing an exception value,           }
           { they can use the scratch registers                                }
-          procedure g_push_exception_value_reg(list : taasmoutput;reg : tregister);virtual; abstract;
-          procedure g_push_exception_value_const(list : taasmoutput;reg : tregister);virtual; abstract;
-          { that procedure pops a exception value                             }
-          procedure g_pop_exception_value_reg(list : taasmoutput;reg : tregister);virtual; abstract;
-          procedure g_return_from_proc(list : taasmoutput;parasize : aword);virtual; abstract;
-          {********************************************************}
-          { these methods can be overriden for extra functionality }
-
-          {# Emits instructions which should be emitted when entering
-             a routine declared as @var(interrupt). The default
-             behavior does nothing, should be overriden as required.
-          }
-          procedure g_interrupt_stackframe_entry(list : taasmoutput);virtual;
-
-          {# Emits instructions which should be emitted when exiting
-             a routine declared as @var(interrupt). The default
-             behavior does nothing, should be overriden as required.
-          }
-          procedure g_interrupt_stackframe_exit(list : taasmoutput);virtual;
-
-          {# Emits instructions when compilation is done in profile
-             mode (this is set as a command line option). The default
-             behavior does nothing, should be overriden as required.
-          }
-          procedure g_profilecode(list : taasmoutput);virtual;
+          procedure g_push_exception(list : taasmoutput;const exceptbuf:treference;l:AWord; exceptlabel:TAsmLabel);virtual;abstract;
+          procedure g_pop_exception(list : taasmoutput;endexceptlabel:tasmlabel);virtual;abstract;
 
           procedure g_maybe_loadself(list : taasmoutput);virtual; abstract;
           {# This should emit the opcode to copy len bytes from the source
@@ -334,10 +292,38 @@ unit cgobj;
           { generates overflow checking code for a node }
           procedure g_overflowcheck(list: taasmoutput; const p: tnode); virtual; abstract;
 
+          {**********************************}
+          {    entry/exit code helpers       }
 
-          { returns the tcgsize corresponding with the size of reg }
-          class function reg_cgsize(const reg: tregister) : tcgsize; virtual;
+          procedure g_copyvaluepara_openarray(list : taasmoutput;const ref:treference;elesize:integer); virtual; abstract;
+          {# Emits instructions which should be emitted when entering
+             a routine declared as @var(interrupt). The default
+             behavior does nothing, should be overriden as required.
+          }
+          procedure g_interrupt_stackframe_entry(list : taasmoutput);virtual;
 
+          {# Emits instructions which should be emitted when exiting
+             a routine declared as @var(interrupt). The default
+             behavior does nothing, should be overriden as required.
+          }
+          procedure g_interrupt_stackframe_exit(list : taasmoutput;selfused,accused,acchiused:boolean);virtual;
+
+          {# Emits instructions when compilation is done in profile
+             mode (this is set as a command line option). The default
+             behavior does nothing, should be overriden as required.
+          }
+          procedure g_profilecode(list : taasmoutput);virtual;
+          procedure g_stackframe_entry(list : taasmoutput;localsize : longint);virtual; abstract;
+          { restores the frame pointer at procedure exit }
+          procedure g_restore_frame_pointer(list : taasmoutput);virtual; abstract;
+          procedure g_return_from_proc(list : taasmoutput;parasize : aword);virtual; abstract;
+          procedure g_call_constructor_helper(list : taasmoutput);virtual;abstract;
+          procedure g_call_destructor_helper(list : taasmoutput);virtual;abstract;
+          procedure g_call_fail_helper(list : taasmoutput);virtual;abstract;
+          procedure g_save_standard_registers(list : taasmoutput);virtual;abstract;
+          procedure g_restore_standard_registers(list : taasmoutput);virtual;abstract;
+          procedure g_save_all_registers(list : taasmoutput);virtual;abstract;
+          procedure g_restore_all_registers(list : taasmoutput;selfused,accused,acchiused:boolean);virtual;abstract;
        end;
 
     var
@@ -347,7 +333,7 @@ unit cgobj;
 
     uses
        globals,globtype,options,systems,cgbase,
-       verbose,types,tgobj,symdef,cga,tainst,rgobj;
+       verbose,types,tgobj,symdef,tainst,rgobj;
 
     const
       max_scratch_regs = high(scratch_regs) - low(scratch_regs) + 1;
@@ -417,25 +403,6 @@ unit cgobj;
          a_reg_dealloc(list,r);
       end;
 
-{*****************************************************************************
-            this methods must be overridden for extra functionality
-******************************************************************************}
-
-    procedure tcg.g_interrupt_stackframe_entry(list : taasmoutput);
-
-      begin
-      end;
-
-    procedure tcg.g_interrupt_stackframe_exit(list : taasmoutput);
-
-      begin
-      end;
-
-    procedure tcg.g_profilecode(list : taasmoutput);
-
-      begin
-      end;
-
 {*****************************************************************************
           for better code generation these methods should be overridden
 ******************************************************************************}
@@ -495,554 +462,10 @@ unit cgobj;
          free_scratch_reg(list,hr);
       end;
 
-{*****************************************************************************
-                  Code generation for subroutine entry- and exit code
- *****************************************************************************}
-
-    { generates the code for initialisation of local data }
-    procedure tcg.g_initialize_data(list : taasmoutput;p : tsym);
-
-{      var
-         hr : treference; }
-
-      begin
-(*
-         if (tsym(p)^.typ=varsym) and
-            assigned(pvarsym(p)^.vartype.def) and
-            not((pvarsym(p)^.vartype.def^.deftype=objectdef) and
-              pobjectdef(pvarsym(p)^.vartype.def)^.is_class) and
-            pvarsym(p)^.vartype.def^.needs_inittable then
-           begin
-              procinfo^.flags:=procinfo^.flags or pi_needs_implicit_finally;
-              reset_reference(hr);
-              if tsym(p)^.owner^.symtabletype=localsymtable then
-                begin
-                   hr.base:=procinfo^.framepointer;
-                   hr.offset:=-pvarsym(p)^.address;
-                end
-              else
-                begin
-                   hr.symbol:=newasmsymbol(pvarsym(p)^.mangledname);
-                end;
-              g_initialize(list,pvarsym(p)^.vartype.def,hr,false);
-           end;
-*)
-        runerror(211);
-      end;
-
-
-    { generates the code for incrementing the reference count of parameters }
-    procedure tcg.g_incr_data(list : taasmoutput;p : tsym);
-
-{      var
-         hr : treference; }
-
-      begin
-(*
-         if (tsym(p)^.typ=varsym) and
-            not((pvarsym(p)^.vartype.def^.deftype=objectdef) and
-              pobjectdef(pvarsym(p)^.vartype.def)^.is_class) and
-            pvarsym(p)^.vartype.def^.needs_inittable and
-            ((pvarsym(p)^.varspez=vs_value)) then
-           begin
-              procinfo^.flags:=procinfo^.flags or pi_needs_implicit_finally;
-              reset_reference(hr);
-              hr.symbol:=pvarsym(p)^.vartype.def^.get_inittable_label;
-              a_param_ref_addr(list,hr,2);
-              reset_reference(hr);
-              hr.base:=procinfo^.framepointer;
-              hr.offset:=pvarsym(p)^.address+procinfo^.para_offset;
-              a_param_ref_addr(list,hr,1);
-              reset_reference(hr);
-              a_call_name(list,'FPC_ADDREF',0);
-           end;
-*)
-        runerror(211);
-      end;
-
-
-    { generates the code for finalisation of local data }
-    procedure tcg.g_finalize_data(list : taasmoutput;p : tnamedindexitem);
-
- {     var
-         hr : treference; }
-
-      begin
-(*
-         if (tsym(p)^.typ=varsym) and
-            assigned(pvarsym(p)^.vartype.def) and
-            not((pvarsym(p)^.vartype.def^.deftype=objectdef) and
-            pobjectdef(pvarsym(p)^.vartype.def)^.is_class) and
-            pvarsym(p)^.vartype.def^.needs_inittable then
-           begin
-              { not all kind of parameters need to be finalized  }
-              if (tsym(p)^.owner^.symtabletype=parasymtable) and
-                ((pvarsym(p)^.varspez=vs_var)  or
-                 (pvarsym(p)^.varspez=vs_const) { and
-                 (dont_copy_const_param(pvarsym(p)^.definition)) } ) then
-                exit;
-              procinfo^.flags:=procinfo^.flags or pi_needs_implicit_finally;
-              reset_reference(hr);
-              case tsym(p)^.owner^.symtabletype of
-                 localsymtable:
-                   begin
-                      hr.base:=procinfo^.framepointer;
-                      hr.offset:=-pvarsym(p)^.address;
-                   end;
-                 parasymtable:
-                   begin
-                      hr.base:=procinfo^.framepointer;
-                      hr.offset:=pvarsym(p)^.address+procinfo^.para_offset;
-                   end;
-                 else
-                   hr.symbol:=newasmsymbol(pvarsym(p)^.mangledname);
-              end;
-              g_finalize(list,pvarsym(p)^.vartype.def,hr,false);
-           end;
-*)
-        runerror(211);
-      end;
-
-
-    { generates the code to make local copies of the value parameters }
-    procedure tcg.g_copyvalueparas(list : taasmoutput;p : tnamedindexitem);
-      begin
-         runerror(255);
-      end;
-
-(*
-    var
-       _list : taasmoutput;
 
-    { wrappers for the methods, because TP doesn't know procedures }
-    { of objects                                                   }
-
-    procedure _copyvalueparas(s : tnamedindexitem);{$ifndef FPC}far;{$endif}
-
-      begin
-         cg^.g_copyvalueparas(_list,s);
-      end;
-
-    procedure _finalize_data(s : tnamedindexitem);{$ifndef FPC}far;{$endif}
-
-      begin
-         cg^.g_finalize_data(_list,s);
-      end;
-
-    procedure _incr_data(s : tnamedindexitem);{$ifndef FPC}far;{$endif}
-
-      begin
-         cg^.g_incr_data(_list,tsym(s));
-      end;
-
-    procedure _initialize_data(s : tnamedindexitem);{$ifndef FPC}far;{$endif}
-
-      begin
-         cg^.g_initialize_data(_list,tsym(s));
-      end;
-*)
-
-    { generates the entry code for a procedure }
-    procedure tcg.g_entrycode(alist : TAAsmoutput;make_global:boolean;
-                     stackframe:longint;
-                     var parasize:longint;var nostackframe:boolean;
-                     inlined : boolean);
-
-
-(*
-      var
-         hs : string;
-         hp : pused_unit;
-         initcode : taasmoutput;
-{$ifdef GDB}
-         stab_function_name : Pai_stab_function_name;
-{$endif GDB}
-         hr : treference;
-         r : tregister;
-*)
-
-      begin
-(*
-         { Align }
-         if (not inlined) then
-           begin
-              { gprof uses 16 byte granularity !! }
-              if (cs_profile in aktmoduleswitches) then
-                list^.insert(new(pai_align,init(16)))
-              else
-                if not(cs_littlesize in aktglobalswitches) then
-                  list^.insert(new(pai_align,init(4)));
-          end;
-         { save registers on cdecl }
-         if (po_savestdregs in aktprocsym^.definition^.procoptions) then
-           begin
-              for r:=firstreg to lastreg do
-                begin
-                   if (r in registers_saved_on_cdecl) then
-                     if (r in (tg.availabletempregsint+
-                               tg.availabletempregsfpu+
-                               tg.availabletempregsmm)) then
-                       begin
-                          if not(r in tg.usedinproc) then
-                            {!!!!!!!!!!!! a_push_reg(list,r) }
-                       end
-                     else
-                       {!!!!!!!! a_push_reg(list,r) };
-                end;
-           end;
-        { omit stack frame ? }
-        if not inlined then
-          if procinfo^.framepointer=STACK_POINTER_REG then
-            begin
-               CGMessage(cg_d_stackframe_omited);
-               nostackframe:=true;
-               if (aktprocsym^.definition^.proctypeoption in [potype_unitinit,potype_proginit,potype_unitfinalize]) then
-                 parasize:=0
-               else
-                 parasize:=aktprocsym^.definition^.parast^.datasize+procinfo^.para_offset-pointersize;
-            end
-          else
-            begin
-               if (aktprocsym^.definition^.proctypeoption in [potype_unitinit,potype_proginit,potype_unitfinalize]) then
-                 parasize:=0
-               else
-                 parasize:=aktprocsym^.definition^.parast^.datasize+procinfo^.para_offset-pointersize*2;
-               nostackframe:=false;
-               if (po_interrupt in aktprocsym^.definition^.procoptions) then
-                 g_interrupt_stackframe_entry(list);
-
-               g_stackframe_entry(list,stackframe);
-
-               if (cs_check_stack in aktlocalswitches) and
-                 (tf_supports_stack_checking in target_info.flags) then
-                 g_stackcheck(@initcode,stackframe);
-            end;
-
-         if cs_profile in aktmoduleswitches then
-           g_profilecode(@initcode);
-          if (not inlined) and (aktprocsym^.definition^.proctypeoption in [potype_unitinit]) then
-            begin
-
-              { needs the target a console flags ? }
-              if tf_needs_isconsole in target_info.flags then
-                begin
-                   hr.symbol:=newasmsymbol('U_'+target_info.system_unit+'_ISCONSOLE');
-                   if apptype=at_cui then
-                     a_load_const_ref(list,OS_8,1,hr)
-                   else
-                     a_load_const_ref(list,OS_8,0,hr);
-                   dispose(hr.symbol,done);
-                end;
-
-              hp:=pused_unit(usedunits.first);
-              while assigned(hp) do
-                begin
-                   { call the unit init code and make it external }
-                   if (hp^.u^.flags and uf_init)<>0 then
-                     a_call_name(list,
-                       'INIT$$'+hp^.u^.modulename^,0);
-                    hp:=Pused_unit(hp^.next);
-                end;
-           end;
-
-{$ifdef dummy}
-         { a constructor needs a help procedure }
-         if (aktprocsym^.definition^.options and poconstructor)<>0 then
-           begin
-             if procinfo^._class^.isclass then
-               begin
-                 list^.concat(new(paicpu,op_sym(A_CALL,S_NO,newasmsymbol('FPC_NEW_CLASS'))));
-                 list^.concat(new(paicpu,op_cond_sym(A_Jcc,C_Z,S_NO,quickexitlabel)));
-               end
-             else
-               begin
-                 {
-                 list^.insert(new(pai_labeled,init(A_JZ,quickexitlabel)));
-                 list^.insert(new(paicpu,op_csymbol(A_CALL,S_NO,
-                   newcsymbol('FPC_HELP_CONSTRUCTOR',0))));
-                 list^.insert(new(paicpu,op_const_reg(A_MOV,S_L,procinfo^._class^.vmt_offset,R_EDI)));
-                 concat_external('FPC_HELP_CONSTRUCTOR',EXT_NEAR);
-                 }
-               end;
-           end;
-{$endif dummy}
-  {$ifdef GDB}
-         if (cs_debuginfo in aktmoduleswitches) then
-           list^.insert(new(pai_force_line,init));
-  {$endif GDB}
-
-         { initialize return value }
-         if assigned(procinfo^.returntype.def) and
-           is_ansistring(procinfo^.returntype.def) or
-           is_widestring(procinfo^.returntype.def) then
-           begin
-              reset_reference(hr);
-              hr.offset:=procinfo^.return_offset;
-              hr.base:=procinfo^.framepointer;
-              a_load_const_ref(list,OS_32,0,hr);
-           end;
-
-         _list:=list;
-         { generate copies of call by value parameters }
-         if (po_assembler in aktprocsym^.definition^.procoptions) then
-            aktprocsym^.definition^.parast^.foreach({$ifdef FPCPROCVAR}@{$endif}_copyvalueparas);
-
-         { initialisizes local data }
-         aktprocsym^.definition^.localst^.foreach({$ifdef FPCPROCVAR}@{$endif}_initialize_data);
-         { add a reference to all call by value/const parameters }
-         aktprocsym^.definition^.parast^.foreach({$ifdef FPCPROCVAR}@{$endif}_incr_data);
-
-         if (cs_profile in aktmoduleswitches) or
-           (aktprocsym^.definition^.owner^.symtabletype=globalsymtable) or
-           (assigned(procinfo^._class) and (procinfo^._class^.owner^.symtabletype=globalsymtable)) then
-           make_global:=true;
-         if not inlined then
-           begin
-              hs:=proc_names.get;
-
-  {$ifdef GDB}
-              if (cs_debuginfo in aktmoduleswitches) and target_os.use_function_relative_addresses then
-                stab_function_name := new(pai_stab_function_name,init(strpnew(hs)));
-  {$endif GDB}
-
-              { insert the names for the procedure }
-              while hs<>'' do
-                begin
-                   if make_global then
-                     exprasmlist^.insert(new(pai_symbol,initname_global(hs,0)))
-                   else
-                     exprasmlist^.insert(new(pai_symbol,initname(hs,0)));
-
-  {$ifdef GDB}
-                   if (cs_debuginfo in aktmoduleswitches) then
-                     begin
-                       if target_os.use_function_relative_addresses then
-                         list^.insert(new(pai_stab_function_name,init(strpnew(hs))));
-                    end;
-  {$endif GDB}
-
-                  hs:=proc_names.get;
-               end;
-          end;
-
-  {$ifdef GDB}
-         if (not inlined) and (cs_debuginfo in aktmoduleswitches) then
-           begin
-              if target_os.use_function_relative_addresses then
-                  list^.insert(stab_function_name);
-              if make_global or ((procinfo^.flags and pi_is_global) <> 0) then
-                  aktprocsym^.is_global := True;
-              list^.insert(new(pai_stabs,init(aktprocsym^.stabstring)));
-              aktprocsym^.isstabwritten:=true;
-            end;
-  {$endif GDB}
-*)
-      runerror(211);
-    end;
-
-    procedure tcg.g_exitcode(list : taasmoutput;parasize:longint;nostackframe,inlined:boolean);
-(*
-      var
-  {$ifdef GDB}
-         mangled_length : longint;
-         p : pchar;
-  {$endif GDB}
-         nofinal,noreraiselabel : tasmlabel;
-         hr : treference;
-         r : tregister;
-*)
-      begin
-(*
-         if aktexitlabel^.is_used then
-           list^.insert(new(pai_label,init(aktexitlabel)));
-
-         { call the destructor help procedure }
-         if (aktprocsym^.definition^.proctypeoption=potype_destructor) then
-           begin
-             if procinfo^._class^.is_class then
-               a_call_name(list,'FPC_DISPOSE_CLASS',0)
-             else
-               begin
-                  if procinfo^._class^.needs_inittable then
-                    begin
-                       getlabel(nofinal);
-                       {!!!!!!!!!!
-                       reset_reference(hr);
-                       hr.base:=R_EBP;
-                       hr.offset:=8;
-                       a_cmp_reg_const_label(list,OS_ADDR,OZ_EQ,
-                       }
-                       reset_reference(hr);
-                       hr.symbol:=procinfo^._class^.get_inittable_label;
-                       a_paramaddr_ref(list,hr,2);
-                       a_param_reg(list,OS_ADDR,self_pointer_reg,1);
-                       a_call_name(list,'FPC_FINALIZE',0);
-                       a_label(list,nofinal);
-                    end;
-                  { vmt_offset_reg can be a scratch register, }
-                  { but it must be always the same            }
-                  a_reg_alloc(list,vmt_offset_reg);
-                  a_load_const_reg(list,OS_32,procinfo^._class^.vmt_offset,vmt_offset_reg);
-                  a_call_name(list,'FPC_HELP_DESTRUCTOR',0);
-                  a_reg_dealloc(list,vmt_offset_reg);
-               end;
-           end;
-
-         { finalize temporary data }
-         g_finalizetempansistrings(list);
-
-         _list:=list;
-
-         { finalize local data }
-         aktprocsym^.definition^.localst^.foreach({$ifdef FPCPROCVAR}@{$endif}_finalize_data);
-
-         { finalize paras data }
-         if assigned(aktprocsym^.definition^.parast) then
-           aktprocsym^.definition^.parast^.foreach({$ifdef FPCPROCVAR}@{$endif}_finalize_data);
-
-         { do we need to handle exceptions because of ansi/widestrings ? }
-         if (procinfo^.flags and pi_needs_implicit_finally)<>0 then
-           begin
-              getlabel(noreraiselabel);
-
-              a_call_name(list,'FPC_POPADDRSTACK',0);
-              a_reg_alloc(list,accumulator);
-              g_pop_exception_value_reg(list,accumulator);
-              a_cmp_const_reg_label(list,OS_32,OC_EQ,0,accumulator,noreraiselabel);
-              a_reg_dealloc(list,accumulator);
-
-              { must be the return value finalized before reraising the exception? }
-              if (procinfo^.returntype.def<>tdef(voiddef)) and
-                (procinfo^.returntype.def^.needs_inittable) and
-                ((procinfo^.returntype.def^.deftype<>objectdef) or
-                not(pobjectdef(procinfo^.returntype.def)^.is_class)) then
-                begin
-                   reset_reference(hr);
-                   hr.offset:=procinfo^.return_offset;
-                   hr.base:=procinfo^.framepointer;
-                   g_finalize(list,procinfo^.returntype.def,hr,ret_in_param(procinfo^.returntype.def));
-                end;
-
-              a_call_name(list,'FPC_RERAISE',0);
-              a_label(list,noreraiselabel);
-           end;
-
-         { call __EXIT for main program }
-         if (not DLLsource) and (not inlined) and (aktprocsym^.definition^.proctypeoption=potype_proginit) then
-           a_call_name(list,'FPC_DO_EXIT',0);
-
-         { handle return value }
-         if not(po_assembler in aktprocsym^.definition^.procoptions) then
-             if (aktprocsym^.definition^.proctypeoption<>potype_constructor) then
-               { handle_return_value(inlined) }
-             else
-               begin
-                  { return self in EAX }
-                  a_label(list,quickexitlabel);
-                  a_reg_alloc(list,accumulator);
-                  a_load_reg_reg(list,OS_ADDR,self_pointer_reg,accumulator);
-                  a_reg_dealloc(list,self_pointer_reg);
-                  a_label(list,quickexitlabel);
-                  { we can't clear the zero flag because the Alpha     }
-                  { for example doesn't have flags, we have to compare }
-                  { the accu. in the caller                            }
-               end;
-
-         { stabs uses the label also ! }
-         if aktexit2label^.is_used or
-            ((cs_debuginfo in aktmoduleswitches) and not inlined) then
-           a_label(list,aktexit2label);
-
-{$ifdef dummy}
-         { should we restore edi ? }
-         { for all i386 gcc implementations }
-         {!!!!!!!!!!! I don't know how to handle register saving yet }
-         if (po_savestdregs in aktprocsym^.definition^.procoptions) then
-           begin
-             if (aktprocsym^.definition^.usedregisters and ($80 shr byte(R_EBX)))<>0 then
-              exprasmlist^.concat(new(paicpu,op_reg(A_POP,S_L,R_EBX)));
-             exprasmlist^.concat(new(paicpu,op_reg(A_POP,S_L,R_ESI)));
-             exprasmlist^.concat(new(paicpu,op_reg(A_POP,S_L,R_EDI)));
-             { here we could reset R_EBX
-               but that is risky because it only works
-               if genexitcode is called after genentrycode
-               so lets skip this for the moment PM
-             aktprocsym^.definition^.usedregisters:=
-               aktprocsym^.definition^.usedregisters or not ($80 shr byte(R_EBX));
-             }
-           end;
-{$endif dummy}
-         if not(nostackframe) and not inlined then
-           g_restore_frame_pointer(list);
-         { at last, the return is generated }
-
-         if not inlined then
-           if po_interrupt in aktprocsym^.definition^.procoptions then
-             g_interrupt_stackframe_exit(list)
-         else
-           g_return_from_proc(list,parasize);
-         list^.concat(new(pai_symbol_end,initname(aktprocsym^.definition^.mangledname)));
-
-    {$ifdef GDB}
-         if (cs_debuginfo in aktmoduleswitches) and not inlined  then
-             begin
-                aktprocsym^.concatstabto(list);
-                if assigned(procinfo^._class) then
-                  if (not assigned(procinfo^.parent) or
-                     not assigned(procinfo^.parent^._class)) then
-                    list^.concat(new(pai_stabs,init(strpnew(
-                     '"$t:v'+procinfo^._class^.numberstring+'",'+
-                     tostr(N_PSYM)+',0,0,'+tostr(procinfo^.selfpointer_offset)))));
-                  {!!!!!!!!!!!!
-                  else
-                    list^.concat(new(pai_stabs,init(strpnew(
-                     '"$t:r'+procinfo^._class^.numberstring+'",'+
-                     tostr(N_RSYM)+',0,0,'+tostr(GDB_i386index[R_ESI])))));
-                  }
-                if (tdef(aktprocsym^.definition^.rettype.def) <> tdef(voiddef)) then
-                  begin
-                    if ret_in_param(aktprocsym^.definition^.rettype.def) then
-                      list^.concat(new(pai_stabs,init(strpnew(
-                       '"'+aktprocsym^.name+':X*'+aktprocsym^.definition^.rettype.def^.numberstring+'",'+
-                       tostr(N_PSYM)+',0,0,'+tostr(procinfo^.return_offset)))))
-                    else
-                      list^.concat(new(pai_stabs,init(strpnew(
-                       '"'+aktprocsym^.name+':X'+aktprocsym^.definition^.rettype.def^.numberstring+'",'+
-                       tostr(N_PSYM)+',0,0,'+tostr(procinfo^.return_offset)))));
-                    if (m_result in aktmodeswitches) then
-                      if ret_in_param(aktprocsym^.definition^.rettype.def) then
-                        list^.concat(new(pai_stabs,init(strpnew(
-                         '"RESULT:X*'+aktprocsym^.definition^.rettype.def^.numberstring+'",'+
-                         tostr(N_PSYM)+',0,0,'+tostr(procinfo^.return_offset)))))
-                      else
-                        list^.concat(new(pai_stabs,init(strpnew(
-                         '"RESULT:X'+aktprocsym^.definition^.rettype.def^.numberstring+'",'+
-                         tostr(N_PSYM)+',0,0,'+tostr(procinfo^.return_offset)))));
-                  end;
-                mangled_length:=length(aktprocsym^.definition^.mangledname);
-                getmem(p,mangled_length+50);
-                strpcopy(p,'192,0,0,');
-                strpcopy(strend(p),aktprocsym^.definition^.mangledname);
-                list^.concat(new(pai_stabn,init(strnew(p))));
-                {list^.concat(new(pai_stabn,init(strpnew('192,0,0,'
-                 +aktprocsym^.definition^.mangledname))));
-                p[0]:='2';p[1]:='2';p[2]:='4';
-                strpcopy(strend(p),'_end');}
-                freemem(p,mangled_length+50);
-                list^.concat(new(pai_stabn,init(
-                  strpnew('224,0,0,'+aktexit2label^.name))));
-                 { strpnew('224,0,0,'
-                 +aktprocsym^.definition^.mangledname+'_end'))));}
-             end;
-    {$endif GDB}
-*)
-        runerror(211);
-      end;
-
-{*****************************************************************************
+{****************************************************************************
                        some generic implementations
- ****************************************************************************}
-
+****************************************************************************}
 
     procedure tcg.a_load_ref_ref(list : taasmoutput;size : tcgsize;const sref : treference;const dref : treference);
 
@@ -1397,7 +820,7 @@ unit cgobj;
         if delsource then
          reference_release(list,source);
         a_param_const(list,OS_INT,len,1);
-        a_call_name(list,'FPC_SHORTSTR_COPY',0);
+        a_call_name(list,'FPC_SHORTSTR_COPY');
         g_maybe_loadself(list);
       end;
 
@@ -1423,14 +846,14 @@ unit cgobj;
          if incrfunc<>'' then
           begin
             a_param_ref(list,OS_ADDR,ref,1);
-            a_call_name(list,incrfunc,0);
+            a_call_name(list,incrfunc);
           end
          else
           begin
             reference_reset_symbol(href,tstoreddef(t).get_rtti_label(initrtti),0);
             a_paramaddr_ref(list,href,2);
             a_paramaddr_ref(list,ref,1);
-            a_call_name(list,'FPC_ADDREF',0);
+            a_call_name(list,'FPC_ADDREF');
          end;
       end;
 
@@ -1454,14 +877,14 @@ unit cgobj;
          if decrfunc<>'' then
           begin
             a_paramaddr_ref(list,ref,1);
-            a_call_name(list,decrfunc,0);
+            a_call_name(list,decrfunc);
           end
          else
           begin
             reference_reset_symbol(href,tstoreddef(t).get_rtti_label(initrtti),0);
             a_paramaddr_ref(list,href,2);
             a_paramaddr_ref(list,ref,1);
-            a_call_name(list,'FPC_DECREF',0);
+            a_call_name(list,'FPC_DECREF');
          end;
       end;
 
@@ -1482,7 +905,7 @@ unit cgobj;
                 a_param_ref(list,OS_ADDR,ref,1)
               else
                 a_paramaddr_ref(list,ref,1);
-              a_call_name(list,'FPC_INITIALIZE',0);
+              a_call_name(list,'FPC_INITIALIZE');
            end;
       end;
 
@@ -1503,7 +926,7 @@ unit cgobj;
                 a_param_ref(list,OS_ADDR,ref,1)
               else
                 a_paramaddr_ref(list,ref,1);
-              a_call_name(list,'FPC_FINALIZE',0);
+              a_call_name(list,'FPC_FINALIZE');
            end;
       end;
 
@@ -1542,7 +965,7 @@ unit cgobj;
         { Note that these checks are mostly processor independent, they only }
         { have to be changed once we introduce 64bit subrange types          }
         if (fromdef = todef) and
-          { then fromdef and todef can only be orddefs }
+           (fromdef.deftype=orddef) and
            (((sizeof(aword) = 4) and
              (((torddef(fromdef).typ = s32bit) and
                (lfrom = low(longint)) and
@@ -1580,7 +1003,7 @@ unit cgobj;
                  { if low(to) > maxlongint also range error }
                  (lto > awordsignedmax) then
                 begin
-                  a_call_name(list,'FPC_RANGEERROR',0);
+                  a_call_name(list,'FPC_RANGEERROR');
                   exit
                 end;
               { from is signed and to is unsigned -> when looking at from }
@@ -1595,7 +1018,7 @@ unit cgobj;
               if (lfrom > awordsignedmax) or
                  (hto < 0) then
                 begin
-                  a_call_name(list,'FPC_RANGEERROR',0);
+                  a_call_name(list,'FPC_RANGEERROR');
                   exit
                 end;
               { from is unsigned and to is signed -> when looking at to }
@@ -1619,7 +1042,7 @@ unit cgobj;
         a_cmp_const_reg_label(list,OS_INT,OC_BE,aword(longint((hto-lto) and $ffffffff)),hreg,neglabel);
         { !!! should happen right after the compare (JM) }
         free_scratch_reg(list,hreg);
-        a_call_name(list,'FPC_RANGEERROR',0);
+        a_call_name(list,'FPC_RANGEERROR');
         a_label(list,neglabel);
       end;
 
@@ -1628,17 +1051,52 @@ unit cgobj;
 
       begin
          a_param_const(list,OS_32,stackframesize,1);
-         a_call_name(list,'FPC_STACKCHECK',0);
+         a_call_name(list,'FPC_STACKCHECK');
       end;
 
 
+{*****************************************************************************
+                            Entry/Exit Code Functions
+*****************************************************************************}
+
+    procedure tcg.g_interrupt_stackframe_entry(list : taasmoutput);
+      begin
+      end;
+
+
+    procedure tcg.g_interrupt_stackframe_exit(list : taasmoutput;selfused,accused,acchiused:boolean);
+      begin
+      end;
+
+
+    procedure tcg.g_profilecode(list : taasmoutput);
+      begin
+      end;
+
 
 finalization
   cg.free;
 end.
 {
   $Log$
-  Revision 1.19  2002-04-26 15:19:04  peter
+  Revision 1.20  2002-05-12 16:53:04  peter
+    * moved entry and exitcode to ncgutil and cgobj
+    * foreach gets extra argument for passing local data to the
+      iterator function
+    * -CR checks also class typecasts at runtime by changing them
+      into as
+    * fixed compiler to cycle with the -CR option
+    * fixed stabs with elf writer, finally the global variables can
+      be watched
+    * removed a lot of routines from cga unit and replaced them by
+      calls to cgobj
+    * u32bit-s32bit updates for and,or,xor nodes. When one element is
+      u32bit then the other is typecasted also to u32bit without giving
+      a rangecheck warning/error.
+    * fixed pascal calling method with reversing also the high tree in
+      the parast, detected by tcalcst3 test
+
+  Revision 1.19  2002/04/26 15:19:04  peter
     * use saveregisters for incr routines, saves also problems with
       the optimizer
 
@@ -1766,5 +1224,4 @@ end.
 
   Revision 1.1  2000/07/13 06:30:07  michael
     + Initial import
-
 }

+ 19 - 2
compiler/compiler.pas

@@ -121,7 +121,7 @@ function Compile(const cmd:string):longint;
 implementation
 
 uses
-  cpubase,cpuasm;
+  cpuasm;
 
 var
   CompilerInitedAfterArgs,
@@ -337,7 +337,24 @@ end;
 end.
 {
   $Log$
-  Revision 1.25  2002-04-15 19:53:54  peter
+  Revision 1.26  2002-05-12 16:53:05  peter
+    * moved entry and exitcode to ncgutil and cgobj
+    * foreach gets extra argument for passing local data to the
+      iterator function
+    * -CR checks also class typecasts at runtime by changing them
+      into as
+    * fixed compiler to cycle with the -CR option
+    * fixed stabs with elf writer, finally the global variables can
+      be watched
+    * removed a lot of routines from cga unit and replaced them by
+      calls to cgobj
+    * u32bit-s32bit updates for and,or,xor nodes. When one element is
+      u32bit then the other is typecasted also to u32bit without giving
+      a rangecheck warning/error.
+    * fixed pascal calling method with reversing also the high tree in
+      the parast, detected by tcalcst3 test
+
+  Revision 1.25  2002/04/15 19:53:54  peter
     * fixed conflicts between the last 2 commits
 
   Revision 1.24  2002/04/15 18:56:42  carl

+ 21 - 4
compiler/fppu.pas

@@ -58,7 +58,7 @@ interface
           procedure load_interface;
           procedure load_symtable_refs;
           procedure load_usedunits;
-          procedure writeusedmacro(p:TNamedIndexItem);
+          procedure writeusedmacro(p:TNamedIndexItem;arg:pointer);
           procedure writeusedmacros;
           procedure writesourcefiles;
           procedure writeusedunit;
@@ -345,7 +345,7 @@ uses
     PPU Reading/Writing Helpers
 ***********************************}
 
-    procedure tppumodule.writeusedmacro(p:TNamedIndexItem);
+    procedure tppumodule.writeusedmacro(p:TNamedIndexItem;arg:pointer);
       begin
         if tmacro(p).is_used or tmacro(p).defined_at_startup then
           begin
@@ -359,7 +359,7 @@ uses
     procedure tppumodule.writeusedmacros;
       begin
         ppufile.do_crc:=false;
-        current_scanner.macros.foreach({$ifdef FPCPROCVAR}@{$endif}writeusedmacro);
+        current_scanner.macros.foreach({$ifdef FPCPROCVAR}@{$endif}writeusedmacro,nil);
         ppufile.writeentry(ibusedmacros);
         ppufile.do_crc:=true;
       end;
@@ -1173,7 +1173,24 @@ uses
 end.
 {
   $Log$
-  Revision 1.13  2002-04-04 19:05:56  peter
+  Revision 1.14  2002-05-12 16:53:05  peter
+    * moved entry and exitcode to ncgutil and cgobj
+    * foreach gets extra argument for passing local data to the
+      iterator function
+    * -CR checks also class typecasts at runtime by changing them
+      into as
+    * fixed compiler to cycle with the -CR option
+    * fixed stabs with elf writer, finally the global variables can
+      be watched
+    * removed a lot of routines from cga unit and replaced them by
+      calls to cgobj
+    * u32bit-s32bit updates for and,or,xor nodes. When one element is
+      u32bit then the other is typecasted also to u32bit without giving
+      a rangecheck warning/error.
+    * fixed pascal calling method with reversing also the high tree in
+      the parast, detected by tcalcst3 test
+
+  Revision 1.13  2002/04/04 19:05:56  peter
     * removed unused units
     * use tlocation.size in cg.a_*loc*() routines
 

+ 22 - 3
compiler/globtype.pas

@@ -79,7 +79,7 @@ interface
        { Switches which can be changed locally }
        tlocalswitch = (cs_localnone,
          { codegen }
-         cs_check_overflow,cs_check_range,cs_check_object_ext,
+         cs_check_overflow,cs_check_range,cs_check_object,
          cs_check_io,cs_check_stack,
          cs_omitstackframe,cs_do_assertion,cs_generate_rtti,
          cs_full_boolean_eval,cs_typed_const_writable,
@@ -119,7 +119,8 @@ interface
          { browser }
          cs_browser_log,
          { debugger }
-         cs_gdb_dbx,cs_gdb_gsym,cs_gdb_heaptrc,cs_gdb_lineinfo,cs_checkpointer,
+         cs_gdb_dbx,cs_gdb_gsym,cs_gdb_heaptrc,cs_gdb_lineinfo,
+         cs_checkpointer,
          { assembling }
          cs_asm_leave,cs_asm_extern,cs_asm_pipe,cs_asm_source,
          cs_asm_regalloc,cs_asm_tempalloc,cs_asm_nodes,
@@ -214,6 +215,7 @@ interface
        tnormalset = set of byte; { 256 elements set }
        pnormalset = ^tnormalset;
 
+       pboolean   = ^boolean;
        pdouble    = ^double;
        pbyte      = ^byte;
        pword      = ^word;
@@ -253,7 +255,24 @@ implementation
 end.
 {
   $Log$
-  Revision 1.22  2002-04-21 19:02:03  peter
+  Revision 1.23  2002-05-12 16:53:05  peter
+    * moved entry and exitcode to ncgutil and cgobj
+    * foreach gets extra argument for passing local data to the
+      iterator function
+    * -CR checks also class typecasts at runtime by changing them
+      into as
+    * fixed compiler to cycle with the -CR option
+    * fixed stabs with elf writer, finally the global variables can
+      be watched
+    * removed a lot of routines from cga unit and replaced them by
+      calls to cgobj
+    * u32bit-s32bit updates for and,or,xor nodes. When one element is
+      u32bit then the other is typecasted also to u32bit without giving
+      a rangecheck warning/error.
+    * fixed pascal calling method with reversing also the high tree in
+      the parast, detected by tcalcst3 test
+
+  Revision 1.22  2002/04/21 19:02:03  peter
     * removed newn and disposen nodes, the code is now directly
       inlined from pexpr
     * -an option that will write the secondpass nodes to the .s file, this

+ 23 - 20
compiler/i386/ag386att.pas

@@ -39,10 +39,10 @@ interface
 
     TAttSuffix = (AttSufNONE,AttSufINT,AttSufFPU,AttSufFPUint);
 
-    const      
+    const
       gas_op2str:op2strtable={$i i386att.inc}
       gas_needsuffix:array[tasmop] of TAttSuffix={$i i386atts.inc}
-      
+
       gas_reg2str : reg2strtable = ('',
         '%eax','%ecx','%edx','%ebx','%esp','%ebp','%esi','%edi',
         '%ax','%cx','%dx','%bx','%sp','%bp','%si','%di',
@@ -55,7 +55,7 @@ interface
         '%mm0','%mm1','%mm2','%mm3','%mm4','%mm5','%mm6','%mm7',
         '%xmm0','%xmm1','%xmm2','%xmm3','%xmm4','%xmm5','%xmm6','%xmm7'
        );
-      
+
      gas_opsize2str : array[topsize] of string[2] = ('',
        'b','w','l','bw','bl','wl',
        's','l','q',
@@ -66,22 +66,8 @@ interface
   implementation
 
     uses
-{$ifdef Delphi}
-      dmisc,
-{$else Delphi}
-      dos,
-{$endif Delphi}
-      cutils,globtype,systems,
-      fmodule,finput,verbose,cpuasm,tainst
-{$ifdef GDB}
-  {$ifdef delphi}
-      ,sysutils
-  {$else}
-      ,strings
-  {$endif}
-      ,gdb
-{$endif GDB}
-      ;
+      cutils,systems,
+      verbose,cpuasm;
 
 
 
@@ -352,7 +338,24 @@ initialization
 end.
 {
   $Log$
-  Revision 1.18  2002-04-15 19:12:10  carl
+  Revision 1.19  2002-05-12 16:53:16  peter
+    * moved entry and exitcode to ncgutil and cgobj
+    * foreach gets extra argument for passing local data to the
+      iterator function
+    * -CR checks also class typecasts at runtime by changing them
+      into as
+    * fixed compiler to cycle with the -CR option
+    * fixed stabs with elf writer, finally the global variables can
+      be watched
+    * removed a lot of routines from cga unit and replaced them by
+      calls to cgobj
+    * u32bit-s32bit updates for and,or,xor nodes. When one element is
+      u32bit then the other is typecasted also to u32bit without giving
+      a rangecheck warning/error.
+    * fixed pascal calling method with reversing also the high tree in
+      the parast, detected by tcalcst3 test
+
+  Revision 1.18  2002/04/15 19:12:10  carl
   + target_info.size_of_pointer -> pointer_size
   + some cleanup of unused types/variables
   * move several constants from cpubase to their specific units

+ 22 - 5
compiler/i386/ag386int.pas

@@ -35,9 +35,9 @@ interface
         Function  DoAssemble:boolean;override;
         procedure WriteExternals;
       end;
-      
 
-      
+
+
 
   implementation
 
@@ -691,7 +691,7 @@ ait_stab_function_name : ;
     var
       currentasmlist : TExternalAssembler;
 
-    procedure writeexternal(p:tnamedindexitem);
+    procedure writeexternal(p:tnamedindexitem;arg:pointer);
       begin
         if tasmsymbol(p).defbind=AB_EXTERNAL then
           begin
@@ -706,7 +706,7 @@ ait_stab_function_name : ;
     procedure T386IntelAssembler.WriteExternals;
       begin
         currentasmlist:=self;
-        AsmSymbolList.foreach_static({$ifdef fpcprocvar}@{$endif}writeexternal);
+        AsmSymbolList.foreach_static({$ifdef fpcprocvar}@{$endif}writeexternal,nil);
       end;
 
 
@@ -824,7 +824,24 @@ initialization
 end.
 {
   $Log$
-  Revision 1.17  2002-04-15 19:12:09  carl
+  Revision 1.18  2002-05-12 16:53:16  peter
+    * moved entry and exitcode to ncgutil and cgobj
+    * foreach gets extra argument for passing local data to the
+      iterator function
+    * -CR checks also class typecasts at runtime by changing them
+      into as
+    * fixed compiler to cycle with the -CR option
+    * fixed stabs with elf writer, finally the global variables can
+      be watched
+    * removed a lot of routines from cga unit and replaced them by
+      calls to cgobj
+    * u32bit-s32bit updates for and,or,xor nodes. When one element is
+      u32bit then the other is typecasted also to u32bit without giving
+      a rangecheck warning/error.
+    * fixed pascal calling method with reversing also the high tree in
+      the parast, detected by tcalcst3 test
+
+  Revision 1.17  2002/04/15 19:12:09  carl
   + target_info.size_of_pointer -> pointer_size
   + some cleanup of unused types/variables
   * move several constants from cpubase to their specific units

+ 25 - 8
compiler/i386/ag386nsm.pas

@@ -35,8 +35,8 @@ interface
         procedure WriteAsmList;override;
         procedure WriteExternals;
       end;
-      
-      
+
+
 
   implementation
 
@@ -727,7 +727,7 @@ interface
     var
       currentasmlist : TExternalAssembler;
 
-    procedure writeexternal(p:tnamedindexitem);
+    procedure writeexternal(p:tnamedindexitem;arg:pointer);
       begin
         if tasmsymbol(p).defbind=AB_EXTERNAL then
          currentasmlist.AsmWriteln('EXTERN'#9+p.name);
@@ -736,7 +736,7 @@ interface
     procedure T386NasmAssembler.WriteExternals;
       begin
         currentasmlist:=self;
-        AsmSymbolList.foreach_static({$ifdef fpcprocvar}@{$endif}writeexternal);
+        AsmSymbolList.foreach_static({$ifdef fpcprocvar}@{$endif}writeexternal,nil);
       end;
 
 
@@ -846,7 +846,7 @@ interface
               '.idata2','.idata4','.idata5','.idata6','.idata7','.edata',
               '.stab','.stabstr')
           );
-          
+
        as_i386_nasmwdosx_info : tasminfo =
           (
             id           : as_i386_nasmwdosx;
@@ -866,7 +866,7 @@ interface
               '.idata2','.idata4','.idata5','.idata6','.idata7','.edata',
               '.stab','.stabstr')
           );
-          
+
 
        as_i386_nasmelf_info : tasminfo =
           (
@@ -892,13 +892,30 @@ interface
 initialization
   RegisterAssembler(as_i386_nasmcoff_info,T386NasmAssembler);
   RegisterAssembler(as_i386_nasmwin32_info,T386NasmAssembler);
-  RegisterAssembler(as_i386_nasmwdosx_info,T386NasmAssembler); 
+  RegisterAssembler(as_i386_nasmwdosx_info,T386NasmAssembler);
   RegisterAssembler(as_i386_nasmobj_info,T386NasmAssembler);
   RegisterAssembler(as_i386_nasmelf_info,T386NasmAssembler);
 end.
 {
   $Log$
-  Revision 1.16  2002-04-15 19:12:09  carl
+  Revision 1.17  2002-05-12 16:53:16  peter
+    * moved entry and exitcode to ncgutil and cgobj
+    * foreach gets extra argument for passing local data to the
+      iterator function
+    * -CR checks also class typecasts at runtime by changing them
+      into as
+    * fixed compiler to cycle with the -CR option
+    * fixed stabs with elf writer, finally the global variables can
+      be watched
+    * removed a lot of routines from cga unit and replaced them by
+      calls to cgobj
+    * u32bit-s32bit updates for and,or,xor nodes. When one element is
+      u32bit then the other is typecasted also to u32bit without giving
+      a rangecheck warning/error.
+    * fixed pascal calling method with reversing also the high tree in
+      the parast, detected by tcalcst3 test
+
+  Revision 1.16  2002/04/15 19:12:09  carl
   + target_info.size_of_pointer -> pointer_size
   + some cleanup of unused types/variables
   * move several constants from cpubase to their specific units

+ 18 - 1766
compiler/i386/cga.pas

@@ -37,7 +37,6 @@ interface
     function def_opsize(p1:tdef):topsize;
     function def_getreg(p1:tdef):tregister;
 
-    procedure emitlab(var l : tasmlabel);
     procedure emitjmp(c : tasmcond;var l : tasmlabel);
 
     procedure emit_none(i : tasmop;s : topsize);
@@ -57,49 +56,6 @@ interface
 
 
     procedure emit_sym(i : tasmop;s : topsize;op : tasmsymbol);
-    procedure emit_sym_ofs(i : tasmop;s : topsize;op : tasmsymbol;ofs : longint);
-    procedure emit_sym_ofs_reg(i : tasmop;s : topsize;op : tasmsymbol;ofs:longint;reg : tregister);
-
-    procedure emitcall(const routine:string);
-
-    { remove non regvar registers in loc from regs (in the format }
-    { pushusedregisters uses)                                     }
-    procedure remove_non_regvars_from_loc(const t: tlocation; var regs: tregisterset);
-
-    procedure push_int(l : longint);
-    procedure emit_push_mem(const ref : treference);
-    procedure emitpushreferenceaddr(const ref : treference);
-
-    procedure maybe_loadself;
-    procedure emitloadord2reg(const location:Tlocation;orddef:torddef;destreg:Tregister;delloc:boolean);
-    procedure concatcopy(source,dest : treference;size : longint;delsource : boolean;loadref:boolean);
-
-    procedure genentrycode(alist : TAAsmoutput;make_global:boolean;
-                           stackframe:longint;
-                           var parasize:longint;var nostackframe:boolean;
-                           inlined : boolean);
-    procedure genexitcode(alist : TAAsmoutput;parasize:longint;
-                          nostackframe,inlined:boolean);
-
-    { if a unit doesn't have a explicit init/final code,  }
-    { we've to generate one, if the units has ansistrings }
-    { in the interface or implementation                  }
-    procedure genimplicitunitfinal(alist : TAAsmoutput);
-    procedure genimplicitunitinit(alist : TAAsmoutput);
-{$ifdef test_dest_loc}
-
-const
-  { used to avoid temporary assignments }
-  dest_loc_known : boolean = false;
-  in_dest_loc    : boolean = false;
-  dest_loc_tree  : ptree = nil;
-
-var
-  dest_loc : tlocation;
-
-procedure mov_reg_to_dest(p : ptree; s : topsize; reg : tregister);
-
-{$endif test_dest_loc}
 
 
 implementation
@@ -128,10 +84,6 @@ implementation
  {$define __NOWINPECOFF__}
 {$endif}
 
-{$ifndef __NOWINPECOFF__}
-  const
-     winstackpagesize = 4096;
-{$endif}
 
 
 {*****************************************************************************
@@ -162,14 +114,6 @@ implementation
                               Emit Assembler
 *****************************************************************************}
 
-    procedure emitlab(var l : tasmlabel);
-      begin
-         if not l.is_set then
-          exprasmList.concat(Tai_label.Create(l))
-         else
-          internalerror(7453984);
-      end;
-
     procedure emitjmp(c : tasmcond;var l : tasmlabel);
       var
         ai : taicpu;
@@ -247,1719 +191,27 @@ implementation
         exprasmList.concat(Taicpu.Op_sym(i,s,op));
       end;
 
-    procedure emit_sym_ofs(i : tasmop;s : topsize;op : tasmsymbol;ofs : longint);
-      begin
-        exprasmList.concat(Taicpu.Op_sym_ofs(i,s,op,ofs));
-      end;
-
-    procedure emit_sym_ofs_reg(i : tasmop;s : topsize;op : tasmsymbol;ofs:longint;reg : tregister);
-      begin
-        exprasmList.concat(Taicpu.Op_sym_ofs_reg(i,s,op,ofs,reg));
-      end;
-
-    procedure emitcall(const routine:string);
-      begin
-        exprasmList.concat(Taicpu.Op_sym(A_CALL,S_NO,newasmsymbol(routine)));
-      end;
-
-    { only usefull in startup code }
-    procedure emitinsertcall(const routine:string);
-      begin
-        exprasmList.insert(Taicpu.Op_sym(A_CALL,S_NO,newasmsymbol(routine)));
-      end;
-
-
-    procedure remove_non_regvars_from_loc(const t: tlocation; var regs: tregisterset);
-    begin
-      case t.loc of
-        LOC_REGISTER:
-          begin
-            { can't be a regvar, since it would be LOC_CREGISTER then }
-            exclude(regs,t.register);
-            if t.registerhigh <> R_NO then
-              exclude(regs,t.registerhigh);
-          end;
-        LOC_CREFERENCE,LOC_REFERENCE:
-          begin
-            if not(cs_regalloc in aktglobalswitches) or
-               (t.reference.base in rg.usableregsint) then
-              exclude(regs,t.reference.base);
-            if not(cs_regalloc in aktglobalswitches) or
-               (t.reference.index in rg.usableregsint) then
-            exclude(regs,t.reference.index);
-          end;
-      end;
-    end;
-
-
-
-{*****************************************************************************
-                           Emit Push Functions
-*****************************************************************************}
-
-    procedure push_int(l : longint);
-      begin
-         if (l = 0) and
-            not(aktoptprocessor in [Class386, ClassP6]) and
-            not(cs_littlesize in aktglobalswitches)
-           Then
-             begin
-               rg.getexplicitregisterint(exprasmlist,R_EDI);
-               emit_reg_reg(A_XOR,S_L,R_EDI,R_EDI);
-               exprasmList.concat(Taicpu.Op_reg(A_PUSH,S_L,R_EDI));
-               rg.ungetregisterint(exprasmlist,R_EDI);
-             end
-           else
-             exprasmList.concat(Taicpu.Op_const(A_PUSH,S_L,aword(l)));
-      end;
-
-    procedure emit_push_mem(const ref : treference);
-
-      begin
-             if not(aktoptprocessor in [Class386, ClassP6]) and
-                not(cs_littlesize in aktglobalswitches)
-               then
-                 begin
-                   rg.getexplicitregisterint(exprasmlist,R_EDI);
-                   emit_ref_reg(A_MOV,S_L,ref,R_EDI);
-                   exprasmList.concat(Taicpu.Op_reg(A_PUSH,S_L,R_EDI));
-                   rg.ungetregisterint(exprasmlist,R_EDI);
-                 end
-               else exprasmList.concat(Taicpu.Op_ref(A_PUSH,S_L,ref));
-      end;
-
-
-    procedure emitpushreferenceaddr(const ref : treference);
-      begin
-              if ref.segment<>R_NO then
-                CGMessage(cg_e_cant_use_far_pointer_there);
-              if (ref.base=R_NO) and (ref.index=R_NO) then
-                exprasmList.concat(Taicpu.Op_sym_ofs(A_PUSH,S_L,ref.symbol,ref.offset))
-              else if (ref.base=R_NO) and (ref.index<>R_NO) and
-                 (ref.offset=0) and (ref.scalefactor=0) and (ref.symbol=nil) then
-                exprasmList.concat(Taicpu.Op_reg(A_PUSH,S_L,ref.index))
-              else if (ref.base<>R_NO) and (ref.index=R_NO) and
-                 (ref.offset=0) and (ref.symbol=nil) then
-                exprasmList.concat(Taicpu.Op_reg(A_PUSH,S_L,ref.base))
-              else
-                begin
-                   rg.getexplicitregisterint(exprasmlist,R_EDI);
-                   emit_ref_reg(A_LEA,S_L,ref,R_EDI);
-                   exprasmList.concat(Taicpu.Op_reg(A_PUSH,S_L,R_EDI));
-                   rg.ungetregisterint(exprasmlist,R_EDI);
-                end;
-        end;
-
-
-{*****************************************************************************
-                           Emit Functions
-*****************************************************************************}
-
-    procedure concatcopy(source,dest : treference;size : longint;delsource,loadref : boolean);
-
-      {const
-         isizes : array[0..3] of topsize=(S_L,S_B,S_W,S_B);
-         ishr : array[0..3] of byte=(2,0,1,0);}
-
-      var
-         ecxpushed : boolean;
-         oldsourceoffset,
-         helpsize : longint;
-         i : byte;
-         reg8,reg32 : tregister;
-         swap : boolean;
-
-         procedure maybepushecx;
-         begin
-           if not(R_ECX in rg.unusedregsint) then
-             begin
-               exprasmList.concat(Taicpu.Op_reg(A_PUSH,S_L,R_ECX));
-               ecxpushed:=true;
-             end
-           else rg.getexplicitregisterint(exprasmlist,R_ECX);
-         end;
-
-      begin
-         oldsourceoffset:=source.offset;
-         if (not loadref) and
-            ((size<=8) or
-             (not(cs_littlesize in aktglobalswitches ) and (size<=12))) then
-           begin
-              helpsize:=size shr 2;
-              rg.getexplicitregisterint(exprasmlist,R_EDI);
-              for i:=1 to helpsize do
-                begin
-                   emit_ref_reg(A_MOV,S_L,source,R_EDI);
-                   If (size = 4) and delsource then
-                     reference_release(exprasmlist,source);
-                   exprasmList.concat(Taicpu.Op_reg_ref(A_MOV,S_L,R_EDI,dest));
-                   inc(source.offset,4);
-                   inc(dest.offset,4);
-                   dec(size,4);
-                end;
-              if size>1 then
-                begin
-                   emit_ref_reg(A_MOV,S_W,source,R_DI);
-                   If (size = 2) and delsource then
-                     reference_release(exprasmlist,source);
-                   exprasmList.concat(Taicpu.Op_reg_ref(A_MOV,S_W,R_DI,dest));
-                   inc(source.offset,2);
-                   inc(dest.offset,2);
-                   dec(size,2);
-                end;
-              rg.ungetregisterint(exprasmlist,R_EDI);
-              if size>0 then
-                begin
-                   { and now look for an 8 bit register }
-                   swap:=false;
-                   if R_EAX in rg.unusedregsint then reg8:=rg.makeregsize(rg.getexplicitregisterint(exprasmlist,R_EAX),OS_8)
-                   else if R_EDX in rg.unusedregsint then reg8:=rg.makeregsize(rg.getexplicitregisterint(exprasmlist,R_EDX),OS_8)
-                   else if R_EBX in rg.unusedregsint then reg8:=rg.makeregsize(rg.getexplicitregisterint(exprasmlist,R_EBX),OS_8)
-                   else if R_ECX in rg.unusedregsint then reg8:=rg.makeregsize(rg.getexplicitregisterint(exprasmlist,R_ECX),OS_8)
-                   else
-                      begin
-                         swap:=true;
-                         { we need only to check 3 registers, because }
-                         { one is always not index or base          }
-                         if (dest.base<>R_EAX) and (dest.index<>R_EAX) then
-                           begin
-                              reg8:=R_AL;
-                              reg32:=R_EAX;
-                           end
-                         else if (dest.base<>R_EBX) and (dest.index<>R_EBX) then
-                           begin
-                              reg8:=R_BL;
-                              reg32:=R_EBX;
-                           end
-                         else if (dest.base<>R_ECX) and (dest.index<>R_ECX) then
-                           begin
-                              reg8:=R_CL;
-                              reg32:=R_ECX;
-                           end;
-                      end;
-                   if swap then
-                     { was earlier XCHG, of course nonsense }
-                     begin
-                       rg.getexplicitregisterint(exprasmlist,R_EDI);
-                       emit_reg_reg(A_MOV,S_L,reg32,R_EDI);
-                     end;
-                   emit_ref_reg(A_MOV,S_B,source,reg8);
-                   If delsource then
-                     reference_release(exprasmlist,source);
-                   exprasmList.concat(Taicpu.Op_reg_ref(A_MOV,S_B,reg8,dest));
-                   if swap then
-                     begin
-                       emit_reg_reg(A_MOV,S_L,R_EDI,reg32);
-                       rg.ungetregisterint(exprasmlist,R_EDI);
-                     end
-                   else
-                     rg.ungetregister(exprasmlist,reg8);
-                end;
-           end
-         else
-           begin
-              rg.getexplicitregisterint(exprasmlist,R_EDI);
-              emit_ref_reg(A_LEA,S_L,dest,R_EDI);
-              exprasmList.concat(Tairegalloc.Alloc(R_ESI));
-              if loadref then
-                emit_ref_reg(A_MOV,S_L,source,R_ESI)
-              else
-                begin
-                  emit_ref_reg(A_LEA,S_L,source,R_ESI);
-                  if delsource then
-                    reference_release(exprasmlist,source);
-                end;
-
-              exprasmList.concat(Taicpu.Op_none(A_CLD,S_NO));
-              ecxpushed:=false;
-              if cs_littlesize in aktglobalswitches  then
-                begin
-                   maybepushecx;
-                   emit_const_reg(A_MOV,S_L,size,R_ECX);
-                   exprasmList.concat(Taicpu.Op_none(A_REP,S_NO));
-                   exprasmList.concat(Taicpu.Op_none(A_MOVSB,S_NO));
-                end
-              else
-                begin
-                   helpsize:=size shr 2;
-                   size:=size and 3;
-                   if helpsize>1 then
-                    begin
-                      maybepushecx;
-                      emit_const_reg(A_MOV,S_L,helpsize,R_ECX);
-                      exprasmList.concat(Taicpu.Op_none(A_REP,S_NO));
-                    end;
-                   if helpsize>0 then
-                    exprasmList.concat(Taicpu.Op_none(A_MOVSD,S_NO));
-                   if size>1 then
-                     begin
-                        dec(size,2);
-                        exprasmList.concat(Taicpu.Op_none(A_MOVSW,S_NO));
-                     end;
-                   if size=1 then
-                     exprasmList.concat(Taicpu.Op_none(A_MOVSB,S_NO));
-                end;
-              rg.ungetregisterint(exprasmlist,R_EDI);
-              exprasmList.concat(Tairegalloc.DeAlloc(R_ESI));
-              if ecxpushed then
-                exprasmList.concat(Taicpu.Op_reg(A_POP,S_L,R_ECX))
-              else
-                rg.ungetregisterint(exprasmlist,R_ECX);
-
-              { loading SELF-reference again }
-              maybe_loadself;
-           end;
-         if delsource then
-           begin
-             source.offset:=oldsourceoffset;
-             tg.ungetiftemp(exprasmlist,source);
-           end;
-      end;
-
-
-    procedure emitloadord2reg(const location:Tlocation;orddef:torddef;
-                              destreg:Tregister;delloc:boolean);
-
-    {A lot smaller and less bug sensitive than the original unfolded loads.}
-
-    var tai:Taicpu;
-
-    begin
-        tai := nil;
-        case location.loc of
-            LOC_REGISTER,LOC_CREGISTER:
-                begin
-                    case orddef.typ of
-                        u8bit,uchar,bool8bit:
-                            tai:=Taicpu.Op_reg_reg(A_MOVZX,S_BL,location.register,destreg);
-                        s8bit:
-                            tai:=Taicpu.Op_reg_reg(A_MOVSX,S_BL,location.register,destreg);
-                        u16bit,uwidechar,bool16bit:
-                            tai:=Taicpu.Op_reg_reg(A_MOVZX,S_WL,location.register,destreg);
-                        s16bit:
-                            tai:=Taicpu.Op_reg_reg(A_MOVSX,S_WL,location.register,destreg);
-                        u32bit,bool32bit,s32bit:
-                            if location.register <> destreg then
-                              tai:=Taicpu.Op_reg_reg(A_MOV,S_L,location.register,destreg);
-                        else
-                          internalerror(330);
-                    end;
-                    if delloc then
-                        rg.ungetregister(exprasmlist,location.register);
-                end;
-            LOC_CONSTANT:
-                begin
-                  tai:=Taicpu.Op_const_reg(A_MOV,S_L,location.value,destreg)
-                end;
-            LOC_CREFERENCE,
-            LOC_REFERENCE:
-                begin
-                       case orddef.typ of
-                         u8bit,uchar,bool8bit:
-                            tai:=Taicpu.Op_ref_reg(A_MOVZX,S_BL,location.reference,destreg);
-                         s8bit:
-                            tai:=Taicpu.Op_ref_reg(A_MOVSX,S_BL,location.reference,destreg);
-                         u16bit,uwidechar,bool16bit:
-                            tai:=Taicpu.Op_ref_reg(A_MOVZX,S_WL,location.reference,destreg);
-                         s16bit:
-                            tai:=Taicpu.Op_ref_reg(A_MOVSX,S_WL,location.reference,destreg);
-                         u32bit,bool32bit:
-                            tai:=Taicpu.Op_ref_reg(A_MOV,S_L,location.reference,destreg);
-                         s32bit:
-                            tai:=Taicpu.Op_ref_reg(A_MOV,S_L,location.reference,destreg);
-                         else
-                           internalerror(330);
-                     end;
-                    if delloc then
-                        reference_release(exprasmlist,location.reference);
-                end
-            else
-                internalerror(6);
-        end;
-        if assigned(tai) then
-          exprasmList.concat(tai);
-    end;
-
-    { if necessary ESI is reloaded after a call}
-    procedure maybe_loadself;
-
-      var
-         hp : treference;
-         p : pprocinfo;
-         i : longint;
-
-      begin
-         if assigned(procinfo^._class) then
-           begin
-              exprasmList.concat(Tairegalloc.Alloc(R_ESI));
-              if lexlevel>normal_function_level then
-                begin
-                   reference_reset_base(hp,procinfo^.framepointer,procinfo^.framepointer_offset);
-                   emit_ref_reg(A_MOV,S_L,hp,R_ESI);
-                   p:=procinfo^.parent;
-                   for i:=3 to lexlevel-1 do
-                     begin
-                        reference_reset_base(hp,R_ESI,p^.framepointer_offset);
-                        emit_ref_reg(A_MOV,S_L,hp,R_ESI);
-                        p:=p^.parent;
-                     end;
-                   reference_reset_base(hp,R_ESI,p^.selfpointer_offset);
-                   emit_ref_reg(A_MOV,S_L,hp,R_ESI);
-                end
-              else
-                begin
-                   reference_reset_base(hp,procinfo^.framepointer,procinfo^.selfpointer_offset);
-                   emit_ref_reg(A_MOV,S_L,hp,R_ESI);
-                end;
-           end;
-      end;
-
-
-{*****************************************************************************
-                            Entry/Exit Code Functions
-*****************************************************************************}
-
-  procedure genprofilecode;
-    var
-      pl : tasmlabel;
-    begin
-      if (po_assembler in aktprocdef.procoptions) then
-       exit;
-      case target_info.target of
-         target_i386_win32,
-         target_i386_freebsd,
-         target_i386_wdosx,
-         target_i386_linux:
-           begin
-              getaddrlabel(pl);
-              emitinsertcall(target_info.Cprefix+'mcount');
-              include(rg.usedinproc,R_EDX);
-              exprasmList.insert(Taicpu.Op_sym_ofs_reg(A_MOV,S_L,pl,0,R_EDX));
-              exprasmList.insert(Tai_section.Create(sec_code));
-              exprasmList.insert(Tai_const.Create_32bit(0));
-              exprasmList.insert(Tai_label.Create(pl));
-              exprasmList.insert(Tai_align.Create(4));
-              exprasmList.insert(Tai_section.Create(sec_data));
-           end;
-
-         target_i386_go32v2:
-           begin
-              emitinsertcall('MCOUNT');
-           end;
-      end;
-    end;
-
-
-    procedure generate_interrupt_stackframe_entry;
-      begin
-         { save the registers of an interrupt procedure }
-         exprasmList.insert(Taicpu.Op_reg(A_PUSH,S_L,R_EAX));
-         exprasmList.insert(Taicpu.Op_reg(A_PUSH,S_L,R_EBX));
-         exprasmList.insert(Taicpu.Op_reg(A_PUSH,S_L,R_ECX));
-         exprasmList.insert(Taicpu.Op_reg(A_PUSH,S_L,R_EDX));
-         exprasmList.insert(Taicpu.Op_reg(A_PUSH,S_L,R_ESI));
-         exprasmList.insert(Taicpu.Op_reg(A_PUSH,S_L,R_EDI));
-
-         { .... also the segment registers }
-         exprasmList.insert(Taicpu.Op_reg(A_PUSH,S_W,R_DS));
-         exprasmList.insert(Taicpu.Op_reg(A_PUSH,S_W,R_ES));
-         exprasmList.insert(Taicpu.Op_reg(A_PUSH,S_W,R_FS));
-         exprasmList.insert(Taicpu.Op_reg(A_PUSH,S_W,R_GS));
-      end;
-
-
-    procedure generate_interrupt_stackframe_exit;
-      begin
-         { restore the registers of an interrupt procedure }
-         { this was all with entrycode instead of exitcode !!}
-         procinfo^.aktexitcode.concat(Taicpu.Op_reg(A_POP,S_L,R_EAX));
-         procinfo^.aktexitcode.concat(Taicpu.Op_reg(A_POP,S_L,R_EBX));
-         procinfo^.aktexitcode.concat(Taicpu.Op_reg(A_POP,S_L,R_ECX));
-         procinfo^.aktexitcode.concat(Taicpu.Op_reg(A_POP,S_L,R_EDX));
-         procinfo^.aktexitcode.concat(Taicpu.Op_reg(A_POP,S_L,R_ESI));
-         procinfo^.aktexitcode.concat(Taicpu.Op_reg(A_POP,S_L,R_EDI));
-
-         { .... also the segment registers }
-         procinfo^.aktexitcode.concat(Taicpu.Op_reg(A_POP,S_W,R_DS));
-         procinfo^.aktexitcode.concat(Taicpu.Op_reg(A_POP,S_W,R_ES));
-         procinfo^.aktexitcode.concat(Taicpu.Op_reg(A_POP,S_W,R_FS));
-         procinfo^.aktexitcode.concat(Taicpu.Op_reg(A_POP,S_W,R_GS));
-
-        { this restores the flags }
-         procinfo^.aktexitcode.concat(Taicpu.Op_none(A_IRET,S_NO));
-      end;
-
-
-  { generates the code for threadvar initialisation }
-  procedure initialize_threadvar(p : tnamedindexitem);
-
-    var
-       hr : treference;
-
-    begin
-       if (tsym(p).typ=varsym) and
-          (vo_is_thread_var in tvarsym(p).varoptions) then
-         begin
-            exprasmList.concat(Taicpu.Op_const(A_PUSH,S_L,tvarsym(p).getsize));
-            reference_reset(hr);
-            hr.symbol:=newasmsymbol(tvarsym(p).mangledname);
-            emitpushreferenceaddr(hr);
-            rg.saveregvars(exprasmlist,all_registers);
-            emitcall('FPC_INIT_THREADVAR');
-         end;
-    end;
-
-
-  { generates the code for initialisation of local data }
-  procedure initialize_data(p : tnamedindexitem);
-
-    var
-       hr : treference;
-
-    begin
-       if (tsym(p).typ=varsym) and
-          assigned(tvarsym(p).vartype.def) and
-          not(is_class(tvarsym(p).vartype.def)) and
-          tvarsym(p).vartype.def.needs_inittable then
-         begin
-            if assigned(procinfo) then
-              procinfo^.flags:=procinfo^.flags or pi_needs_implicit_finally;
-            reference_reset(hr);
-            if tsym(p).owner.symtabletype in [localsymtable,inlinelocalsymtable] then
-              begin
-                 hr.base:=procinfo^.framepointer;
-                 hr.offset:=-tvarsym(p).address+tvarsym(p).owner.address_fixup;
-              end
-            else
-              begin
-                 hr.symbol:=newasmsymbol(tvarsym(p).mangledname);
-              end;
-            cg.g_initialize(exprasmlist,tvarsym(p).vartype.def,hr,false);
-         end;
-    end;
-
-  { generates the code for incrementing the reference count of parameters and
-    initialize out parameters }
-  procedure init_paras(p : tnamedindexitem);
-
-    var
-       hrv : treference;
-       hr: treference;
-
-    begin
-       if (tsym(p).typ=varsym) and
-          not is_class(tvarsym(p).vartype.def) and
-          tvarsym(p).vartype.def.needs_inittable then
-         begin
-           if (tvarsym(p).varspez=vs_value) then
-             begin
-               procinfo^.flags:=procinfo^.flags or pi_needs_implicit_finally;
-
-               reference_reset(hrv);
-               hrv.base:=procinfo^.framepointer;
-               if assigned(tvarsym(p).localvarsym) then
-                hrv.offset:=-tvarsym(p).localvarsym.address+tvarsym(p).localvarsym.owner.address_fixup
-               else
-                hrv.offset:=tvarsym(p).address+procinfo^.para_offset;
-
-               cg.g_incrrefcount(exprasmlist,tvarsym(p).vartype.def,hrv);
-             end
-           else if (tvarsym(p).varspez=vs_out) then
-             begin
-               reference_reset(hrv);
-               hrv.base:=procinfo^.framepointer;
-               hrv.offset:=tvarsym(p).address+procinfo^.para_offset;
-               rg.getexplicitregisterint(exprasmlist,R_EDI);
-               exprasmList.concat(Taicpu.Op_ref_reg(A_MOV,S_L,hrv,R_EDI));
-               reference_reset_base(hr,R_EDI,0);
-               cg.g_initialize(exprasmlist,tvarsym(p).vartype.def,hr,false);
-             end;
-         end;
-    end;
-
-  { generates the code for decrementing the reference count of parameters }
-  procedure final_paras(p : tnamedindexitem);
-    var
-       hrv : treference;
-    begin
-       if (tsym(p).typ=varsym) and
-          not is_class(tvarsym(p).vartype.def) and
-          tvarsym(p).vartype.def.needs_inittable then
-         begin
-           if (tvarsym(p).varspez=vs_value) then
-             begin
-               procinfo^.flags:=procinfo^.flags or pi_needs_implicit_finally;
-
-               reference_reset(hrv);
-               hrv.base:=procinfo^.framepointer;
-               if assigned(tvarsym(p).localvarsym) then
-                hrv.offset:=-tvarsym(p).localvarsym.address+tvarsym(p).localvarsym.owner.address_fixup
-               else
-                hrv.offset:=tvarsym(p).address+procinfo^.para_offset;
-
-               cg.g_decrrefcount(exprasmlist,tvarsym(p).vartype.def,hrv);
-             end;
-         end;
-    end;
-
-
-  { generates the code for finalisation of local data }
-  procedure finalize_data(p : tnamedindexitem);
-
-    var
-       hr : treference;
-
-    begin
-       if (tsym(p).typ=varsym) and
-          assigned(tvarsym(p).vartype.def) and
-          not(is_class(tvarsym(p).vartype.def)) and
-          tvarsym(p).vartype.def.needs_inittable then
-         begin
-            if assigned(procinfo) then
-              procinfo^.flags:=procinfo^.flags or pi_needs_implicit_finally;
-            reference_reset(hr);
-            case tsym(p).owner.symtabletype of
-               localsymtable,inlinelocalsymtable:
-                 begin
-                    hr.base:=procinfo^.framepointer;
-                    hr.offset:=-tvarsym(p).address+tvarsym(p).owner.address_fixup;
-                 end;
-               else
-                 hr.symbol:=newasmsymbol(tvarsym(p).mangledname);
-            end;
-            cg.g_finalize(exprasmlist,tvarsym(p).vartype.def,hr,false);
-         end;
-    end;
-
-
-  { generates the code to make local copies of the value parameters }
-  procedure copyvalueparas(p : tnamedindexitem);
-    var
-      href1,href2 : treference;
-      r    : treference;
-      power,len  : longint;
-      opsize : topsize;
-{$ifndef __NOWINPECOFF__}
-      again,ok : tasmlabel;
-{$endif}
-    begin
-       if (tsym(p).typ=varsym) and
-          (tvarsym(p).varspez=vs_value) and
-          (push_addr_param(tvarsym(p).vartype.def)) then
-        begin
-          if is_open_array(tvarsym(p).vartype.def) or
-             is_array_of_const(tvarsym(p).vartype.def) then
-           begin
-              { get stack space }
-              reference_reset_base(r,procinfo^.framepointer,tvarsym(p).address+4+procinfo^.para_offset);
-              rg.getexplicitregisterint(exprasmlist,R_EDI);
-              exprasmList.concat(Taicpu.op_ref_reg(A_MOV,S_L,r,R_EDI));
-              exprasmList.concat(Taicpu.op_reg(A_INC,S_L,R_EDI));
-              if (tarraydef(tvarsym(p).vartype.def).elesize<>1) then
-               begin
-                 if ispowerof2(tarraydef(tvarsym(p).vartype.def).elesize, power) then
-                   exprasmList.concat(Taicpu.op_const_reg(A_SHL,S_L,power,R_EDI))
-                 else
-                   exprasmList.concat(Taicpu.op_const_reg(A_IMUL,S_L,
-                     tarraydef(tvarsym(p).vartype.def).elesize,R_EDI));
-               end;
-{$ifndef NOTARGETWIN32}
-              { windows guards only a few pages for stack growing, }
-              { so we have to access every page first              }
-              if target_info.target=target_i386_win32 then
-                begin
-                   getlabel(again);
-                   getlabel(ok);
-                   emitlab(again);
-                   exprasmList.concat(Taicpu.op_const_reg(A_CMP,S_L,winstackpagesize,R_EDI));
-                   emitjmp(C_C,ok);
-                   exprasmList.concat(Taicpu.op_const_reg(A_SUB,S_L,winstackpagesize-4,R_ESP));
-                   exprasmList.concat(Taicpu.op_reg(A_PUSH,S_L,R_EAX));
-                   exprasmList.concat(Taicpu.op_const_reg(A_SUB,S_L,winstackpagesize,R_EDI));
-                   emitjmp(C_None,again);
-
-                   emitlab(ok);
-                   exprasmList.concat(Taicpu.op_reg_reg(A_SUB,S_L,R_EDI,R_ESP));
-                   rg.ungetregisterint(exprasmlist,R_EDI);
-                   { now reload EDI }
-                   reference_reset_base(r,procinfo^.framepointer,tvarsym(p).address+4+procinfo^.para_offset);
-                   rg.getexplicitregisterint(exprasmlist,R_EDI);
-                   exprasmList.concat(Taicpu.op_ref_reg(A_MOV,S_L,r,R_EDI));
-
-                   exprasmList.concat(Taicpu.op_reg(A_INC,S_L,R_EDI));
-
-                   if (tarraydef(tvarsym(p).vartype.def).elesize<>1) then
-                    begin
-                      if ispowerof2(tarraydef(tvarsym(p).vartype.def).elesize, power) then
-                        exprasmList.concat(Taicpu.op_const_reg(A_SHL,S_L,power,R_EDI))
-                      else
-                        exprasmList.concat(Taicpu.op_const_reg(A_IMUL,S_L,
-                          tarraydef(tvarsym(p).vartype.def).elesize,R_EDI));
-                    end;
-                end
-              else
-{$endif NOTARGETWIN32}
-                exprasmList.concat(Taicpu.op_reg_reg(A_SUB,S_L,R_EDI,R_ESP));
-              { load destination }
-              exprasmList.concat(Taicpu.op_reg_reg(A_MOV,S_L,R_ESP,R_EDI));
-
-              { don't destroy the registers! }
-              exprasmList.concat(Taicpu.op_reg(A_PUSH,S_L,R_ECX));
-              exprasmList.concat(Taicpu.op_reg(A_PUSH,S_L,R_ESI));
-
-              { load count }
-              reference_reset_base(r,procinfo^.framepointer,tvarsym(p).address+4+procinfo^.para_offset);
-              exprasmList.concat(Taicpu.op_ref_reg(A_MOV,S_L,r,R_ECX));
-
-              { load source }
-              reference_reset_base(r,procinfo^.framepointer,tvarsym(p).address+procinfo^.para_offset);
-              exprasmList.concat(Taicpu.op_ref_reg(A_MOV,S_L,r,R_ESI));
-
-              { scheduled .... }
-              exprasmList.concat(Taicpu.op_reg(A_INC,S_L,R_ECX));
-
-              { calculate size }
-              len:=tarraydef(tvarsym(p).vartype.def).elesize;
-              opsize:=S_B;
-              if (len and 3)=0 then
-               begin
-                 opsize:=S_L;
-                 len:=len shr 2;
-               end
-              else
-               if (len and 1)=0 then
-                begin
-                  opsize:=S_W;
-                  len:=len shr 1;
-                end;
-
-              if ispowerof2(len, power) then
-                exprasmList.concat(Taicpu.op_const_reg(A_SHL,S_L,power,R_ECX))
-              else
-                exprasmList.concat(Taicpu.op_const_reg(A_IMUL,S_L,len,R_ECX));
-              exprasmList.concat(Taicpu.op_none(A_REP,S_NO));
-              case opsize of
-                S_B : exprasmList.concat(Taicpu.Op_none(A_MOVSB,S_NO));
-                S_W : exprasmList.concat(Taicpu.Op_none(A_MOVSW,S_NO));
-                S_L : exprasmList.concat(Taicpu.Op_none(A_MOVSD,S_NO));
-              end;
-              rg.ungetregisterint(exprasmlist,R_EDI);
-              exprasmList.concat(Taicpu.op_reg(A_POP,S_L,R_ESI));
-              exprasmList.concat(Taicpu.op_reg(A_POP,S_L,R_ECX));
-
-              { patch the new address }
-              reference_reset_base(r,procinfo^.framepointer,tvarsym(p).address+procinfo^.para_offset);
-              exprasmList.concat(Taicpu.op_reg_ref(A_MOV,S_L,R_ESP,r));
-           end
-          else
-           if is_shortstring(tvarsym(p).vartype.def) then
-            begin
-              reference_reset_base(href1,procinfo^.framepointer,tvarsym(p).address+procinfo^.para_offset);
-              reference_reset_base(href2,procinfo^.framepointer,-tvarsym(p).localvarsym.address+tvarsym(p).localvarsym.owner.address_fixup);
-              cg.g_copyshortstring(exprasmlist,href1,href2,tstringdef(tvarsym(p).vartype.def).len,false,true);
-            end
-           else
-            begin
-              reference_reset_base(href1,procinfo^.framepointer,tvarsym(p).address+procinfo^.para_offset);
-              reference_reset_base(href2,procinfo^.framepointer,-tvarsym(p).localvarsym.address+tvarsym(p).localvarsym.owner.address_fixup);
-              concatcopy(href1,href2,tvarsym(p).vartype.def.size,true,true);
-            end;
-        end;
-    end;
-
-  procedure inittempvariables;
-
-    var
-       hp : ptemprecord;
-       r : treference;
-
-    begin
-       hp:=tg.templist;
-       while assigned(hp) do
-         begin
-           if hp^.temptype in [tt_ansistring,tt_freeansistring,
-             tt_widestring,tt_freewidestring,
-             tt_interfacecom] then
-             begin
-               procinfo^.flags:=procinfo^.flags or pi_needs_implicit_finally;
-               reference_reset_base(r,procinfo^.framepointer,hp^.pos);
-               emit_const_ref(A_MOV,S_L,0,r);
-             end;
-           hp:=hp^.next;
-         end;
-   end;
-
-  procedure finalizetempvariables;
-
-    var
-       hp : ptemprecord;
-       hr : treference;
-    begin
-       hp:=tg.templist;
-       while assigned(hp) do
-         begin
-            if hp^.temptype in [tt_ansistring,tt_freeansistring] then
-              begin
-                procinfo^.flags:=procinfo^.flags or pi_needs_implicit_finally;
-                reference_reset_base(hr,procinfo^.framepointer,hp^.pos);
-                emitpushreferenceaddr(hr);
-                emitcall('FPC_ANSISTR_DECR_REF');
-              end
-            else if hp^.temptype in [tt_widestring,tt_freewidestring] then
-              begin
-                procinfo^.flags:=procinfo^.flags or pi_needs_implicit_finally;
-                reference_reset_base(hr,procinfo^.framepointer,hp^.pos);
-                emitpushreferenceaddr(hr);
-                emitcall('FPC_WIDESTR_DECR_REF');
-              end
-            else if hp^.temptype=tt_interfacecom then
-              begin
-                procinfo^.flags:=procinfo^.flags or pi_needs_implicit_finally;
-                reference_reset_base(hr,procinfo^.framepointer,hp^.pos);
-                emitpushreferenceaddr(hr);
-                emitcall('FPC_INTF_DECR_REF');
-              end;
-            hp:=hp^.next;
-         end;
-   end;
-
-{$ifdef dummy}
-  var
-     ls : longint;
-
-  procedure largest_size(p : tnamedindexitem);
-
-    begin
-       if (tsym(p).typ=varsym) and
-         (tvarsym(p).getvaluesize>ls) then
-         ls:=tvarsym(p).getvaluesize;
-    end;
-{$endif dummy}
-
-  procedure alignstack(alist : TAAsmoutput);
-
-    begin
-{$ifdef dummy}
-       if (cs_optimize in aktglobalswitches) and
-         (aktoptprocessor in [classp5,classp6]) then
-         begin
-            ls:=0;
-            aktprocdef.localst.foreach({$ifndef TP}@{$endif}largest_size);
-            if ls>=8 then
-              aList.insert(Taicpu.Op_const_reg(A_AND,S_L,aword(-8),R_ESP));
-         end;
-{$endif dummy}
-    end;
-
-  procedure genentrycode(alist : TAAsmoutput;make_global:boolean;
-                         stackframe:longint;
-                         var parasize:longint;var nostackframe:boolean;
-                         inlined : boolean);
-  {
-    Generates the entry code for a procedure
-  }
-    var
-      hs : string;
-{$ifdef GDB}
-      stab_function_name : tai_stab_function_name;
-{$endif GDB}
-      hr : treference;
-      p : tsymtable;
-      r : treference;
-      oldlist,
-      oldexprasmlist : TAAsmoutput;
-      again : tasmlabel;
-      i : longint;
-      tempbuf,tempaddr : treference;
-
-    begin
-       oldexprasmlist:=exprasmlist;
-       exprasmlist:=alist;
-       if (not inlined) and (aktprocdef.proctypeoption=potype_proginit) then
-           begin
-              emitinsertcall('FPC_INITIALIZEUNITS');
-
-              { add global threadvars }
-              oldlist:=exprasmlist;
-              exprasmlist:=TAAsmoutput.Create;
-              p:=symtablestack;
-              while assigned(p) do
-                begin
-                   p.foreach_static({$ifndef TP}@{$endif}initialize_threadvar);
-                   p:=p.next;
-                end;
-              oldList.insertlist(exprasmlist);
-              exprasmlist.free;
-              exprasmlist:=oldlist;
-
-              { add local threadvars in units (only if needed because not all platforms
-                have threadvar support) }
-              if have_local_threadvars then
-                emitinsertcall('FPC_INITIALIZELOCALTHREADVARS');
-
-              { initialize profiling for win32 }
-              if (target_info.target in [target_I386_WIN32,target_I386_wdosx]) and
-                 (cs_profile in aktmoduleswitches) then
-                emitinsertcall('__monstartup');
-           end;
-
-{$ifdef GDB}
-      if (not inlined) and (cs_debuginfo in aktmoduleswitches) then
-        exprasmList.insert(Tai_force_line.Create);
-{$endif GDB}
-
-      { a constructor needs a help procedure }
-      if (aktprocdef.proctypeoption=potype_constructor) then
-        begin
-          if is_class(procinfo^._class) then
-            begin
-              procinfo^.flags:=procinfo^.flags or pi_needs_implicit_finally;
-              exprasmList.insert(Taicpu.Op_cond_sym(A_Jcc,C_Z,S_NO,faillabel));
-              emitinsertcall('FPC_NEW_CLASS');
-            end
-          else if is_object(procinfo^._class) then
-            begin
-              exprasmList.insert(Taicpu.Op_cond_sym(A_Jcc,C_Z,S_NO,faillabel));
-              emitinsertcall('FPC_HELP_CONSTRUCTOR');
-              rg.getexplicitregisterint(exprasmlist,R_EDI);
-              exprasmList.insert(Taicpu.Op_const_reg(A_MOV,S_L,procinfo^._class.vmt_offset,R_EDI));
-            end
-          else
-            Internalerror(200006161);
-        end;
-
-      { 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
-           maybe_loadself;
-
-      { When message method contains self as a parameter,
-        we must load it into ESI }
-      If (po_containsself in aktprocdef.procoptions) then
-        begin
-           reference_reset_base(hr,procinfo^.framepointer,procinfo^.selfpointer_offset);
-           exprasmList.insert(Taicpu.Op_ref_reg(A_MOV,S_L,hr,R_ESI));
-           exprasmList.insert(Tairegalloc.Alloc(R_ESI));
-        end;
-      { should we save edi,esi,ebx like C ? }
-      if (po_savestdregs in aktprocdef.procoptions) then
-       begin
-         if (R_EBX in aktprocdef.usedregisters) then
-           exprasmList.insert(Taicpu.Op_reg(A_PUSH,S_L,R_EBX));
-         exprasmList.insert(Taicpu.Op_reg(A_PUSH,S_L,R_ESI));
-         exprasmList.insert(Taicpu.Op_reg(A_PUSH,S_L,R_EDI));
-       end;
-
-      { for the save all registers we can simply use a pusha,popa which
-        push edi,esi,ebp,esp(ignored),ebx,edx,ecx,eax }
-      if (po_saveregisters in aktprocdef.procoptions) then
-        begin
-          exprasmList.insert(Taicpu.Op_none(A_PUSHA,S_L));
-        end;
-
-      { omit stack frame ? }
-      if (not inlined) then
-        if (procinfo^.framepointer=STACK_POINTER_REG) then
-          begin
-              CGMessage(cg_d_stackframe_omited);
-              nostackframe:=true;
-              if (aktprocdef.proctypeoption in [potype_unitinit,potype_proginit,potype_unitfinalize]) then
-                parasize:=0
-              else
-                parasize:=aktprocdef.parast.datasize+procinfo^.para_offset-4;
-              if stackframe<>0 then
-                exprasmList.insert(Taicpu.op_const_reg(A_SUB,S_L,stackframe,R_ESP));
-          end
-        else
-          begin
-              alignstack(alist);
-              if (aktprocdef.proctypeoption in [potype_unitinit,potype_proginit,potype_unitfinalize]) then
-                parasize:=0
-              else
-                parasize:=aktprocdef.parast.datasize+procinfo^.para_offset-target_info.first_parm_offset;
-              nostackframe:=false;
-              if stackframe<>0 then
-               begin
-{$ifndef __NOWINPECOFF__}
-                 { windows guards only a few pages for stack growing, }
-                 { so we have to access every page first              }
-                 if (target_info.target=target_i386_win32) and
-                    (stackframe>=winstackpagesize) then
-                   begin
-                     if stackframe div winstackpagesize<=5 then
-                       begin
-                          exprasmList.insert(Taicpu.Op_const_reg(A_SUB,S_L,stackframe-4,R_ESP));
-                          for i:=1 to stackframe div winstackpagesize do
-                            begin
-                               reference_reset_base(hr,R_ESP,stackframe-i*winstackpagesize);
-                               exprasmList.concat(Taicpu.op_const_ref(A_MOV,S_L,0,hr));
-                            end;
-                          exprasmList.concat(Taicpu.op_reg(A_PUSH,S_L,R_EAX));
-                       end
-                     else
-                       begin
-                          getlabel(again);
-                          rg.getexplicitregisterint(exprasmlist,R_EDI);
-                          exprasmList.concat(Taicpu.op_const_reg(A_MOV,S_L,stackframe div winstackpagesize,R_EDI));
-                          emitlab(again);
-                          exprasmList.concat(Taicpu.op_const_reg(A_SUB,S_L,winstackpagesize-4,R_ESP));
-                          exprasmList.concat(Taicpu.op_reg(A_PUSH,S_L,R_EAX));
-                          exprasmList.concat(Taicpu.op_reg(A_DEC,S_L,R_EDI));
-                          emitjmp(C_NZ,again);
-                          rg.ungetregisterint(exprasmlist,R_EDI);
-                          exprasmList.concat(Taicpu.op_const_reg(A_SUB,S_L,stackframe mod winstackpagesize,R_ESP));
-                       end
-                   end
-                 else
-{$endif __NOWINPECOFF__}
-                   exprasmList.insert(Taicpu.Op_const_reg(A_SUB,S_L,stackframe,R_ESP));
-                 if (cs_check_stack in aktlocalswitches) then
-                   begin
-                      emitinsertcall('FPC_STACKCHECK');
-                      exprasmList.insert(Taicpu.Op_const(A_PUSH,S_L,stackframe));
-                   end;
-                 if cs_profile in aktmoduleswitches then
-                   genprofilecode;
-                 exprasmList.insert(Taicpu.Op_reg_reg(A_MOV,S_L,R_ESP,R_EBP));
-                 exprasmList.insert(Taicpu.Op_reg(A_PUSH,S_L,R_EBP));
-               end { endif stackframe <> 0 }
-              else
-               begin
-                 if cs_profile in aktmoduleswitches then
-                   genprofilecode;
-                 exprasmList.insert(Taicpu.Op_reg_reg(A_MOV,S_L,R_ESP,R_EBP));
-                 exprasmList.insert(Taicpu.Op_reg(A_PUSH,S_L,R_EBP));
-               end;
-          end;
-
-      if (po_interrupt in aktprocdef.procoptions) then
-          generate_interrupt_stackframe_entry;
-
-      { initialize return value }
-      if (not is_void(aktprocdef.rettype.def)) and
-         (aktprocdef.rettype.def.needs_inittable) then
-        begin
-           procinfo^.flags:=procinfo^.flags or pi_needs_implicit_finally;
-           reference_reset_base(r,procinfo^.framepointer,procinfo^.return_offset);
-           cg.g_initialize(exprasmlist,aktprocdef.rettype.def,r,ret_in_param(aktprocdef.rettype.def));
-        end;
-
-      { initialisize local data like ansistrings }
-      case aktprocdef.proctypeoption of
-         potype_unitinit:
-           begin
-              { using current_module.globalsymtable is hopefully      }
-              { more robust than symtablestack and symtablestack.next }
-              tsymtable(current_module.globalsymtable).foreach_static({$ifndef TP}@{$endif}initialize_data);
-              tsymtable(current_module.localsymtable).foreach_static({$ifndef TP}@{$endif}initialize_data);
-           end;
-         { units have seperate code for initilization and finalization }
-         potype_unitfinalize: ;
-         else
-           aktprocdef.localst.foreach_static({$ifndef TP}@{$endif}initialize_data);
-      end;
-
-      { initialisizes temp. ansi/wide string data }
-      inittempvariables;
-
-      { generate copies of call by value parameters }
-      if not(po_assembler in aktprocdef.procoptions) and
-         not(aktprocdef.proccalloption in [pocall_cdecl,pocall_cppdecl,pocall_palmossyscall,pocall_system]) then
-        aktprocdef.parast.foreach_static({$ifndef TP}@{$endif}copyvalueparas);
-
-      if assigned( aktprocdef.parast) then
-        aktprocdef.parast.foreach_static({$ifndef TP}@{$endif}init_paras);
-
-      { do we need an exception frame because of ansi/widestrings/interfaces ? }
-      if not inlined and
-         ((procinfo^.flags and pi_needs_implicit_finally)<>0) and
-      { but it's useless in init/final code of units }
-        not(aktprocdef.proctypeoption in [potype_unitfinalize,potype_unitinit]) then
-        begin
-            include(rg.usedinproc,R_EAX);
-
-            exprasmList.concat(Taicpu.op_const_reg(A_SUB,S_L,36,R_ESP));
-            exprasmList.concat(Taicpu.op_reg_reg(A_MOV,S_L,R_ESP,R_EDI));
-
-            reference_reset(tempaddr);
-            tempaddr.base:=R_EDI;
-            emitpushreferenceaddr(tempaddr);
-
-            reference_reset(tempbuf);
-            tempbuf.base:=R_EDI;
-            tempbuf.offset:=12;
-            emitpushreferenceaddr(tempbuf);
-
-            { Type of stack-frame must be pushed}
-            exprasmList.concat(Taicpu.op_const(A_PUSH,S_L,1));
-            emitcall('FPC_PUSHEXCEPTADDR');
-
-            exprasmList.concat(Taicpu.op_reg(A_PUSH,S_L,R_EAX));
-            emitcall('FPC_SETJMP');
-            exprasmList.concat(Taicpu.op_reg(A_PUSH,S_L,R_EAX));
-            exprasmList.concat(Taicpu.op_reg_reg(A_TEST,S_L,R_EAX,R_EAX));
-            emitjmp(C_NE,aktexitlabel);
-            { probably we've to reload self here }
-            maybe_loadself;
-        end;
-
-      if not inlined then
-       begin
-         if (cs_profile in aktmoduleswitches) or
-            (aktprocdef.owner.symtabletype=globalsymtable) or
-            (assigned(procinfo^._class) and (procinfo^._class.owner.symtabletype=globalsymtable)) then
-              make_global:=true;
-
-         hs:=aktprocdef.aliasnames.getfirst;
-
-{$ifdef GDB}
-         if (cs_debuginfo in aktmoduleswitches) and target_info.use_function_relative_addresses then
-           stab_function_name := Tai_stab_function_name.Create(strpnew(hs));
-{$EndIf GDB}
-
-         while hs<>'' do
-          begin
-            if make_global then
-              exprasmList.insert(Tai_symbol.Createname_global(hs,0))
-            else
-              exprasmList.insert(Tai_symbol.Createname(hs,0));
-
-{$ifdef GDB}
-            if (cs_debuginfo in aktmoduleswitches) and
-               target_info.use_function_relative_addresses then
-              exprasmList.insert(Tai_stab_function_name.Create(strpnew(hs)));
-{$endif GDB}
-
-            hs:=aktprocdef.aliasnames.getfirst;
-          end;
-
-         if make_global or ((procinfo^.flags and pi_is_global) <> 0) then
-          aktprocsym.is_global := True;
-
-{$ifdef GDB}
-         if (cs_debuginfo in aktmoduleswitches) then
-          begin
-            if target_info.use_function_relative_addresses then
-             exprasmList.insert(stab_function_name);
-            exprasmList.insert(Tai_stabs.Create(aktprocdef.stabstring));
-            aktprocsym.isstabwritten:=true;
-          end;
-{$endif GDB}
-
-         { Align, gprof uses 16 byte granularity }
-         if (cs_profile in aktmoduleswitches) then
-          exprasmList.insert(Tai_align.Create_op(16,$90))
-         else
-          exprasmList.insert(Tai_align.Create(aktalignment.procalign));
-       end;
-       if inlined then
-         load_regvars(exprasmlist,nil);
-      exprasmlist:=oldexprasmlist;
-  end;
-
-
-  procedure handle_return_value(inlined : boolean;var uses_eax,uses_edx : boolean);
-    var
-       hr : treference;
-  begin
-      if not is_void(aktprocdef.rettype.def) then
-          begin
-              {if ((procinfo^.flags and pi_operator)<>0) and
-                 assigned(otsym) then
-                procinfo^.funcret_is_valid:=
-                  procinfo^.funcret_is_valid or (otsym.refs>0);}
-              if (tfuncretsym(aktprocdef.funcretsym).funcretstate<>vs_assigned) and not inlined { and
-                ((procinfo^.flags and pi_uses_asm)=0)} then
-               CGMessage(sym_w_function_result_not_set);
-              reference_reset_base(hr,procinfo^.framepointer,procinfo^.return_offset);
-              if (aktprocdef.rettype.def.deftype in [orddef,enumdef]) then
-                begin
-                  uses_eax:=true;
-                  exprasmList.concat(Tairegalloc.Alloc(R_EAX));
-                  case aktprocdef.rettype.def.size of
-                   8:
-                     begin
-                        emit_ref_reg(A_MOV,S_L,hr,R_EAX);
-                        reference_reset_base(hr,procinfo^.framepointer,procinfo^.return_offset+4);
-                        exprasmList.concat(Tairegalloc.Alloc(R_EDX));
-                        emit_ref_reg(A_MOV,S_L,hr,R_EDX);
-                        uses_edx:=true;
-                     end;
-
-                   4:
-                     emit_ref_reg(A_MOV,S_L,hr,R_EAX);
-
-                   2:
-                     emit_ref_reg(A_MOV,S_W,hr,R_AX);
-
-                   1:
-                     emit_ref_reg(A_MOV,S_B,hr,R_AL);
-                  end;
-                end
-              else
-                if ret_in_acc(aktprocdef.rettype.def) then
-                  begin
-                    uses_eax:=true;
-                    exprasmList.concat(Tairegalloc.Alloc(R_EAX));
-                    emit_ref_reg(A_MOV,S_L,hr,R_EAX);
-                  end
-              else
-                 if (aktprocdef.rettype.def.deftype=floatdef) then
-                   begin
-                      cg.a_loadfpu_ref_reg(exprasmlist,
-                        def_cgsize(aktprocdef.rettype.def),hr,R_ST);
-                   end;
-          end
-  end;
-
-
-  procedure handle_fast_exit_return_value;
-    var
-       hr : treference;
-    begin
-      if not is_void(aktprocdef.rettype.def) then
-          begin
-              reference_reset_base(hr,procinfo^.framepointer,procinfo^.return_offset);
-              if (aktprocdef.rettype.def.deftype in [orddef,enumdef]) then
-                begin
-                  case aktprocdef.rettype.def.size of
-                   8:
-                     begin
-                        emit_reg_ref(A_MOV,S_L,R_EAX,hr);
-                        reference_reset_base(hr,procinfo^.framepointer,procinfo^.return_offset+4);
-                        emit_reg_ref(A_MOV,S_L,R_EDX,hr);
-                     end;
-
-                   4:
-                     emit_reg_ref(A_MOV,S_L,R_EAX,hr);
-
-                   2:
-                     emit_reg_ref(A_MOV,S_W,R_AX,hr);
-
-                   1:
-                     emit_reg_ref(A_MOV,S_B,R_AL,hr);
-                  end;
-                end
-              else
-                if ret_in_acc(aktprocdef.rettype.def) then
-                  begin
-                    emit_reg_ref(A_MOV,S_L,R_EAX,hr);
-                  end
-              else
-                 if (aktprocdef.rettype.def.deftype=floatdef) then
-                   begin
-                      cg.a_loadfpu_reg_ref(exprasmlist,
-                        def_cgsize(aktprocdef.rettype.def),
-                        R_ST,hr);
-                   end;
-          end
-     end;
-
-
-  procedure genexitcode(alist : TAAsmoutput;parasize:longint;nostackframe,inlined:boolean);
-
-    var
-{$ifdef GDB}
-       mangled_length : longint;
-       p : pchar;
-       st : string[2];
-{$endif GDB}
-       stabsendlabel,nofinal,okexitlabel,
-       noreraiselabel,nodestroycall : tasmlabel;
-       hr : treference;
-       uses_eax,uses_edx,uses_esi : boolean;
-       oldexprasmlist : TAAsmoutput;
-       ai : taicpu;
-       pd : tprocdef;
-
-  begin
-      oldexprasmlist:=exprasmlist;
-      exprasmlist:=alist;
-
-      if aktexit2label.is_used and
-         ((procinfo^.flags and (pi_needs_implicit_finally or pi_uses_exceptions)) <> 0) then
-        begin
-          exprasmlist.concat(taicpu.op_sym(A_JMP,S_NO,aktexitlabel));
-          exprasmlist.concat(tai_label.create(aktexit2label));
-          handle_fast_exit_return_value;
-        end;
-
-      if aktexitlabel.is_used then
-        exprasmList.concat(Tai_label.Create(aktexitlabel));
-
-      cleanup_regvars(alist);
-
-      { call the destructor help procedure }
-      if (aktprocdef.proctypeoption=potype_destructor) and
-         assigned(procinfo^._class) then
-        begin
-          if is_class(procinfo^._class) then
-            begin
-              emitinsertcall('FPC_DISPOSE_CLASS');
-            end
-          else if is_object(procinfo^._class) then
-            begin
-              emitinsertcall('FPC_HELP_DESTRUCTOR');
-              rg.getexplicitregisterint(exprasmlist,R_EDI);
-              exprasmList.insert(Taicpu.Op_const_reg(A_MOV,S_L,procinfo^._class.vmt_offset,R_EDI));
-              { must the object be finalized ? }
-              if procinfo^._class.needs_inittable then
-                begin
-                   getlabel(nofinal);
-                   exprasmList.insert(Tai_label.Create(nofinal));
-                   emitinsertcall('FPC_FINALIZE');
-                   rg.ungetregisterint(exprasmlist,R_EDI);
-                   exprasmList.insert(Taicpu.Op_reg(A_PUSH,S_L,R_ESI));
-                   exprasmList.insert(Taicpu.Op_sym(A_PUSH,S_L,procinfo^._class.get_rtti_label(initrtti)));
-                   ai:=Taicpu.Op_sym(A_Jcc,S_NO,nofinal);
-                   ai.SetCondition(C_Z);
-                   exprasmList.insert(ai);
-                   reference_reset_base(hr,R_EBP,8);
-                   exprasmList.insert(Taicpu.Op_const_ref(A_CMP,S_L,0,hr));
-                end;
-            end
-          else
-            begin
-              Internalerror(200006161);
-            end;
-        end;
-
-      { finalize temporary data }
-      finalizetempvariables;
-
-      { finalize local data like ansistrings}
-      case aktprocdef.proctypeoption of
-         potype_unitfinalize:
-           begin
-              { using current_module.globalsymtable is hopefully      }
-              { more robust than symtablestack and symtablestack.next }
-              tsymtable(current_module.globalsymtable).foreach_static({$ifndef TP}@{$endif}finalize_data);
-              tsymtable(current_module.localsymtable).foreach_static({$ifndef TP}@{$endif}finalize_data);
-           end;
-         { units have seperate code for initialization and finalization }
-         potype_unitinit: ;
-         else
-           aktprocdef.localst.foreach_static({$ifndef TP}@{$endif}finalize_data);
-      end;
-
-      { finalize paras data }
-      if assigned(aktprocdef.parast) then
-        aktprocdef.parast.foreach_static({$ifndef TP}@{$endif}final_paras);
-
-      { do we need to handle exceptions because of ansi/widestrings ? }
-      if not inlined and
-         ((procinfo^.flags and pi_needs_implicit_finally)<>0) and
-      { but it's useless in init/final code of units }
-        not(aktprocdef.proctypeoption in [potype_unitfinalize,potype_unitinit]) then
-        begin
-           { the exception helper routines modify all registers }
-           aktprocdef.usedregisters:=all_registers;
-
-           getlabel(noreraiselabel);
-           emitcall('FPC_POPADDRSTACK');
-           exprasmList.concat(Tairegalloc.Alloc(R_EAX));
-           exprasmList.concat(Taicpu.op_reg(A_POP,S_L,R_EAX));
-           exprasmList.concat(Taicpu.op_reg_reg(A_TEST,S_L,R_EAX,R_EAX));
-           rg.ungetregisterint(exprasmlist,R_EAX);
-           emitjmp(C_E,noreraiselabel);
-           if (aktprocdef.proctypeoption=potype_constructor) then
-             begin
-                if assigned(procinfo^._class) then
-                  begin
-                     pd:=procinfo^._class.searchdestructor;
-                     if assigned(pd) then
-                       begin
-                          getlabel(nodestroycall);
-                          reference_reset_base(hr,procinfo^.framepointer,procinfo^.selfpointer_offset);
-                          emit_const_ref(A_CMP,S_L,0,hr);
-                          emitjmp(C_E,nodestroycall);
-                          if is_class(procinfo^._class) then
-                            begin
-                               emit_const(A_PUSH,S_L,1);
-                               emit_reg(A_PUSH,S_L,R_ESI);
-                            end
-                          else if is_object(procinfo^._class) then
-                            begin
-                               emit_reg(A_PUSH,S_L,R_ESI);
-                               emit_sym(A_PUSH,S_L,newasmsymbol(procinfo^._class.vmt_mangledname));
-                            end
-                          else
-                            begin
-                              Internalerror(200006161);
-                            end;
-                          if (po_virtualmethod in pd.procoptions) then
-                            begin
-                               reference_reset_base(hr,R_ESI,0);
-                               emit_ref_reg(A_MOV,S_L,hr,R_EDI);
-                               reference_reset_base(hr,R_EDI,procinfo^._class.vmtmethodoffset(pd.extnumber));
-                               emit_ref(A_CALL,S_NO,hr);
-                            end
-                          else
-                            emitcall(pd.mangledname);
-                          { not necessary because the result is never assigned in the
-                            case of an exception (FK)
-                          emit_const_reg(A_MOV,S_L,0,R_ESI);
-                          emit_const_ref(A_MOV,S_L,0,reference_reset_base(procinfo^.framepointer,8));
-                          }
-                          emitlab(nodestroycall);
-                       end;
-                  end
-             end
-           else
-           { must be the return value finalized before reraising the exception? }
-           if (not is_void(aktprocdef.rettype.def)) and
-             (aktprocdef.rettype.def.needs_inittable) and
-             ((aktprocdef.rettype.def.deftype<>objectdef) or
-              not is_class(aktprocdef.rettype.def)) then
-             begin
-                reference_reset_base(hr,procinfo^.framepointer,procinfo^.return_offset);
-                cg.g_finalize(exprasmlist,aktprocdef.rettype.def,hr,ret_in_param(aktprocdef.rettype.def));
-             end;
-
-           emitcall('FPC_RERAISE');
-           emitlab(noreraiselabel);
-        end;
-
-      { call __EXIT for main program }
-      if (not DLLsource) and (not inlined) and (aktprocdef.proctypeoption=potype_proginit) then
-       begin
-         emitcall('FPC_DO_EXIT');
-       end;
-
-      { handle return value, this is not done for assembler routines when
-        they didn't reference the result variable }
-      uses_eax:=false;
-      uses_edx:=false;
-      uses_esi:=false;
-      if not(po_assembler in aktprocdef.procoptions) or
-         (assigned(aktprocdef.funcretsym) and
-          (tfuncretsym(aktprocdef.funcretsym).refcount>1)) then
-        begin
-          if (aktprocdef.proctypeoption<>potype_constructor) then
-            handle_return_value(inlined,uses_eax,uses_edx)
-          else
-            begin
-                { successful constructor deletes the zero flag }
-                { and returns self in eax                   }
-                { eax must be set to zero if the allocation failed !!! }
-                getlabel(okexitlabel);
-                emitjmp(C_NONE,okexitlabel);
-                emitlab(faillabel);
-                if is_class(procinfo^._class) then
-                  begin
-                    reference_reset_base(hr,procinfo^.framepointer,8);
-                    emit_ref_reg(A_MOV,S_L,hr,R_ESI);
-                    emitcall('FPC_HELP_FAIL_CLASS');
-                  end
-                else if is_object(procinfo^._class) then
-                  begin
-                    reference_reset_base(hr,procinfo^.framepointer,12);
-                    emit_ref_reg(A_MOV,S_L,hr,R_ESI);
-                    rg.getexplicitregisterint(exprasmlist,R_EDI);
-                    emit_const_reg(A_MOV,S_L,procinfo^._class.vmt_offset,R_EDI);
-                    emitcall('FPC_HELP_FAIL');
-                    rg.ungetregisterint(exprasmlist,R_EDI);
-                  end
-                else
-                  Internalerror(200006161);
-
-              emitlab(okexitlabel);
-
-              { for classes this is done after the call to }
-              { AfterConstruction                          }
-              if is_object(procinfo^._class) then
-                begin
-                  exprasmList.concat(Tairegalloc.Alloc(R_EAX));
-                  emit_reg_reg(A_MOV,S_L,R_ESI,R_EAX);
-                  uses_eax:=true;
-                end;
-              emit_reg_reg(A_TEST,S_L,R_ESI,R_ESI);
-              uses_esi:=true;
-            end;
-        end;
-
-      if aktexit2label.is_used and not aktexit2label.is_set then
-        emitlab(aktexit2label);
-
-      if ((cs_debuginfo in aktmoduleswitches) and not inlined) then
-        begin
-          getlabel(stabsendlabel);
-          emitlab(stabsendlabel);
-        end;
-      { gives problems for long mangled names }
-      {List.concat(Tai_symbol.Create(aktprocdef.mangledname+'_end'));}
-
-      { should we restore edi ? }
-      { for all i386 gcc implementations }
-      if (po_savestdregs in aktprocdef.procoptions) then
-        begin
-          if (R_EBX in aktprocdef.usedregisters) then
-           exprasmList.concat(Taicpu.Op_reg(A_POP,S_L,R_EBX));
-          exprasmList.concat(Taicpu.Op_reg(A_POP,S_L,R_ESI));
-          exprasmList.concat(Taicpu.Op_reg(A_POP,S_L,R_EDI));
-          { here we could reset R_EBX
-            but that is risky because it only works
-            if genexitcode is called after genentrycode
-            so lets skip this for the moment PM
-          aktprocdef.usedregisters:=
-            aktprocdef.usedregisters or not ($80 shr byte(R_EBX));
-          }
-        end;
-
-      { for the save all registers we can simply use a pusha,popa which
-        push edi,esi,ebp,esp(ignored),ebx,edx,ecx,eax }
-      if (po_saveregisters in aktprocdef.procoptions) then
-        begin
-          if uses_esi then
-           begin
-             reference_reset_base(hr,R_ESP,4);
-             exprasmList.concat(Taicpu.Op_reg_ref(A_MOV,S_L,R_ESI,hr));
-           end;
-          if uses_edx then
-           begin
-             reference_reset_base(hr,R_ESP,20);
-             exprasmList.concat(Taicpu.Op_reg_ref(A_MOV,S_L,R_EDX,hr));
-           end;
-          if uses_eax then
-           begin
-             reference_reset_base(hr,R_ESP,28);
-             exprasmList.concat(Taicpu.Op_reg_ref(A_MOV,S_L,R_EAX,hr));
-           end;
-          exprasmList.concat(Taicpu.Op_none(A_POPA,S_L));
-          { We add a NOP because of the 386DX CPU bugs with POPAD }
-          exprasmlist.concat(taicpu.op_none(A_NOP,S_L));
-        end;
-      if not(nostackframe) then
-        begin
-          if not inlined then
-            exprasmList.concat(Taicpu.Op_none(A_LEAVE,S_NO));
-        end
-      else
-        begin
-          if (tg.gettempsize<>0) and not inlined then
-            exprasmList.insert(Taicpu.op_const_reg(A_ADD,S_L,tg.gettempsize,R_ESP));
-        end;
-
-      { parameters are limited to 65535 bytes because }
-      { ret allows only imm16                    }
-      if (parasize>65535) and not(po_clearstack in aktprocdef.procoptions) then
-       CGMessage(cg_e_parasize_too_big);
-
-      { at last, the return is generated }
-
-      if not inlined then
-      if (po_interrupt in aktprocdef.procoptions) then
-          begin
-             if uses_esi then
-              begin
-                reference_reset_base(hr,R_ESP,16);
-                exprasmList.concat(Taicpu.Op_reg_ref(A_MOV,S_L,R_ESI,hr));
-              end;
-             if uses_edx then
-               begin
-                 reference_reset_base(hr,R_ESP,12);
-                 exprasmList.concat(Tairegalloc.Alloc(R_EAX));
-                 exprasmList.concat(Taicpu.Op_reg_ref(A_MOV,S_L,R_EDX,hr));
-               end;
-             if uses_eax then
-               begin
-                 reference_reset_base(hr,R_ESP,0);
-                 exprasmList.concat(Tairegalloc.Alloc(R_EAX));
-                 exprasmList.concat(Taicpu.Op_reg_ref(A_MOV,S_L,R_EAX,hr));
-               end;
-             generate_interrupt_stackframe_exit;
-          end
-      else
-       begin
-       {Routines with the poclearstack flag set use only a ret.}
-       { also routines with parasize=0     }
-         if (po_clearstack in aktprocdef.procoptions) then
-           begin
-{$ifndef OLD_C_STACK}
-             { complex return values are removed from stack in C code PM }
-             if ret_in_param(aktprocdef.rettype.def) then
-               exprasmList.concat(Taicpu.Op_const(A_RET,S_NO,4))
-             else
-{$endif not OLD_C_STACK}
-               exprasmList.concat(Taicpu.Op_none(A_RET,S_NO));
-           end
-         else if (parasize=0) then
-          exprasmList.concat(Taicpu.Op_none(A_RET,S_NO))
-         else
-          exprasmList.concat(Taicpu.Op_const(A_RET,S_NO,parasize));
-       end;
-
-      if not inlined then
-        exprasmList.concat(Tai_symbol_end.Createname(aktprocdef.mangledname));
-
-{$ifdef GDB}
-      if (cs_debuginfo in aktmoduleswitches) and not inlined  then
-          begin
-              aktprocdef.concatstabto(exprasmlist);
-              if assigned(procinfo^._class) then
-                if (not assigned(procinfo^.parent) or
-                   not assigned(procinfo^.parent^._class)) then
-                  begin
-                    if (po_classmethod in aktprocdef.procoptions) or
-                       ((po_virtualmethod in aktprocdef.procoptions) and
-                        (potype_constructor=aktprocdef.proctypeoption)) or
-                       (po_staticmethod in aktprocdef.procoptions) then
-                      begin
-                        exprasmList.concat(Tai_stabs.Create(strpnew(
-                         '"pvmt:p'+tstoreddef(pvmttype.def).numberstring+'",'+
-                         tostr(N_tsym)+',0,0,'+tostr(procinfo^.selfpointer_offset))));
-                      end
-                    else
-                      begin
-                        if not(is_class(procinfo^._class)) then
-                          st:='v'
-                        else
-                          st:='p';
-                        exprasmList.concat(Tai_stabs.Create(strpnew(
-                         '"$t:'+st+procinfo^._class.numberstring+'",'+
-                         tostr(N_tsym)+',0,0,'+tostr(procinfo^.selfpointer_offset))));
-                      end;
-                  end
-                else
-                  begin
-                    if not is_class(procinfo^._class) then
-                      st:='*'
-                    else
-                      st:='';
-                    exprasmList.concat(Tai_stabs.Create(strpnew(
-                     '"$t:r'+st+procinfo^._class.numberstring+'",'+
-                     tostr(N_RSYM)+',0,0,'+tostr(GDB_i386index[R_ESI]))));
-                  end;
-
-              { define calling EBP as pseudo local var PM }
-              { this enables test if the function is a local one !! }
-              if  assigned(procinfo^.parent) and (lexlevel>normal_function_level) then
-                exprasmList.concat(Tai_stabs.Create(strpnew(
-                 '"parent_ebp:'+tstoreddef(voidpointertype.def).numberstring+'",'+
-                 tostr(N_LSYM)+',0,0,'+tostr(procinfo^.framepointer_offset))));
-
-              if (not is_void(aktprocdef.rettype.def)) then
-                begin
-                  if ret_in_param(aktprocdef.rettype.def) then
-                    exprasmList.concat(Tai_stabs.Create(strpnew(
-                     '"'+aktprocsym.name+':X*'+tstoreddef(aktprocdef.rettype.def).numberstring+'",'+
-                     tostr(N_tsym)+',0,0,'+tostr(procinfo^.return_offset))))
-                  else
-                    exprasmList.concat(Tai_stabs.Create(strpnew(
-                     '"'+aktprocsym.name+':X'+tstoreddef(aktprocdef.rettype.def).numberstring+'",'+
-                     tostr(N_tsym)+',0,0,'+tostr(procinfo^.return_offset))));
-                  if (m_result in aktmodeswitches) then
-                    if ret_in_param(aktprocdef.rettype.def) then
-                      exprasmList.concat(Tai_stabs.Create(strpnew(
-                       '"RESULT:X*'+tstoreddef(aktprocdef.rettype.def).numberstring+'",'+
-                       tostr(N_tsym)+',0,0,'+tostr(procinfo^.return_offset))))
-                    else
-                      exprasmList.concat(Tai_stabs.Create(strpnew(
-                       '"RESULT:X'+tstoreddef(aktprocdef.rettype.def).numberstring+'",'+
-                       tostr(N_tsym)+',0,0,'+tostr(procinfo^.return_offset))));
-                end;
-              mangled_length:=length(aktprocdef.mangledname);
-              getmem(p,2*mangled_length+50);
-              strpcopy(p,'192,0,0,');
-              strpcopy(strend(p),aktprocdef.mangledname);
-              if (target_info.use_function_relative_addresses) then
-                begin
-                  strpcopy(strend(p),'-');
-                  strpcopy(strend(p),aktprocdef.mangledname);
-                end;
-              exprasmList.concat(Tai_stabn.Create(strnew(p)));
-              {List.concat(Tai_stabn.Create(strpnew('192,0,0,'
-               +aktprocdef.mangledname))));
-              p[0]:='2';p[1]:='2';p[2]:='4';
-              strpcopy(strend(p),'_end');}
-              strpcopy(p,'224,0,0,'+stabsendlabel.name);
-              if (target_info.use_function_relative_addresses) then
-                begin
-                  strpcopy(strend(p),'-');
-                  strpcopy(strend(p),aktprocdef.mangledname);
-                end;
-              exprasmList.concatlist(withdebuglist);
-              exprasmList.concat(Tai_stabn.Create(strnew(p)));
-               { strpnew('224,0,0,'
-               +aktprocdef.mangledname+'_end'))));}
-              freemem(p,2*mangled_length+50);
-          end;
-{$endif GDB}
-       if inlined then
-         cleanup_regvars(exprasmlist);
-      exprasmlist:=oldexprasmlist;
-  end;
-
-    procedure genimplicitunitfinal(alist : TAAsmoutput);
-
-      begin
-         { using current_module.globalsymtable is hopefully      }
-         { more robust than symtablestack and symtablestack.next }
-         tsymtable(current_module.globalsymtable).foreach_static({$ifndef TP}@{$endif}finalize_data);
-         tsymtable(current_module.localsymtable).foreach_static({$ifndef TP}@{$endif}finalize_data);
-         exprasmList.insert(Tai_symbol.Createname_global('FINALIZE$$'+current_module.modulename^,0));
-         exprasmList.insert(Tai_symbol.Createname_global(target_info.cprefix+current_module.modulename^+'_finalize',0));
-{$ifdef GDB}
-         if (cs_debuginfo in aktmoduleswitches) and
-           target_info.use_function_relative_addresses then
-           exprasmList.insert(Tai_stab_function_name.Create(strpnew('FINALIZE$$'+current_module.modulename^)));
-{$endif GDB}
-         exprasmList.concat(Taicpu.Op_none(A_RET,S_NO));
-         aList.concatlist(exprasmlist);
-      end;
-
-    procedure genimplicitunitinit(alist : TAAsmoutput);
-
-      begin
-         { using current_module.globalsymtable is hopefully      }
-         { more robust than symtablestack and symtablestack.next }
-         tsymtable(current_module.globalsymtable).foreach_static({$ifndef TP}@{$endif}finalize_data);
-         tsymtable(current_module.localsymtable).foreach_static({$ifndef TP}@{$endif}finalize_data);
-         exprasmList.insert(Tai_symbol.Createname_global('INIT$$'+current_module.modulename^,0));
-         exprasmList.insert(Tai_symbol.Createname_global(target_info.cprefix+current_module.modulename^+'_init',0));
-{$ifdef GDB}
-         if (cs_debuginfo in aktmoduleswitches) and
-           target_info.use_function_relative_addresses then
-           exprasmList.insert(Tai_stab_function_name.Create(strpnew('INIT$$'+current_module.modulename^)));
-{$endif GDB}
-         exprasmList.concat(Taicpu.Op_none(A_RET,S_NO));
-         aList.concatlist(exprasmlist);
-      end;
-
-{$ifdef test_dest_loc}
-       procedure mov_reg_to_dest(p : ptree; s : topsize; reg : tregister);
-
-         begin
-            if (dest_loc.loc=LOC_CREGISTER) or (dest_loc.loc=LOC_REGISTER) then
-              begin
-                emit_reg_reg(A_MOV,s,reg,dest_loc.register);
-                set_location(p^.location,dest_loc);
-                in_dest_loc:=true;
-              end
-            else
-            if (dest_loc.loc=LOC_REFERENCE) or (dest_loc.loc=LOC_CREFERENCE) then
-              begin
-                exprasmList.concat(Taicpu.Op_reg_ref(A_MOV,s,reg,dest_loc.reference));
-                set_location(p^.location,dest_loc);
-                in_dest_loc:=true;
-              end
-            else
-              internalerror(20080);
-         end;
-
-{$endif test_dest_loc}
-{$ifdef __NOWINPECOFF__}
- {$undef __NOWINPECOFF__}
-{$endif}
-
 end.
 {
   $Log$
-  Revision 1.27  2002-04-25 20:16:39  peter
+  Revision 1.28  2002-05-12 16:53:16  peter
+    * moved entry and exitcode to ncgutil and cgobj
+    * foreach gets extra argument for passing local data to the
+      iterator function
+    * -CR checks also class typecasts at runtime by changing them
+      into as
+    * fixed compiler to cycle with the -CR option
+    * fixed stabs with elf writer, finally the global variables can
+      be watched
+    * removed a lot of routines from cga unit and replaced them by
+      calls to cgobj
+    * u32bit-s32bit updates for and,or,xor nodes. When one element is
+      u32bit then the other is typecasted also to u32bit without giving
+      a rangecheck warning/error.
+    * fixed pascal calling method with reversing also the high tree in
+      the parast, detected by tcalcst3 test
+
+  Revision 1.27  2002/04/25 20:16:39  peter
     * moved more routines from cga/n386util
 
   Revision 1.26  2002/04/21 15:29:53  carl

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 768 - 207
compiler/i386/cgcpu.pas


+ 20 - 20
compiler/i386/cpuasm.pas

@@ -46,7 +46,7 @@ uses
 
 const
   MaxPrefixes=4;
-  
+
 {*****************************************************************************
                               Instruction table
 *****************************************************************************}
@@ -147,7 +147,7 @@ type
      procedure Swatoperands;
 {$endif NOAG386BIN}
   end;
-  
+
   procedure InitAsm;
   procedure DoneAsm;
 
@@ -159,23 +159,6 @@ uses
   ogbase,
   ag386att;
 
-const  
-{ Convert reg to operand type }
-  reg_2_type:array[firstreg..lastreg] of longint = (OT_NONE,
-    OT_REG_EAX,OT_REG_ECX,OT_REG32,OT_REG32,OT_REG32,OT_REG32,OT_REG32,OT_REG32,
-    OT_REG_AX,OT_REG_CX,OT_REG_DX,OT_REG16,OT_REG16,OT_REG16,OT_REG16,OT_REG16,
-    OT_REG_AL,OT_REG_CL,OT_REG8,OT_REG8,OT_REG8,OT_REG8,OT_REG8,OT_REG8,
-    OT_REG_CS,OT_REG_DESS,OT_REG_DESS,OT_REG_DESS,OT_REG_FSGS,OT_REG_FSGS,
-    OT_FPU0,OT_FPU0,OT_FPUREG,OT_FPUREG,OT_FPUREG,OT_FPUREG,OT_FPUREG,OT_FPUREG,OT_FPUREG,
-    OT_REG_DREG,OT_REG_DREG,OT_REG_DREG,OT_REG_DREG,OT_REG_DREG,OT_REG_DREG,
-    OT_REG_CREG,OT_REG_CREG,OT_REG_CREG,OT_REG_CR4,
-    OT_REG_TREG,OT_REG_TREG,OT_REG_TREG,OT_REG_TREG,OT_REG_TREG,
-    OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,
-    OT_XMMREG,OT_XMMREG,OT_XMMREG,OT_XMMREG,OT_XMMREG,OT_XMMREG,OT_XMMREG,OT_XMMREG
-  );
-  
-
-
 {****************************************************************************
                               TAI_ALIGN
  ****************************************************************************}
@@ -1680,7 +1663,24 @@ end;
 end.
 {
   $Log$
-  Revision 1.20  2002-04-15 19:44:20  peter
+  Revision 1.21  2002-05-12 16:53:16  peter
+    * moved entry and exitcode to ncgutil and cgobj
+    * foreach gets extra argument for passing local data to the
+      iterator function
+    * -CR checks also class typecasts at runtime by changing them
+      into as
+    * fixed compiler to cycle with the -CR option
+    * fixed stabs with elf writer, finally the global variables can
+      be watched
+    * removed a lot of routines from cga unit and replaced them by
+      calls to cgobj
+    * u32bit-s32bit updates for and,or,xor nodes. When one element is
+      u32bit then the other is typecasted also to u32bit without giving
+      a rangecheck warning/error.
+    * fixed pascal calling method with reversing also the high tree in
+      the parast, detected by tcalcst3 test
+
+  Revision 1.20  2002/04/15 19:44:20  peter
     * fixed stackcheck that would be called recursively when a stack
       error was found
     * generic changeregsize(reg,size) for i386 register resizing

+ 35 - 19
compiler/i386/cpubase.pas

@@ -465,10 +465,10 @@ type
 
 const
   general_registers = [R_EAX,R_EBX,R_ECX,R_EDX];
-  
-  {# Table of registers which can be allocated by the code generator       
-     internally, when generating the code.                             
-  }   
+
+  {# Table of registers which can be allocated by the code generator
+     internally, when generating the code.
+  }
   { legend:                                                                }
   { xxxregs = set of all possibly used registers of that type in the code  }
   {           generator                                                    }
@@ -504,7 +504,7 @@ const
     LOC_CREGISTER,LOC_MMXREGISTER,LOC_CMMXREGISTER];
 
 {*****************************************************************************
-                          Default generic sizes 
+                          Default generic sizes
 *****************************************************************************}
    {# Defines the default address size for a processor, }
    OS_ADDR = OS_32;
@@ -523,10 +523,10 @@ const
   stack_pointer_reg = R_ESP;
   {# Frame pointer register }
   frame_pointer_reg = R_EBP;
-  {# Self pointer register : contains the instance address of an 
+  {# Self pointer register : contains the instance address of an
      object or class. }
   self_pointer_reg  = R_ESI;
-  {# 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 }
   pic_offset_reg = R_EBX;
   {# Results are returned in this register (32-bit values) }
@@ -538,12 +538,12 @@ const
   fpuresultreg = R_ST;
   mmresultreg = R_MM0;
 
-  {# Registers which are defined as scratch and no need to save across 
+  {# Registers which are defined as scratch and no need to save across
      routine calls or in assembler blocks.
   }
   scratch_regs : array[1..1] of tregister = (R_EDI);
 
-  
+
 
 {*****************************************************************************
                        GCC /ABI linking information
@@ -552,20 +552,20 @@ const
   {# Registers which must be saved when calling a routine declared as
      cppdecl, cdecl, stdcall, safecall, palmossyscall. The registers
      saved should be the ones as defined in the target ABI and / or GCC.
-     
+
      This value can be deduced from the CALLED_USED_REGISTERS array in the
      GCC source.
   }
   std_saved_registers = [R_ESI,R_EDI,R_EBX];
   {# Required parameter alignment when calling a routine declared as
      stdcall and cdecl. The alignment value should be the one defined
-     by GCC or the target ABI. 
-     
-     The value of this constant is equal to the constant 
+     by GCC or the target ABI.
+
+     The value of this constant is equal to the constant
      PARM_BOUNDARY / BITS_PER_UNIT in the GCC source.
-  }     
+  }
   std_param_align = 4;
-  
+
 
 
 
@@ -593,11 +593,10 @@ const
 
 implementation
 
-  uses
 {$ifdef heaptrc}
-      ppheap,
+  uses
+      ppheap;
 {$endif heaptrc}
-      verbose;
 
 
 {*****************************************************************************
@@ -640,7 +639,24 @@ implementation
 end.
 {
   $Log$
-  Revision 1.18  2002-04-21 15:31:40  carl
+  Revision 1.19  2002-05-12 16:53:16  peter
+    * moved entry and exitcode to ncgutil and cgobj
+    * foreach gets extra argument for passing local data to the
+      iterator function
+    * -CR checks also class typecasts at runtime by changing them
+      into as
+    * fixed compiler to cycle with the -CR option
+    * fixed stabs with elf writer, finally the global variables can
+      be watched
+    * removed a lot of routines from cga unit and replaced them by
+      calls to cgobj
+    * u32bit-s32bit updates for and,or,xor nodes. When one element is
+      u32bit then the other is typecasted also to u32bit without giving
+      a rangecheck warning/error.
+    * fixed pascal calling method with reversing also the high tree in
+      the parast, detected by tcalcst3 test
+
+  Revision 1.18  2002/04/21 15:31:40  carl
   - removed some other stuff to their units
 
   Revision 1.17  2002/04/20 21:37:07  carl

+ 18 - 2
compiler/i386/cputarg.pas

@@ -69,7 +69,6 @@ implementation
 **************************************}
 
     {$ifndef NOAG386ATT}
-      ,aggas
       ,ag386att
     {$endif}
     {$ifndef NOAG386NSM}
@@ -86,7 +85,24 @@ implementation
 end.
 {
   $Log$
-  Revision 1.5  2002-04-14 17:00:49  carl
+  Revision 1.6  2002-05-12 16:53:16  peter
+    * moved entry and exitcode to ncgutil and cgobj
+    * foreach gets extra argument for passing local data to the
+      iterator function
+    * -CR checks also class typecasts at runtime by changing them
+      into as
+    * fixed compiler to cycle with the -CR option
+    * fixed stabs with elf writer, finally the global variables can
+      be watched
+    * removed a lot of routines from cga unit and replaced them by
+      calls to cgobj
+    * u32bit-s32bit updates for and,or,xor nodes. When one element is
+      u32bit then the other is typecasted also to u32bit without giving
+      a rangecheck warning/error.
+    * fixed pascal calling method with reversing also the high tree in
+      the parast, detected by tcalcst3 test
+
+  Revision 1.5  2002/04/14 17:00:49  carl
   + att_reg2str -> gas_reg2str
 
   Revision 1.4  2002/04/04 18:31:37  carl

+ 27 - 6
compiler/i386/daopt386.pas

@@ -226,7 +226,7 @@ Var
 Implementation
 
 Uses
-  globals, systems, verbose, cgbase, symconst, symsym, tainst, cginfo, cgobj, 
+  globals, systems, verbose, cgbase, symconst, symsym, tainst, cginfo, cgobj,
    rgobj;
 
 Type
@@ -776,9 +776,9 @@ var p: Taicpu;
 begin
   RegReadByInstruction := false;
   reg := reg32(reg);
-  p := Taicpu(hp);
   if hp.typ <> ait_instruction then
     exit;
+  p := Taicpu(hp);
   case p.opcode of
     A_IMUL:
       case p.ops of
@@ -844,9 +844,9 @@ var p: Taicpu;
 begin
   reg := reg32(reg);
   regInInstruction := false;
-  p := Taicpu(p1);
   if p1.typ <> ait_instruction then
     exit;
+  p := Taicpu(p1);
   case p.opcode of
     A_IMUL:
       case p.ops of
@@ -1112,10 +1112,14 @@ function regLoadedWithNewValue(reg: tregister; canDependOnPrevValue: boolean;
 { assumes reg is a 32bit register }
 var p: Taicpu;
 begin
+  if not assigned(hp) or
+     (hp.typ <> ait_instruction) then
+   begin
+     regLoadedWithNewValue := false;
+     exit;
+   end;
   p := Taicpu(hp);
   regLoadedWithNewValue :=
-    assigned(hp) and
-    (hp.typ = ait_instruction) and
     (((p.opcode = A_MOV) or
       (p.opcode = A_MOVZX) or
       (p.opcode = A_MOVSX) or
@@ -2587,7 +2591,24 @@ End.
 
 {
   $Log$
-  Revision 1.33  2002-04-21 15:32:59  carl
+  Revision 1.34  2002-05-12 16:53:16  peter
+    * moved entry and exitcode to ncgutil and cgobj
+    * foreach gets extra argument for passing local data to the
+      iterator function
+    * -CR checks also class typecasts at runtime by changing them
+      into as
+    * fixed compiler to cycle with the -CR option
+    * fixed stabs with elf writer, finally the global variables can
+      be watched
+    * removed a lot of routines from cga unit and replaced them by
+      calls to cgobj
+    * u32bit-s32bit updates for and,or,xor nodes. When one element is
+      u32bit then the other is typecasted also to u32bit without giving
+      a rangecheck warning/error.
+    * fixed pascal calling method with reversing also the high tree in
+      the parast, detected by tcalcst3 test
+
+  Revision 1.33  2002/04/21 15:32:59  carl
   * changeregsize -> rg.makeregsize
 
   Revision 1.32  2002/04/20 21:37:07  carl

+ 52 - 35
compiler/i386/n386add.pas

@@ -154,7 +154,7 @@ interface
               { maybe we can reuse a constant register when the
                 operation is a comparison that doesn't change the
                 value of the register }
-              location_force_reg(left.location,opsize_2_cgsize[opsize],(nodetype in [ltn,lten,gtn,gten,equaln,unequaln]));
+              location_force_reg(exprasmlist,left.location,opsize_2_cgsize[opsize],(nodetype in [ltn,lten,gtn,gten,equaln,unequaln]));
             end;
           end;
        end;
@@ -294,8 +294,8 @@ interface
                emitjmp(C_NB,hl4)
               else
                emitjmp(C_NO,hl4);
-              emitcall('FPC_OVERFLOW');
-              emitlab(hl4);
+              cg.a_call_name(exprasmlist,'FPC_OVERFLOW');
+              cg.a_label(exprasmlist,hl4);
             end;
          end;
       end;
@@ -380,17 +380,17 @@ interface
                         remove_non_regvars_from_loc(right.location,regstopush);
                         rg.saveusedregisters(exprasmlist,pushedregs,regstopush);
                         { push the maximum possible length of the result }
-                        emitpushreferenceaddr(left.location.reference);
+                        cg.a_paramaddr_ref(exprasmlist,left.location.reference,2);
                         { the optimizer can more easily put the          }
                         { deallocations in the right place if it happens }
                         { too early than when it happens too late (if    }
                         { the pushref needs a "lea (..),edi; push edi")  }
                         location_release(exprasmlist,right.location);
-                        emitpushreferenceaddr(right.location.reference);
+                        cg.a_paramaddr_ref(exprasmlist,right.location.reference,1);
                         rg.saveregvars(exprasmlist,regstopush);
-                        emitcall('FPC_SHORTSTR_CONCAT');
+                        cg.a_call_name(exprasmlist,'FPC_SHORTSTR_CONCAT');
                         tg.ungetiftemp(exprasmlist,right.location.reference);
-                        maybe_loadself;
+                        cg.g_maybe_loadself(exprasmlist);
                         rg.restoreusedregisters(exprasmlist,pushedregs);
                         location_copy(location,left.location);
                      end;
@@ -400,13 +400,13 @@ interface
                        rg.saveusedregisters(exprasmlist,pushedregs,all_registers);
                        secondpass(left);
                        location_release(exprasmlist,left.location);
-                       emitpushreferenceaddr(left.location.reference);
+                       cg.a_paramaddr_ref(exprasmlist,left.location.reference,2);
                        secondpass(right);
                        location_release(exprasmlist,right.location);
-                       emitpushreferenceaddr(right.location.reference);
+                       cg.a_paramaddr_ref(exprasmlist,right.location.reference,1);
                        rg.saveregvars(exprasmlist,all_registers);
-                       emitcall('FPC_SHORTSTR_COMPARE');
-                       maybe_loadself;
+                       cg.a_call_name(exprasmlist,'FPC_SHORTSTR_COMPARE');
+                       cg.g_maybe_loadself(exprasmlist);
                        rg.restoreusedregisters(exprasmlist,pushedregs);
                        location_freetemp(exprasmlist,left.location);
                        location_freetemp(exprasmlist,right.location);
@@ -463,7 +463,7 @@ interface
               end;
             secondpass(left);
             if left.location.loc in [LOC_FLAGS,LOC_JUMP] then
-             location_force_reg(left.location,opsize_2_cgsize[opsize],false);
+             location_force_reg(exprasmlist,left.location,opsize_2_cgsize[opsize],false);
             if isjump then
              begin
                truelabel:=otl;
@@ -483,7 +483,7 @@ interface
             if pushed then
              restore(left,false);
             if right.location.loc in [LOC_FLAGS,LOC_JUMP] then
-             location_force_reg(right.location,opsize_2_cgsize[opsize],false);
+             location_force_reg(exprasmlist,right.location,opsize_2_cgsize[opsize],false);
             if isjump then
              begin
                truelabel:=otl;
@@ -532,8 +532,8 @@ interface
                         otl:=truelabel;
                         getlabel(truelabel);
                         secondpass(left);
-                        maketojumpbool(left,lr_load_regvars);
-                        emitlab(truelabel);
+                        maketojumpbool(exprasmlist,left,lr_load_regvars);
+                        cg.a_label(exprasmlist,truelabel);
                         truelabel:=otl;
                      end;
                    orn :
@@ -541,15 +541,15 @@ interface
                         ofl:=falselabel;
                         getlabel(falselabel);
                         secondpass(left);
-                        maketojumpbool(left,lr_load_regvars);
-                        emitlab(falselabel);
+                        maketojumpbool(exprasmlist,left,lr_load_regvars);
+                        cg.a_label(exprasmlist,falselabel);
                         falselabel:=ofl;
                      end;
                    else
                      CGMessage(type_e_mismatch);
                  end;
                  secondpass(right);
-                 maketojumpbool(right,lr_load_regvars);
+                 maketojumpbool(exprasmlist,right,lr_load_regvars);
                end;
              else
                CGMessage(type_e_mismatch);
@@ -642,7 +642,7 @@ interface
           end;
         { to avoid the pentium bug
         if (op=FDIVP) and (opt_processors=pentium) then
-          emitcall('EMUL_FDIVP')
+          cg.a_call_name(exprasmlist,'EMUL_FDIVP')
         else
         }
         { the Intel assemblers want operands }
@@ -748,8 +748,8 @@ interface
                  if assigned(tsetelementnode(right).right) then
                   internalerror(43244);
                  { bts requires both elements to be registers }
-                 location_force_reg(left.location,opsize_2_cgsize[opsize],false);
-                 location_force_reg(right.location,opsize_2_cgsize[opsize],true);
+                 location_force_reg(exprasmlist,left.location,opsize_2_cgsize[opsize],false);
+                 location_force_reg(exprasmlist,right.location,opsize_2_cgsize[opsize],true);
                  op:=A_BTS;
                  noswap:=true;
                end
@@ -785,7 +785,7 @@ interface
                  ((nf_swaped in flags) and
                   (nodetype = gten)) then
                 swapleftright;
-              location_force_reg(left.location,opsize_2_cgsize[opsize],true);
+              location_force_reg(exprasmlist,left.location,opsize_2_cgsize[opsize],true);
               emit_op_right_left(A_AND,opsize);
               op:=A_CMP;
               cmpop:=true;
@@ -886,17 +886,17 @@ interface
                    { the comparisaion of the low dword have to be }
                    {  always unsigned!                            }
                    emitjmp(flags_to_cond(getresflags(true)),truelabel);
-                   emitjmp(C_None,falselabel);
+                   cg.a_jmp_always(exprasmlist,falselabel);
                 end;
               equaln:
                 begin
                    emitjmp(C_NE,falselabel);
-                   emitjmp(C_None,truelabel);
+                   cg.a_jmp_always(exprasmlist,truelabel);
                 end;
               unequaln:
                 begin
                    emitjmp(C_NE,truelabel);
-                   emitjmp(C_None,falselabel);
+                   cg.a_jmp_always(exprasmlist,falselabel);
                 end;
            end;
         end;
@@ -1045,7 +1045,7 @@ interface
                     firstjmp64bitcmp;
                     emit_ref_reg(A_CMP,S_L,right.location.reference,left.location.registerlow);
                     secondjmp64bitcmp;
-                    emitjmp(C_None,falselabel);
+                    cg.a_jmp_always(exprasmlist,falselabel);
                     location_freetemp(exprasmlist,right.location);
                     location_release(exprasmlist,right.location);
                   end;
@@ -1092,8 +1092,8 @@ interface
                emitjmp(C_NB,hl4)
               else
                emitjmp(C_NO,hl4);
-              emitcall('FPC_OVERFLOW');
-              emitlab(hl4);
+              cg.a_call_name(exprasmlist,'FPC_OVERFLOW');
+              cg.a_label(exprasmlist,hl4);
             end;
          end;
 
@@ -1457,8 +1457,8 @@ interface
                    { constant (JM)                             }
                    location_release(exprasmlist,right.location);
                    location.register:=rg.getregisterint(exprasmlist);
-                   emitloadord2reg(right.location,torddef(u32bittype.def),location.register,false);
-                   emit_const_reg(A_SHL,S_L,power,location.register)
+                   cg.a_load_loc_reg(exprasmlist,right.location,location.register);
+                   cg.a_op_const_reg(exprasmlist,OP_SHL,power,location.register);
                  End
                Else
                 Begin
@@ -1485,13 +1485,13 @@ interface
                   { left.location can be R_EAX !!! }
                   rg.getexplicitregisterint(exprasmlist,R_EDI);
                   { load the left value }
-                  emitloadord2reg(left.location,torddef(u32bittype.def),R_EDI,true);
+                  cg.a_load_loc_reg(exprasmlist,left.location,R_EDI);
                   location_release(exprasmlist,left.location);
                   { allocate EAX }
                   if R_EAX in rg.unusedregsint then
                     exprasmList.concat(Tairegalloc.Alloc(R_EAX));
                   { load he right value }
-                  emitloadord2reg(right.location,torddef(u32bittype.def),R_EAX,true);
+                  cg.a_load_loc_reg(exprasmlist,right.location,R_EAX);
                   location_release(exprasmlist,right.location);
                   { allocate EAX if it isn't yet allocated (JM) }
                   if (R_EAX in rg.unusedregsint) then
@@ -1522,9 +1522,9 @@ interface
 
             { Convert flags to register first }
             if (left.location.loc=LOC_FLAGS) then
-             location_force_reg(left.location,opsize_2_cgsize[opsize],false);
+             location_force_reg(exprasmlist,left.location,opsize_2_cgsize[opsize],false);
             if (right.location.loc=LOC_FLAGS) then
-             location_force_reg(right.location,opsize_2_cgsize[opsize],false);
+             location_force_reg(exprasmlist,right.location,opsize_2_cgsize[opsize],false);
 
             left_must_be_reg(opsize,false);
             emit_generic_code(op,opsize,unsigned,extra_not,mboverflow);
@@ -1574,7 +1574,24 @@ begin
 end.
 {
   $Log$
-  Revision 1.34  2002-04-25 20:16:40  peter
+  Revision 1.35  2002-05-12 16:53:17  peter
+    * moved entry and exitcode to ncgutil and cgobj
+    * foreach gets extra argument for passing local data to the
+      iterator function
+    * -CR checks also class typecasts at runtime by changing them
+      into as
+    * fixed compiler to cycle with the -CR option
+    * fixed stabs with elf writer, finally the global variables can
+      be watched
+    * removed a lot of routines from cga unit and replaced them by
+      calls to cgobj
+    * u32bit-s32bit updates for and,or,xor nodes. When one element is
+      u32bit then the other is typecasted also to u32bit without giving
+      a rangecheck warning/error.
+    * fixed pascal calling method with reversing also the high tree in
+      the parast, detected by tcalcst3 test
+
+  Revision 1.34  2002/04/25 20:16:40  peter
     * moved more routines from cga/n386util
 
   Revision 1.33  2002/04/05 15:09:13  jonas

+ 148 - 139
compiler/i386/n386cal.pas

@@ -89,6 +89,7 @@ implementation
          otlabel,oflabel : tasmlabel;
          { temporary variables: }
          tempdeftype : tdeftype;
+         tmpreg : tregister;
          href   : treference;
 
       begin
@@ -118,7 +119,7 @@ implementation
              if push_addr_param(left.resulttype.def) then
                begin
                  inc(pushedparasize,4);
-                 emitpushreferenceaddr(left.location.reference);
+                 cg.a_paramaddr_ref(exprasmlist,left.location.reference,-1);
                  location_release(exprasmlist,left.location);
                end
              else
@@ -136,22 +137,21 @@ implementation
               { allow passing of a constant to a const formaldef }
               if (defcoll.paratyp=vs_const) and
                  (left.location.loc=LOC_CONSTANT) then
-                location_force_mem(left.location);
+                location_force_mem(exprasmlist,left.location);
 
               { allow @var }
               inc(pushedparasize,4);
               if (left.nodetype=addrn) and
                  (not(nf_procvarload in left.flags)) then
                 begin
-                { always a register }
                   if inlined then
                     begin
                        reference_reset_base(href,procinfo^.framepointer,para_offset-pushedparasize);
-                       emit_reg_ref(A_MOV,S_L,left.location.register,href);
+                       cg.a_load_loc_ref(exprasmlist,left.location,href);
                     end
                   else
-                    emit_reg(A_PUSH,S_L,left.location.register);
-                  rg.ungetregisterint(exprasmlist,left.location.register);
+                    cg.a_param_loc(exprasmlist,left.location,-1);
+                  location_release(exprasmlist,left.location);
                 end
               else
                 begin
@@ -161,11 +161,11 @@ implementation
                      begin
                        if inlined then
                          begin
-                           rg.getexplicitregisterint(exprasmlist,R_EDI);
-                           emit_ref_reg(A_LEA,S_L,left.location.reference,R_EDI);
+                           tmpreg:=cg.get_scratch_reg(exprasmlist);
+                           cg.a_loadaddr_ref_reg(exprasmlist,left.location.reference,tmpreg);
                            reference_reset_base(href,procinfo^.framepointer,para_offset-pushedparasize);
-                           emit_reg_ref(A_MOV,S_L,R_EDI,href);
-                           rg.ungetregisterint(exprasmlist,R_EDI);
+                           cg.a_load_reg_ref(exprasmlist,OS_ADDR,tmpreg,href);
+                           cg.free_scratch_reg(exprasmlist,tmpreg);
                          end
                        else
                          cg.a_paramaddr_ref(exprasmlist,left.location.reference,-1);
@@ -202,11 +202,11 @@ implementation
               inc(pushedparasize,4);
               if inlined then
                 begin
-                   rg.getexplicitregisterint(exprasmlist,R_EDI);
-                   emit_ref_reg(A_LEA,S_L,left.location.reference,R_EDI);
+                   tmpreg:=cg.get_scratch_reg(exprasmlist);
+                   cg.a_loadaddr_ref_reg(exprasmlist,left.location.reference,tmpreg);
                    reference_reset_base(href,procinfo^.framepointer,para_offset-pushedparasize);
-                   emit_reg_ref(A_MOV,S_L,R_EDI,href);
-                   rg.ungetregisterint(exprasmlist,R_EDI);
+                   cg.a_load_reg_ref(exprasmlist,OS_ADDR,tmpreg,href);
+                   cg.free_scratch_reg(exprasmlist,tmpreg);
                 end
               else
                 cg.a_paramaddr_ref(exprasmlist,left.location.reference,-1);
@@ -249,11 +249,11 @@ implementation
                    inc(pushedparasize,4);
                    if inlined then
                      begin
-                        rg.getexplicitregisterint(exprasmlist,R_EDI);
-                        emit_ref_reg(A_LEA,S_L,left.location.reference,R_EDI);
+                        tmpreg:=cg.get_scratch_reg(exprasmlist);
+                        cg.a_loadaddr_ref_reg(exprasmlist,left.location.reference,tmpreg);
                         reference_reset_base(href,procinfo^.framepointer,para_offset-pushedparasize);
-                        emit_reg_ref(A_MOV,S_L,R_EDI,href);
-                        rg.ungetregisterint(exprasmlist,R_EDI);
+                        cg.a_load_reg_ref(exprasmlist,OS_ADDR,tmpreg,href);
+                        cg.free_scratch_reg(exprasmlist,tmpreg);
                      end
                    else
                      cg.a_paramaddr_ref(exprasmlist,left.location.reference,-1);
@@ -290,6 +290,7 @@ implementation
          unusedstate: pointer;
          pushed : tpushedsaved;
          funcretref,refcountedtemp : treference;
+         tmpreg : tregister;
          hregister : tregister;
          oldpushedparasize : longint;
          { true if ESI must be loaded again after the subroutine }
@@ -306,6 +307,7 @@ implementation
          i : longint;
          { help reference pointer }
          href : treference;
+         hrefvmt : treference;
          hp : tnode;
          pp : tbinarynode;
          params : tnode;
@@ -325,7 +327,7 @@ implementation
          push_size : longint;
 {$endif OPTALIGN}
          pop_allowed : boolean;
-         release_edi : boolean;
+         release_tmpreg : boolean;
          constructorfailed : tasmlabel;
 
       label
@@ -402,7 +404,7 @@ implementation
                  not(po_iocheck in aktprocdef.procoptions) then
                 begin
                    getaddrlabel(iolabel);
-                   emitlab(iolabel);
+                   cg.a_label(exprasmlist,iolabel);
                 end
               else
                 iolabel:=nil;
@@ -586,9 +588,9 @@ implementation
                    if ((not(nf_islocal in twithnode(twithsymtable(symtableproc).withnode).flags)) and
                        (not twithsymtable(symtableproc).direct_with)) or
                       is_class_or_interface(methodpointer.resulttype.def) then
-                     emit_ref_reg(A_MOV,S_L,href,R_ESI)
+                     cg.a_load_ref_reg(exprasmlist,OS_ADDR,href,self_pointer_reg)
                    else
-                     emit_ref_reg(A_LEA,S_L,href,R_ESI);
+                     cg.a_loadaddr_ref_reg(exprasmlist,href,self_pointer_reg);
                 end;
 
               { push self }
@@ -629,12 +631,11 @@ implementation
                                          { if no VMT just use $0 bug0214 PM }
                                          rg.getexplicitregisterint(exprasmlist,R_ESI);
                                          if not(oo_has_vmt in tobjectdef(methodpointer.resulttype.def).objectoptions) then
-                                           emit_const_reg(A_MOV,S_L,0,R_ESI)
+                                           cg.a_load_const_reg(exprasmlist,OS_ADDR,0,self_pointer_reg)
                                          else
                                            begin
-                                             emit_sym_ofs_reg(A_MOV,S_L,
-                                               newasmsymbol(tobjectdef(methodpointer.resulttype.def).vmt_mangledname),
-                                               0,R_ESI);
+                                             reference_reset_symbol(href,newasmsymbol(tobjectdef(methodpointer.resulttype.def).vmt_mangledname),0);
+                                             cg.a_loadaddr_ref_reg(exprasmlist,href,self_pointer_reg);
                                            end;
                                          { emit_reg(A_PUSH,S_L,R_ESI);
                                            this is done below !! }
@@ -647,15 +648,15 @@ implementation
                                     if is_class(tobjectdef(methodpointer.resulttype.def)) and
                                        (procdefinition.proctypeoption=potype_destructor) then
                                       begin
-                                        push_int(0);
-                                        emit_reg(A_PUSH,S_L,R_ESI);
+                                        cg.a_param_const(exprasmlist,OS_ADDR,0,2);
+                                        cg.a_param_reg(exprasmlist,OS_ADDR,self_pointer_reg,1);
                                       end;
 
                                     if not(is_con_or_destructor and
                                            is_class(methodpointer.resulttype.def) and
                                            (procdefinition.proctypeoption in [potype_constructor,potype_destructor])
                                           ) then
-                                      emit_reg(A_PUSH,S_L,R_ESI);
+                                      cg.a_param_reg(exprasmlist,OS_ADDR,self_pointer_reg,1);
                                     { if an inherited con- or destructor should be  }
                                     { called in a con- or destructor then a warning }
                                     { will be made                                  }
@@ -678,8 +679,8 @@ implementation
                                       begin
                                          { a constructor needs also a flag }
                                          if is_class(methodpointer.resulttype.def) then
-                                           push_int(0);
-                                         push_int(0);
+                                           cg.a_param_const(exprasmlist,OS_ADDR,0,2);
+                                         cg.a_param_const(exprasmlist,OS_ADDR,0,1);
                                       end;
                                  end;
                                hnewn:
@@ -687,11 +688,11 @@ implementation
                                     { extended syntax of new }
                                     { ESI must be zero }
                                     rg.getexplicitregisterint(exprasmlist,R_ESI);
-                                    emit_reg_reg(A_XOR,S_L,R_ESI,R_ESI);
-                                    emit_reg(A_PUSH,S_L,R_ESI);
+                                    cg.a_load_const_reg(exprasmlist,OS_ADDR,0,self_pointer_reg);
+                                    cg.a_param_reg(exprasmlist,OS_ADDR,self_pointer_reg,2);
                                     { insert the vmt }
-                                    emit_sym(A_PUSH,S_L,
-                                      newasmsymbol(tobjectdef(methodpointer.resulttype.def).vmt_mangledname));
+                                    reference_reset_symbol(href,newasmsymbol(tobjectdef(methodpointer.resulttype.def).vmt_mangledname),0);
+                                    cg.a_paramaddr_ref(exprasmlist,href,1);
                                     extended_new:=true;
                                  end;
                                hdisposen:
@@ -703,9 +704,9 @@ implementation
                                     rg.getexplicitregisterint(exprasmlist,R_ESI);
                                     emit_ref_reg(A_LEA,S_L,methodpointer.location.reference,R_ESI);
                                     reference_release(exprasmlist,methodpointer.location.reference);
-                                    emit_reg(A_PUSH,S_L,R_ESI);
-                                    emit_sym(A_PUSH,S_L,
-                                      newasmsymbol(tobjectdef(methodpointer.resulttype.def).vmt_mangledname));
+                                    cg.a_param_reg(exprasmlist,OS_ADDR,self_pointer_reg,2);
+                                    reference_reset_symbol(href,newasmsymbol(tobjectdef(methodpointer.resulttype.def).vmt_mangledname),0);
+                                    cg.a_paramaddr_ref(exprasmlist,href,1);
                                  end;
                                else
                                  begin
@@ -718,16 +719,16 @@ implementation
                                             LOC_CREGISTER,
                                             LOC_REGISTER:
                                               begin
-                                                 emit_reg_reg(A_MOV,S_L,methodpointer.location.register,R_ESI);
+                                                 cg.a_load_reg_reg(exprasmlist,OS_ADDR,methodpointer.location.register,R_ESI);
                                                  rg.ungetregisterint(exprasmlist,methodpointer.location.register);
                                               end;
                                             else
                                               begin
                                                  if (methodpointer.resulttype.def.deftype=classrefdef) or
                                                     is_class_or_interface(methodpointer.resulttype.def) then
-                                                   emit_ref_reg(A_MOV,S_L,methodpointer.location.reference,R_ESI)
+                                                   cg.a_load_ref_reg(exprasmlist,OS_ADDR,methodpointer.location.reference,R_ESI)
                                                  else
-                                                   emit_ref_reg(A_LEA,S_L,methodpointer.location.reference,R_ESI);
+                                                   cg.a_loadaddr_ref_reg(exprasmlist,methodpointer.location.reference,R_ESI);
                                                  reference_release(exprasmlist,methodpointer.location.reference);
                                               end;
                                          end;
@@ -742,20 +743,20 @@ implementation
                                              { class method needs current VMT }
                                              rg.getexplicitregisterint(exprasmlist,R_ESI);
                                              reference_reset_base(href,R_ESI,tprocdef(procdefinition)._class.vmt_offset);
-                                             emit_ref_reg(A_MOV,S_L,href,R_ESI);
+                                             cg.a_load_ref_reg(exprasmlist,OS_ADDR,href,self_pointer_reg);
                                           end;
 
                                         { direct call to destructor: remove data }
                                         if (procdefinition.proctypeoption=potype_destructor) and
                                            is_class(methodpointer.resulttype.def) then
-                                          emit_const(A_PUSH,S_L,1);
+                                          cg.a_param_const(exprasmlist,OS_INT,1,1);
 
                                         { direct call to class constructor, don't allocate memory }
                                         if (procdefinition.proctypeoption=potype_constructor) and
                                            is_class(methodpointer.resulttype.def) then
                                           begin
-                                             emit_const(A_PUSH,S_L,0);
-                                             emit_const(A_PUSH,S_L,0);
+                                             cg.a_param_const(exprasmlist,OS_INT,0,2);
+                                             cg.a_param_const(exprasmlist,OS_INT,0,1);
                                           end
                                         else
                                           begin
@@ -763,8 +764,8 @@ implementation
                                              if (procdefinition.proctypeoption=potype_constructor) and
                                                 (methodpointer.resulttype.def.deftype=classrefdef) and
                                                 is_class(tclassrefdef(methodpointer.resulttype.def).pointertype.def) then
-                                                emit_const(A_PUSH,S_L,1);
-                                             emit_reg(A_PUSH,S_L,R_ESI);
+                                               cg.a_param_const(exprasmlist,OS_INT,1,1);
+                                             cg.a_param_reg(exprasmlist,OS_ADDR,self_pointer_reg,1);
                                           end;
                                       end;
 
@@ -775,14 +776,15 @@ implementation
                                            begin
                                               if (procdefinition.proctypeoption=potype_constructor) then
                                                 begin
-                                                   { it's no bad idea, to insert the VMT }
-                                                   emit_sym(A_PUSH,S_L,newasmsymbol(
-                                                     tobjectdef(methodpointer.resulttype.def).vmt_mangledname));
+                                                  { it's no bad idea, to insert the VMT }
+                                                  reference_reset_symbol(href,newasmsymbol(
+                                                     tobjectdef(methodpointer.resulttype.def).vmt_mangledname),0);
+                                                  cg.a_paramaddr_ref(exprasmlist,href,1);
                                                 end
                                               { destructors haven't to dispose the instance, if this is }
                                               { a direct call                                           }
                                               else
-                                                push_int(0);
+                                                cg.a_param_const(exprasmlist,OS_INT,0,1);
                                            end;
                                       end;
                                  end;
@@ -800,7 +802,7 @@ implementation
                              { class method needs current VMT }
                              rg.getexplicitregisterint(exprasmlist,R_ESI);
                              reference_reset_base(href,R_ESI,tprocdef(procdefinition)._class.vmt_offset);
-                             emit_ref_reg(A_MOV,S_L,href,R_ESI);
+                             cg.a_load_ref_reg(exprasmlist,OS_ADDR,href,R_ESI);
                           end
                         else
                           begin
@@ -812,32 +814,32 @@ implementation
                           begin
                              if (procdefinition.proctypeoption=potype_destructor) then
                                begin
-                                  emit_const(A_PUSH,S_L,0);
-                                  emit_reg(A_PUSH,S_L,R_ESI);
+                                  cg.a_param_const(exprasmlist,OS_INT,0,2);
+                                  cg.a_param_reg(exprasmlist,OS_ADDR,R_ESI,1);
                                end
                              else if (procdefinition.proctypeoption=potype_constructor) then
                                begin
-                                  emit_const(A_PUSH,S_L,0);
-                                  emit_const(A_PUSH,S_L,0);
+                                  cg.a_param_const(exprasmlist,OS_INT,0,2);
+                                  cg.a_param_const(exprasmlist,OS_INT,0,1);
                                end
                              else
-                               emit_reg(A_PUSH,S_L,R_ESI);
+                               cg.a_param_reg(exprasmlist,OS_ADDR,R_ESI,1);
                           end
                         else if is_object(procinfo^._class) then
                           begin
-                             emit_reg(A_PUSH,S_L,R_ESI);
+                             cg.a_param_reg(exprasmlist,OS_ADDR,R_ESI,1);
                              if is_con_or_destructor then
                                begin
                                   if (procdefinition.proctypeoption=potype_constructor) then
                                     begin
-                                       { it's no bad idea, to insert the VMT }
-                                       emit_sym(A_PUSH,S_L,newasmsymbol(
-                                         procinfo^._class.vmt_mangledname));
+                                      { it's no bad idea, to insert the VMT }
+                                      reference_reset_symbol(href,newasmsymbol(procinfo^._class.vmt_mangledname),0);
+                                      cg.a_paramaddr_ref(exprasmlist,href,1);
                                     end
                                   { destructors haven't to dispose the instance, if this is }
                                   { a direct call                                           }
                                   else
-                                    push_int(0);
+                                    cg.a_param_const(exprasmlist,OS_INT,0,1);
                                end;
                           end
                         else
@@ -853,13 +855,13 @@ implementation
                    (inlined or
                    (right=nil)) then
                   begin
-                     emit_reg(A_PUSH,S_L,R_ESI);
-                     reference_reset_base(href,R_ESI,0);
-                     rg.getexplicitregisterint(exprasmlist,R_EDI);
-                     emit_ref_reg(A_MOV,S_L,href,R_EDI);
-                     reference_reset_base(href,R_EDI,72);
-                     emit_ref(A_CALL,S_NO,href);
-                     rg.ungetregisterint(exprasmlist,R_EDI);
+                     cg.a_param_reg(exprasmlist,OS_ADDR,self_pointer_reg,1);
+                     reference_reset_base(href,self_pointer_reg,0);
+                     tmpreg:=cg.get_scratch_reg(exprasmlist);
+                     cg.a_load_ref_reg(exprasmlist,OS_ADDR,href,tmpreg);
+                     reference_reset_base(href,tmpreg,72);
+                     cg.a_call_ref(exprasmlist,href);
+                     cg.free_scratch_reg(exprasmlist,tmpreg);
                   end;
 
               { push base pointer ?}
@@ -883,27 +885,27 @@ implementation
                      if lexlevel=(tprocdef(procdefinition).parast.symtablelevel) then
                        begin
                           reference_reset_base(href,procinfo^.framepointer,procinfo^.framepointer_offset);
-                          emit_ref(A_PUSH,S_L,href)
+                          cg.a_param_ref(exprasmlist,OS_ADDR,href,-1);
                        end
                        { this is only true if the difference is one !!
                          but it cannot be more !! }
                      else if (lexlevel=(tprocdef(procdefinition).parast.symtablelevel)-1) then
                        begin
-                          emit_reg(A_PUSH,S_L,procinfo^.framepointer)
+                          cg.a_param_reg(exprasmlist,OS_ADDR,procinfo^.framepointer,-1);
                        end
                      else if (lexlevel>(tprocdef(procdefinition).parast.symtablelevel)) then
                        begin
                           hregister:=rg.getregisterint(exprasmlist);
                           reference_reset_base(href,procinfo^.framepointer,procinfo^.framepointer_offset);
-                          emit_ref_reg(A_MOV,S_L,href,hregister);
+                          cg.a_load_ref_reg(exprasmlist,OS_ADDR,href,hregister);
                           for i:=(tprocdef(procdefinition).parast.symtablelevel) to lexlevel-1 do
                             begin
                                {we should get the correct frame_pointer_offset at each level
                                how can we do this !!! }
                                reference_reset_base(href,hregister,procinfo^.framepointer_offset);
-                               emit_ref_reg(A_MOV,S_L,href,hregister);
+                               cg.a_load_ref_reg(exprasmlist,OS_ADDR,href,hregister);
                             end;
-                          emit_reg(A_PUSH,S_L,hregister);
+                          cg.a_param_reg(exprasmlist,OS_ADDR,hregister,-1);
                           rg.ungetregisterint(exprasmlist,hregister);
                        end
                      else
@@ -919,7 +921,7 @@ implementation
                    { also class methods                       }
                    { Here it is quite tricky because it also depends }
                    { on the methodpointer                        PM }
-                   release_edi:=false;
+                   release_tmpreg:=false;
                    rg.getexplicitregisterint(exprasmlist,R_ESI);
                    if assigned(aktprocdef) then
                      begin
@@ -943,48 +945,39 @@ implementation
                          begin
                             { this is one point where we need vmt_offset (PM) }
                             reference_reset_base(href,R_ESI,tprocdef(procdefinition)._class.vmt_offset);
-                            rg.getexplicitregisterint(exprasmlist,R_EDI);
-                            emit_ref_reg(A_MOV,S_L,href,R_EDI);
-                            reference_reset_base(href,R_EDI,0);
-                            release_edi:=true;
+                            tmpreg:=cg.get_scratch_reg(exprasmlist);
+                            cg.a_load_ref_reg(exprasmlist,OS_ADDR,href,tmpreg);
+                            reference_reset_base(href,tmpreg,0);
+                            release_tmpreg:=true;
                          end;
                      end
                    else
                      { aktprocdef should be assigned, also in main program }
                      internalerror(12345);
-                   {
-                     begin
-                       new(r);
-                       reset_reference(r^);
-                       r^.base:=R_ESI;
-                       emit_ref_reg(A_MOV,S_L,r,R_EDI);
-                       new(r);
-                       reset_reference(r^);
-                       r^.base:=R_EDI;
-                     end;
-                   }
+
                    if tprocdef(procdefinition).extnumber=-1 then
                      internalerror(44584);
+
                    href.offset:=tprocdef(procdefinition)._class.vmtmethodoffset(tprocdef(procdefinition).extnumber);
                    if not(is_interface(tprocdef(procdefinition)._class)) and
-                     not(is_cppclass(tprocdef(procdefinition)._class)) then
+                      not(is_cppclass(tprocdef(procdefinition)._class)) then
                      begin
-                        if (cs_check_object_ext in aktlocalswitches) then
+                        if (cs_check_object in aktlocalswitches) then
                           begin
-                             emit_sym(A_PUSH,S_L,
-                               newasmsymbol(tprocdef(procdefinition)._class.vmt_mangledname));
-                             emit_reg(A_PUSH,S_L,href.base);
-                             emitcall('FPC_CHECK_OBJECT_EXT');
+                             reference_reset_symbol(hrefvmt,newasmsymbol(tprocdef(procdefinition)._class.vmt_mangledname),0);
+                             cg.a_paramaddr_ref(exprasmlist,hrefvmt,2);
+                             cg.a_param_reg(exprasmlist,OS_ADDR,href.base,1);
+                             cg.a_call_name(exprasmlist,'FPC_CHECK_OBJECT_EXT');
                           end
                         else if (cs_check_range in aktlocalswitches) then
                           begin
-                             emit_reg(A_PUSH,S_L,href.base);
-                             emitcall('FPC_CHECK_OBJECT');
+                             cg.a_param_reg(exprasmlist,OS_ADDR,href.base,1);
+                             cg.a_call_name(exprasmlist,'FPC_CHECK_OBJECT');
                           end;
                      end;
-                   emit_ref(A_CALL,S_NO,href);
-                   if release_edi then
-                     rg.ungetregisterint(exprasmlist,R_EDI);
+                   cg.a_call_ref(exprasmlist,href);
+                   if release_tmpreg then
+                     cg.free_scratch_reg(exprasmlist,tmpreg);
                 end
               else if not inlined then
                 begin
@@ -995,7 +988,7 @@ implementation
                         emit_none(A_PUSHF,S_L);
                         emit_reg(A_PUSH,S_L,R_CS);
                     end;
-                  emitcall(tprocdef(procdefinition).mangledname);
+                  cg.a_call_name(exprasmlist,tprocdef(procdefinition).mangledname);
                 end
               else { inlined proc }
                 { inlined code is in inlinecode }
@@ -1029,32 +1022,31 @@ implementation
                       (right.location.reference.index=R_ESI) then
                      begin
                         reference_release(exprasmlist,right.location.reference);
-                        rg.getexplicitregisterint(exprasmlist,R_EDI);
-                        emit_ref_reg(A_MOV,S_L,right.location.reference,R_EDI);
-                        hregister:=R_EDI;
+                        hregister:=cg.get_scratch_reg(exprasmlist);
+                        cg.a_load_ref_reg(exprasmlist,OS_ADDR,right.location.reference,hregister);
                      end;
 
                    { load self, but not if it's already explicitly pushed }
                    if not(po_containsself in procdefinition.procoptions) then
                      begin
                        { load ESI }
-                       inc(right.location.reference.offset,4);
+                       href:=right.location.reference;
+                       inc(href.offset,4);
                        rg.getexplicitregisterint(exprasmlist,R_ESI);
-                       emit_ref_reg(A_MOV,S_L,right.location.reference,R_ESI);
-                       dec(right.location.reference.offset,4);
+                       cg.a_load_ref_reg(exprasmlist,OS_ADDR,href,self_pointer_reg);
                        { push self pointer }
-                       emit_reg(A_PUSH,S_L,R_ESI);
+                       cg.a_param_reg(exprasmlist,OS_ADDR,self_pointer_reg,-1);
                      end;
 
                    rg.saveregvars(exprasmlist,ALL_REGISTERS);
-                   if hregister=R_NO then
-                     emit_ref(A_CALL,S_NO,right.location.reference)
+                   if hregister<>R_NO then
+                     reference_reset_base(href,hregister,0)
                    else
-                     begin
-                       emit_reg(A_CALL,S_NO,hregister);
-                       rg.ungetregisterint(exprasmlist,hregister);
-                     end;
+                     href:=right.location.reference;
+                   cg.a_call_ref(exprasmlist,href);
 
+                   if hregister<>R_NO then
+                     cg.free_scratch_reg(exprasmlist,hregister);
                    reference_release(exprasmlist,right.location.reference);
                 end
               else
@@ -1062,12 +1054,13 @@ implementation
                    rg.saveregvars(exprasmlist,ALL_REGISTERS);
                    case right.location.loc of
                       LOC_REGISTER,LOC_CREGISTER:
-                        emit_reg(A_CALL,S_NO,right.location.register);
+                        reference_reset_base(href,right.location.register,0);
                       LOC_REFERENCE,LOC_CREFERENCE :
-                        emit_ref(A_CALL,S_NO,right.location.reference);
+                        href:=right.location.reference;
                       else
                         internalerror(200203311);
                    end;
+                   cg.a_call_ref(exprasmlist,href);
                    location_release(exprasmlist,right.location);
                 end;
            end;
@@ -1138,16 +1131,16 @@ implementation
            begin
               getlabel(constructorfailed);
               emitjmp(C_Z,constructorfailed);
-              emit_reg(A_PUSH,S_L,R_ESI);
-              reference_reset_base(href,R_ESI,0);
-              rg.getexplicitregisterint(exprasmlist,R_EDI);
-              emit_ref_reg(A_MOV,S_L,href,R_EDI);
-              reference_reset_base(href,R_EDI,68);
-              emit_ref(A_CALL,S_NO,href);
-              rg.ungetregisterint(exprasmlist,R_EDI);
-              exprasmList.concat(Tairegalloc.Alloc(R_EAX));
-              emitlab(constructorfailed);
-              emit_reg_reg(A_MOV,S_L,R_ESI,R_EAX);
+              cg.a_param_reg(exprasmlist,OS_ADDR,self_pointer_reg,1);
+              reference_reset_base(href,self_pointer_reg,0);
+              tmpreg:=cg.get_scratch_reg(exprasmlist);
+              cg.a_load_ref_reg(exprasmlist,OS_ADDR,href,tmpreg);
+              reference_reset_base(href,tmpreg,68);
+              cg.a_call_ref(exprasmlist,href);
+              cg.free_scratch_reg(exprasmlist,tmpreg);
+              exprasmList.concat(Tairegalloc.Alloc(accumulator));
+              cg.a_label(exprasmlist,constructorfailed);
+              cg.a_load_reg_reg(exprasmlist,OS_ADDR,self_pointer_reg,accumulator);
            end;
 
          { handle function results }
@@ -1244,8 +1237,9 @@ implementation
          { perhaps i/o check ? }
          if iolabel<>nil then
            begin
-              emit_sym(A_PUSH,S_L,iolabel);
-              emitcall('FPC_IOCHECK');
+              reference_reset_symbol(href,iolabel,0);
+              cg.a_paramaddr_ref(exprasmlist,href,1);
+              cg.a_call_name(exprasmlist,'FPC_IOCHECK');
            end;
          if pop_size>0 then
            emit_const_reg(A_ADD,S_L,pop_size,R_ESP);
@@ -1255,15 +1249,14 @@ implementation
 
          { at last, restore instance pointer (SELF) }
          if loadesi then
-           maybe_loadself;
+           cg.g_maybe_loadself(exprasmlist);
          pp:=tbinarynode(params);
          while assigned(pp) do
            begin
               if assigned(pp.left) then
                 begin
-                  if (pp.left.location.loc in [LOC_REFERENCE,LOC_CREFERENCE]) then
-                    tg.ungetiftemp(exprasmlist,pp.left.location.reference);
-                { process also all nodes of an array of const }
+                  location_freetemp(exprasmlist,pp.left.location);
+                  { process also all nodes of an array of const }
                   if pp.left.nodetype=arrayconstructorn then
                     begin
                       if assigned(tarrayconstructornode(pp.left).left) then
@@ -1271,9 +1264,8 @@ implementation
                          hp:=pp.left;
                          while assigned(hp) do
                           begin
-                            if (tarrayconstructornode(tunarynode(hp).left).location.loc in [LOC_REFERENCE,LOC_CREFERENCE]) then
-                              tg.ungetiftemp(exprasmlist,tarrayconstructornode(hp).left.location.reference);
-                            hp:=tbinarynode(hp).right;
+                            location_freetemp(exprasmlist,tarrayconstructornode(hp).left.location);
+                            hp:=tarrayconstructornode(hp).right;
                           end;
                        end;
                     end;
@@ -1401,7 +1393,7 @@ implementation
             begin
               getaddrlabel(startlabel);
               getaddrlabel(endlabel);
-              emitlab(startlabel);
+              cg.a_label(exprasmlist,startlabel);
               inlineprocdef.localst.symtabletype:=inlinelocalsymtable;
               inlineprocdef.parast.symtabletype:=inlineparasymtable;
 
@@ -1457,7 +1449,7 @@ implementation
 {$ifdef GDB}
           if (cs_debuginfo in aktmoduleswitches) then
             begin
-              emitlab(endlabel);
+              cg.a_label(exprasmlist,endlabel);
               strpcopy(pp,'224,0,0,'+endlabel.name);
              if (target_info.use_function_relative_addresses) then
                begin
@@ -1492,7 +1484,24 @@ begin
 end.
 {
   $Log$
-  Revision 1.48  2002-04-25 20:16:40  peter
+  Revision 1.49  2002-05-12 16:53:17  peter
+    * moved entry and exitcode to ncgutil and cgobj
+    * foreach gets extra argument for passing local data to the
+      iterator function
+    * -CR checks also class typecasts at runtime by changing them
+      into as
+    * fixed compiler to cycle with the -CR option
+    * fixed stabs with elf writer, finally the global variables can
+      be watched
+    * removed a lot of routines from cga unit and replaced them by
+      calls to cgobj
+    * u32bit-s32bit updates for and,or,xor nodes. When one element is
+      u32bit then the other is typecasted also to u32bit without giving
+      a rangecheck warning/error.
+    * fixed pascal calling method with reversing also the high tree in
+      the parast, detected by tcalcst3 test
+
+  Revision 1.48  2002/04/25 20:16:40  peter
     * moved more routines from cga/n386util
 
   Revision 1.47  2002/04/21 19:02:07  peter

+ 73 - 63
compiler/i386/n386cnv.pas

@@ -65,7 +65,7 @@ implementation
       symconst,symdef,aasm,
       cginfo,cgbase,pass_2,
       ncon,ncal,ncnv,
-      cpubase,
+      cpubase,cpuasm,
       cgobj,cga,tgobj,rgobj,rgcpu,ncgutil;
 
 
@@ -76,63 +76,56 @@ implementation
     procedure ti386typeconvnode.second_int_to_real;
 
       var
-         r : treference;
+         href : treference;
          hregister : tregister;
          l1,l2 : tasmlabel;
+         freereg : boolean;
 
       begin
          location_reset(location,LOC_FPUREGISTER,def_cgsize(resulttype.def));
+         hregister:=R_NO;
+         freereg:=false;
+
          { for u32bit a solution is to push $0 and to load a comp }
          { does this first, it destroys maybe EDI }
-         hregister:=R_EDI;
          if torddef(left.resulttype.def).typ=u32bit then
-            push_int(0);
+          exprasmlist.concat(taicpu.op_const(A_PUSH,S_L,0));
 
          case left.location.loc of
            LOC_REGISTER,
            LOC_CREGISTER :
              begin
-                if not (torddef(left.resulttype.def).typ in [u32bit,s32bit,u64bit,s64bit]) then
-                  rg.getexplicitregisterint(exprasmlist,R_EDI);
-                case torddef(left.resulttype.def).typ of
-                   s8bit : emit_reg_reg(A_MOVSX,S_BL,left.location.register,R_EDI);
-                   u8bit : emit_reg_reg(A_MOVZX,S_BL,left.location.register,R_EDI);
-                   s16bit : emit_reg_reg(A_MOVSX,S_WL,left.location.register,R_EDI);
-                   u16bit : emit_reg_reg(A_MOVZX,S_WL,left.location.register,R_EDI);
-                   u32bit,s32bit:
-                     hregister:=left.location.register;
-                   u64bit,s64bit:
-                     begin
-                        emit_reg(A_PUSH,S_L,left.location.registerhigh);
-                        hregister:=left.location.registerlow;
-                     end;
-                end;
-              end;
-            LOC_REFERENCE,
-            LOC_CREFERENCE :
-              begin
-                r:=left.location.reference;
-                rg.getexplicitregisterint(exprasmlist,R_EDI);
-                case torddef(left.resulttype.def).typ of
-                   s8bit:
-                     emit_ref_reg(A_MOVSX,S_BL,r,R_EDI);
-                   u8bit:
-                     emit_ref_reg(A_MOVZX,S_BL,r,R_EDI);
-                   s16bit:
-                     emit_ref_reg(A_MOVSX,S_WL,r,R_EDI);
-                   u16bit:
-                     emit_ref_reg(A_MOVZX,S_WL,r,R_EDI);
-                   u32bit,s32bit:
-                     emit_ref_reg(A_MOV,S_L,r,R_EDI);
-                   u64bit,s64bit:
-                     begin
-                        inc(r.offset,4);
-                        emit_ref_reg(A_MOV,S_L,r,R_EDI);
-                        emit_reg(A_PUSH,S_L,R_EDI);
-                        r:=left.location.reference;
-                        emit_ref_reg(A_MOV,S_L,r,R_EDI);
-                     end;
-                end;
+               case left.location.size of
+                 OS_64,OS_S64 :
+                   begin
+                     exprasmlist.concat(taicpu.op_reg(A_PUSH,S_L,left.location.registerhigh));
+                     hregister:=left.location.registerlow;
+                   end;
+                 OS_32,OS_S32 :
+                   hregister:=left.location.register;
+                 else
+                   begin
+                     hregister:=cg.get_scratch_reg(exprasmlist);
+                     freereg:=true;
+                     cg.a_load_reg_reg(exprasmlist,left.location.size,left.location.register,hregister);
+                   end;
+               end;
+             end;
+           LOC_REFERENCE,
+           LOC_CREFERENCE :
+             begin
+               hregister:=cg.get_scratch_reg(exprasmlist);
+               freereg:=true;
+               if left.location.size in [OS_64,OS_S64] then
+                begin
+                  href:=left.location.reference;
+                  inc(href.offset,4);
+                  cg.a_load_ref_reg(exprasmlist,OS_32,href,hregister);
+                  exprasmlist.concat(taicpu.op_reg(A_PUSH,S_L,hregister));
+                  cg.a_load_ref_reg(exprasmlist,OS_32,left.location.reference,hregister);
+                end
+               else
+                cg.a_load_ref_reg(exprasmlist,left.location.size,left.location.reference,hregister);
              end;
            else
              internalerror(2002032218);
@@ -141,19 +134,19 @@ implementation
          location_freetemp(exprasmlist,left.location);
 
          { for 64 bit integers, the high dword is already pushed }
-         emit_reg(A_PUSH,S_L,hregister);
-         if hregister = R_EDI then
-           rg.ungetregisterint(exprasmlist,R_EDI);
-         reference_reset_base(r,R_ESP,0);
+         exprasmlist.concat(taicpu.op_reg(A_PUSH,S_L,hregister));
+         if freereg then
+           cg.free_scratch_reg(exprasmlist,hregister);
+         reference_reset_base(href,R_ESP,0);
          case torddef(left.resulttype.def).typ of
            u32bit:
              begin
-                emit_ref(A_FILD,S_IQ,r);
+                emit_ref(A_FILD,S_IQ,href);
                 emit_const_reg(A_ADD,S_L,8,R_ESP);
              end;
            s64bit:
              begin
-                emit_ref(A_FILD,S_IQ,r);
+                emit_ref(A_FILD,S_IQ,href);
                 emit_const_reg(A_ADD,S_L,8,R_ESP);
              end;
            u64bit:
@@ -162,15 +155,15 @@ implementation
                 { we load bits 0..62 and then check bit 63:  }
                 { if it is 1 then we add $80000000 000000000 }
                 { as double                                  }
-                inc(r.offset,4);
+                inc(href.offset,4);
                 rg.getexplicitregisterint(exprasmlist,R_EDI);
-                emit_ref_reg(A_MOV,S_L,r,R_EDI);
-                reference_reset_base(r,R_ESP,4);
-                emit_const_ref(A_AND,S_L,$7fffffff,r);
+                emit_ref_reg(A_MOV,S_L,href,R_EDI);
+                reference_reset_base(href,R_ESP,4);
+                emit_const_ref(A_AND,S_L,$7fffffff,href);
                 emit_const_reg(A_TEST,S_L,longint($80000000),R_EDI);
                 rg.ungetregisterint(exprasmlist,R_EDI);
-                reference_reset_base(r,R_ESP,0);
-                emit_ref(A_FILD,S_IQ,r);
+                reference_reset_base(href,R_ESP,0);
+                emit_ref(A_FILD,S_IQ,href);
                 getdatalabel(l1);
                 getlabel(l2);
                 emitjmp(C_Z,l2);
@@ -178,14 +171,14 @@ implementation
                 { I got this constant from a test progtram (FK) }
                 Consts.concat(Tai_const.Create_32bit(0));
                 Consts.concat(Tai_const.Create_32bit(1138753536));
-                reference_reset_symbol(r,l1,0);
-                emit_ref(A_FADD,S_FL,r);
-                emitlab(l2);
+                reference_reset_symbol(href,l1,0);
+                emit_ref(A_FADD,S_FL,href);
+                cg.a_label(exprasmlist,l2);
                 emit_const_reg(A_ADD,S_L,8,R_ESP);
              end
            else
              begin
-                emit_ref(A_FILD,S_IL,r);
+                emit_ref(A_FILD,S_IL,href);
                 rg.getexplicitregisterint(exprasmlist,R_EDI);
                 emit_reg(A_POP,S_L,R_EDI);
                 rg.ungetregisterint(exprasmlist,R_EDI);
@@ -239,7 +232,7 @@ implementation
                  end
                 else
                  begin
-                   location_force_reg(left.location,left.location.size,true);
+                   location_force_reg(exprasmlist,left.location,left.location.size,true);
                    cg.a_op_reg_reg(exprasmlist,OP_OR,left.location.size,left.location.register,left.location.register);
                  end;
               end;
@@ -372,7 +365,24 @@ begin
 end.
 {
   $Log$
-  Revision 1.37  2002-04-21 19:02:07  peter
+  Revision 1.38  2002-05-12 16:53:17  peter
+    * moved entry and exitcode to ncgutil and cgobj
+    * foreach gets extra argument for passing local data to the
+      iterator function
+    * -CR checks also class typecasts at runtime by changing them
+      into as
+    * fixed compiler to cycle with the -CR option
+    * fixed stabs with elf writer, finally the global variables can
+      be watched
+    * removed a lot of routines from cga unit and replaced them by
+      calls to cgobj
+    * u32bit-s32bit updates for and,or,xor nodes. When one element is
+      u32bit then the other is typecasted also to u32bit without giving
+      a rangecheck warning/error.
+    * fixed pascal calling method with reversing also the high tree in
+      the parast, detected by tcalcst3 test
+
+  Revision 1.37  2002/04/21 19:02:07  peter
     * removed newn and disposen nodes, the code is now directly
       inlined from pexpr
     * -an option that will write the secondpass nodes to the .s file, this

+ 114 - 94
compiler/i386/n386flw.pas

@@ -56,8 +56,8 @@ implementation
     uses
       verbose,systems,
       symsym,aasm,
-      cginfo,cgbase,pass_2,
-      cpubase,cpuasm,
+      cgbase,pass_2,
+      cpuinfo,cpubase,cpuasm,
       nld,ncon,
       tainst,cga,cgobj,tgobj,rgobj;
 
@@ -94,7 +94,7 @@ implementation
               else
                 begin
                    getaddrlabel(a);
-                   emitlab(a);
+                   cg.a_label(exprasmlist,a);
                    cg.a_param_reg(exprasmlist,OS_INT,R_EBP,2);
                    emit_sym(A_PUSH,S_L,a);
                 end;
@@ -103,12 +103,12 @@ implementation
               if codegenerror then
                 exit;
               cg.a_param_loc(exprasmlist,left.location,1);
-              emitcall('FPC_RAISEEXCEPTION');
+              cg.a_call_name(exprasmlist,'FPC_RAISEEXCEPTION');
            end
          else
            begin
-              emitcall('FPC_POPADDRSTACK');
-              emitcall('FPC_RERAISE');
+              cg.a_call_name(exprasmlist,'FPC_POPADDRSTACK');
+              cg.a_call_name(exprasmlist,'FPC_RERAISE');
            end;
        end;
 
@@ -125,12 +125,12 @@ implementation
     procedure cleanupobjectstack;
 
       begin
-         emitcall('FPC_POPOBJECTSTACK');
+         cg.a_call_name(exprasmlist,'FPC_POPOBJECTSTACK');
          exprasmList.concat(Tairegalloc.Alloc(R_EAX));
          emit_reg(A_PUSH,S_L,R_EAX);
-         emitcall('FPC_DESTROYEXCEPTION');
+         cg.a_call_name(exprasmlist,'FPC_DESTROYEXCEPTION');
          exprasmList.concat(Tairegalloc.DeAlloc(R_EAX));
-         maybe_loadself;
+         cg.g_maybe_loadself(exprasmlist);
       end;
 
     { pops one element from the exception address stack }
@@ -138,7 +138,7 @@ implementation
     procedure cleanupaddrstack;
 
       begin
-         emitcall('FPC_POPADDRSTACK');
+         cg.a_call_name(exprasmlist,'FPC_POPADDRSTACK');
          { allocate eax }
          exprasmList.concat(Tairegalloc.Alloc(R_EAX));
          emit_reg(A_POP,S_L,R_EAX);
@@ -205,15 +205,16 @@ implementation
 
          tg.gettempofsizereferencepersistant(exprasmlist,24,tempbuf);
          tg.gettempofsizereferencepersistant(exprasmlist,12,tempaddr);
-         emitpushreferenceaddr(tempaddr);
-         emitpushreferenceaddr(tempbuf);
-         push_int (1); { push type of exceptionframe }
-         emitcall('FPC_PUSHEXCEPTADDR');
+         cg.a_paramaddr_ref(exprasmlist,tempaddr,3);
+         cg.a_paramaddr_ref(exprasmlist,tempbuf,2);
+         { push type of exceptionframe }
+         cg.a_param_const(exprasmlist,OS_INT,1,1);
+         cg.a_call_name(exprasmlist,'FPC_PUSHEXCEPTADDR');
 
          { allocate eax }
          exprasmList.concat(Tairegalloc.Alloc(R_EAX));
          emit_reg(A_PUSH,S_L,R_EAX);
-         emitcall('FPC_SETJMP');
+         cg.a_call_name(exprasmlist,'FPC_SETJMP');
          emit_reg(A_PUSH,S_L,R_EAX);
          emit_reg_reg(A_TEST,S_L,R_EAX,R_EAX);
          { deallocate eax }
@@ -236,8 +237,8 @@ implementation
          if codegenerror then
            goto errorexit;
 
-         emitlab(exceptlabel);
-         emitcall('FPC_POPADDRSTACK');
+         cg.a_label(exprasmlist,exceptlabel);
+         cg.a_call_name(exprasmlist,'FPC_POPADDRSTACK');
          tg.ungetpersistanttempreference(exprasmlist,tempaddr);
          tg.ungetpersistanttempreference(exprasmlist,tempbuf);
 
@@ -247,7 +248,7 @@ implementation
          exprasmList.concat(Tairegalloc.DeAlloc(R_EAX));
 
          emitjmp(C_E,endexceptlabel);
-         emitlab(doexceptlabel);
+         cg.a_label(exprasmlist,doexceptlabel);
 
          { set control flow labels for the except block }
          { and the on statements                        }
@@ -264,46 +265,47 @@ implementation
          if assigned(right) then
            secondpass(right);
 
-         emitlab(lastonlabel);
+         cg.a_label(exprasmlist,lastonlabel);
          { default handling except handling }
          if assigned(t1) then
            begin
               { FPC_CATCHES must be called with
                 'default handler' flag (=-1)
               }
-              push_int (-1);
-              emitcall('FPC_CATCHES');
-              maybe_loadself;
+              cg.a_param_const(exprasmlist,OS_INT,aword(-1),1);
+              cg.a_call_name(exprasmlist,'FPC_CATCHES');
+              cg.g_maybe_loadself(exprasmlist);
 
               { the destruction of the exception object must be also }
               { guarded by an exception frame                        }
               getlabel(doobjectdestroy);
               getlabel(doobjectdestroyandreraise);
 
-              tg.gettempofsizereferencepersistant(exprasmlist,12,tempaddr);
               tg.gettempofsizereferencepersistant(exprasmlist,24,tempbuf);
-              emitpushreferenceaddr(tempaddr);
-              emitpushreferenceaddr(tempbuf);
-              exprasmList.concat(Taicpu.Op_const(A_PUSH,S_L,1));
-              emitcall('FPC_PUSHEXCEPTADDR');
+              tg.gettempofsizereferencepersistant(exprasmlist,12,tempaddr);
+              cg.a_paramaddr_ref(exprasmlist,tempaddr,3);
+              cg.a_paramaddr_ref(exprasmlist,tempbuf,2);
+              { push type of exceptionframe }
+              cg.a_param_const(exprasmlist,OS_INT,1,1);
+              cg.a_call_name(exprasmlist,'FPC_PUSHEXCEPTADDR');
 
+              { allocate eax }
               exprasmList.concat(Tairegalloc.Alloc(R_EAX));
-              exprasmList.concat(Taicpu.op_reg(A_PUSH,S_L,R_EAX));
-              exprasmList.concat(Tairegalloc.DeAlloc(R_EAX));
-              emitcall('FPC_SETJMP');
-              exprasmList.concat(Tairegalloc.Alloc(R_EAX));
-              exprasmList.concat(Taicpu.op_reg(A_PUSH,S_L,R_EAX));
-              exprasmList.concat(Taicpu.op_reg_reg(A_TEST,S_L,R_EAX,R_EAX));
+              emit_reg(A_PUSH,S_L,R_EAX);
+              cg.a_call_name(exprasmlist,'FPC_SETJMP');
+              emit_reg(A_PUSH,S_L,R_EAX);
+              emit_reg_reg(A_TEST,S_L,R_EAX,R_EAX);
+              { deallocate eax }
               exprasmList.concat(Tairegalloc.DeAlloc(R_EAX));
-              emitjmp(C_NE,doobjectdestroyandreraise);
+              emitjmp(C_NE,exceptlabel);
 
               { here we don't have to reset flowcontrol           }
               { the default and on flowcontrols are handled equal }
               secondpass(t1);
               exceptflowcontrol:=flowcontrol;
 
-              emitlab(doobjectdestroyandreraise);
-              emitcall('FPC_POPADDRSTACK');
+              cg.a_label(exprasmlist,doobjectdestroyandreraise);
+              cg.a_call_name(exprasmlist,'FPC_POPADDRSTACK');
               tg.ungetpersistanttempreference(exprasmlist,tempaddr);
               tg.ungetpersistanttempreference(exprasmlist,tempbuf);
 
@@ -312,79 +314,79 @@ implementation
               exprasmList.concat(Taicpu.op_reg_reg(A_TEST,S_L,R_EAX,R_EAX));
               exprasmList.concat(Tairegalloc.DeAlloc(R_EAX));
               emitjmp(C_E,doobjectdestroy);
-              emitcall('FPC_POPSECONDOBJECTSTACK');
+              cg.a_call_name(exprasmlist,'FPC_POPSECONDOBJECTSTACK');
               exprasmList.concat(Tairegalloc.Alloc(R_EAX));
               emit_reg(A_PUSH,S_L,R_EAX);
-              emitcall('FPC_DESTROYEXCEPTION');
+              cg.a_call_name(exprasmlist,'FPC_DESTROYEXCEPTION');
               exprasmList.concat(Tairegalloc.DeAlloc(R_EAX));
               { we don't need to restore esi here because reraise never }
               { returns                                                 }
-              emitcall('FPC_RERAISE');
+              cg.a_call_name(exprasmlist,'FPC_RERAISE');
 
-              emitlab(doobjectdestroy);
+              cg.a_label(exprasmlist,doobjectdestroy);
               cleanupobjectstack;
-              emitjmp(C_None,endexceptlabel);
+              cg.a_jmp_always(exprasmlist,endexceptlabel);
            end
          else
            begin
-              emitcall('FPC_RERAISE');
+              cg.a_call_name(exprasmlist,'FPC_RERAISE');
               exceptflowcontrol:=flowcontrol;
            end;
 
          if fc_exit in exceptflowcontrol then
            begin
               { do some magic for exit in the try block }
-              emitlab(exitexceptlabel);
+              cg.a_label(exprasmlist,exitexceptlabel);
               { we must also destroy the address frame which guards }
               { exception object                                    }
               cleanupaddrstack;
               cleanupobjectstack;
-              emitjmp(C_None,oldaktexitlabel);
+              cg.a_jmp_always(exprasmlist,oldaktexitlabel);
            end;
 
          if fc_break in exceptflowcontrol then
            begin
-              emitlab(breakexceptlabel);
+              cg.a_label(exprasmlist,breakexceptlabel);
               { we must also destroy the address frame which guards }
               { exception object                                    }
               cleanupaddrstack;
               cleanupobjectstack;
-              emitjmp(C_None,oldaktbreaklabel);
+              cg.a_jmp_always(exprasmlist,oldaktbreaklabel);
            end;
 
          if fc_continue in exceptflowcontrol then
            begin
-              emitlab(continueexceptlabel);
+              cg.a_label(exprasmlist,continueexceptlabel);
               { we must also destroy the address frame which guards }
               { exception object                                    }
               cleanupaddrstack;
               cleanupobjectstack;
-              emitjmp(C_None,oldaktcontinuelabel);
+              cg.a_jmp_always(exprasmlist,oldaktcontinuelabel);
            end;
 
          if fc_exit in tryflowcontrol then
            begin
               { do some magic for exit in the try block }
-              emitlab(exittrylabel);
+              cg.a_label(exprasmlist,exittrylabel);
               cleanupaddrstack;
-              emitjmp(C_None,oldaktexitlabel);
+              cg.a_jmp_always(exprasmlist,oldaktexitlabel);
            end;
 
          if fc_break in tryflowcontrol then
            begin
-              emitlab(breaktrylabel);
+              cg.a_label(exprasmlist,breaktrylabel);
               cleanupaddrstack;
-              emitjmp(C_None,oldaktbreaklabel);
+              cg.a_jmp_always(exprasmlist,oldaktbreaklabel);
            end;
 
          if fc_continue in tryflowcontrol then
            begin
-              emitlab(continuetrylabel);
+              cg.a_label(exprasmlist,continuetrylabel);
               cleanupaddrstack;
-              emitjmp(C_None,oldaktcontinuelabel);
+              cg.a_jmp_always(exprasmlist,oldaktcontinuelabel);
            end;
 
-         emitlab(endexceptlabel);
+         cg.a_label(exprasmlist,endexceptlabel);
 
        errorexit:
          { restore all saved labels }
@@ -428,7 +430,7 @@ implementation
          { push the vmt }
          emit_sym(A_PUSH,S_L,
            newasmsymbol(excepttype.vmt_mangledname));
-         emitcall('FPC_CATCHES');
+         cg.a_call_name(exprasmlist,'FPC_CATCHES');
          { allocate eax }
          exprasmList.concat(Tairegalloc.Alloc(R_EAX));
          emit_reg_reg(A_TEST,S_L,R_EAX,R_EAX);
@@ -450,15 +452,15 @@ implementation
 
          tg.gettempofsizereferencepersistant(exprasmlist,12,tempaddr);
          tg.gettempofsizereferencepersistant(exprasmlist,24,tempbuf);
-         emitpushreferenceaddr(tempaddr);
-         emitpushreferenceaddr(tempbuf);
-         exprasmList.concat(Taicpu.Op_const(A_PUSH,S_L,1));
-         emitcall('FPC_PUSHEXCEPTADDR');
+         cg.a_paramaddr_ref(exprasmlist,tempaddr,3);
+         cg.a_paramaddr_ref(exprasmlist,tempbuf,2);
+         cg.a_param_const(exprasmlist,OS_INT,1,1);
+         cg.a_call_name(exprasmlist,'FPC_PUSHEXCEPTADDR');
 
          exprasmList.concat(Tairegalloc.Alloc(R_EAX));
          exprasmList.concat(Taicpu.op_reg(A_PUSH,S_L,R_EAX));
          exprasmList.concat(Tairegalloc.DeAlloc(R_EAX));
-         emitcall('FPC_SETJMP');
+         cg.a_call_name(exprasmlist,'FPC_SETJMP');
          exprasmList.concat(Tairegalloc.Alloc(R_EAX));
          exprasmList.concat(Taicpu.op_reg(A_PUSH,S_L,R_EAX));
          exprasmList.concat(Taicpu.op_reg_reg(A_TEST,S_L,R_EAX,R_EAX));
@@ -483,12 +485,12 @@ implementation
                end;
 
               { esi is destroyed by FPC_CATCHES }
-              maybe_loadself;
+              cg.g_maybe_loadself(exprasmlist);
               secondpass(right);
            end;
          getlabel(doobjectdestroy);
-         emitlab(doobjectdestroyandreraise);
-         emitcall('FPC_POPADDRSTACK');
+         cg.a_label(exprasmlist,doobjectdestroyandreraise);
+         cg.a_call_name(exprasmlist,'FPC_POPADDRSTACK');
          tg.ungetpersistanttempreference(exprasmlist,tempaddr);
          tg.ungetpersistanttempreference(exprasmlist,tempbuf);
 
@@ -497,20 +499,20 @@ implementation
          exprasmList.concat(Taicpu.op_reg_reg(A_TEST,S_L,R_EAX,R_EAX));
          exprasmList.concat(Tairegalloc.DeAlloc(R_EAX));
          emitjmp(C_E,doobjectdestroy);
-         emitcall('FPC_POPSECONDOBJECTSTACK');
+         cg.a_call_name(exprasmlist,'FPC_POPSECONDOBJECTSTACK');
          exprasmList.concat(Tairegalloc.Alloc(R_EAX));
          emit_reg(A_PUSH,S_L,R_EAX);
-         emitcall('FPC_DESTROYEXCEPTION');
+         cg.a_call_name(exprasmlist,'FPC_DESTROYEXCEPTION');
          exprasmList.concat(Tairegalloc.DeAlloc(R_EAX));
          { we don't need to restore esi here because reraise never }
          { returns                                                 }
-         emitcall('FPC_RERAISE');
+         cg.a_call_name(exprasmlist,'FPC_RERAISE');
 
-         emitlab(doobjectdestroy);
+         cg.a_label(exprasmlist,doobjectdestroy);
          cleanupobjectstack;
          { clear some stuff }
          tg.ungetiftemp(exprasmlist,ref);
-         emitjmp(C_None,endexceptlabel);
+         cg.a_jmp_always(exprasmlist,endexceptlabel);
 
          if assigned(right) then
            begin
@@ -518,22 +520,22 @@ implementation
               if fc_exit in flowcontrol then
                 begin
                    { the address and object pop does secondtryexcept }
-                   emitlab(exitonlabel);
-                   emitjmp(C_None,oldaktexitlabel);
+                   cg.a_label(exprasmlist,exitonlabel);
+                   cg.a_jmp_always(exprasmlist,oldaktexitlabel);
                 end;
 
               if fc_break in flowcontrol then
                 begin
                    { the address and object pop does secondtryexcept }
-                   emitlab(breakonlabel);
-                   emitjmp(C_None,oldaktbreaklabel);
+                   cg.a_label(exprasmlist,breakonlabel);
+                   cg.a_jmp_always(exprasmlist,oldaktbreaklabel);
                 end;
 
               if fc_continue in flowcontrol then
                 begin
                    { the address and object pop does secondtryexcept }
-                   emitlab(continueonlabel);
-                   emitjmp(C_None,oldaktcontinuelabel);
+                   cg.a_label(exprasmlist,continueonlabel);
+                   cg.a_jmp_always(exprasmlist,oldaktcontinuelabel);
                 end;
 
               aktexitlabel:=oldaktexitlabel;
@@ -545,7 +547,7 @@ implementation
                end;
            end;
 
-         emitlab(nextonlabel);
+         cg.a_label(exprasmlist,nextonlabel);
          flowcontrol:=oldflowcontrol+flowcontrol;
          { next on node }
          if assigned(left) then
@@ -604,15 +606,16 @@ implementation
 
          tg.gettempofsizereferencepersistant(exprasmlist,12,tempaddr);
          tg.gettempofsizereferencepersistant(exprasmlist,24,tempbuf);
-         emitpushreferenceaddr(tempaddr);
-         emitpushreferenceaddr(tempbuf);
-         push_int(1); { Type of stack-frame must be pushed}
-         emitcall('FPC_PUSHEXCEPTADDR');
+         cg.a_paramaddr_ref(exprasmlist,tempaddr,3);
+         cg.a_paramaddr_ref(exprasmlist,tempbuf,2);
+         { Type of stack-frame must be pushed}
+         cg.a_param_const(exprasmlist,OS_INT,1,1);
+         cg.a_call_name(exprasmlist,'FPC_PUSHEXCEPTADDR');
 
          { allocate eax }
          exprasmList.concat(Tairegalloc.Alloc(R_EAX));
          emit_reg(A_PUSH,S_L,R_EAX);
-         emitcall('FPC_SETJMP');
+         cg.a_call_name(exprasmlist,'FPC_SETJMP');
          emit_reg(A_PUSH,S_L,R_EAX);
          emit_reg_reg(A_TEST,S_L,R_EAX,R_EAX);
          { deallocate eax }
@@ -628,8 +631,8 @@ implementation
                 exit;
            end;
 
-         emitlab(finallylabel);
-         emitcall('FPC_POPADDRSTACK');
+         cg.a_label(exprasmlist,finallylabel);
+         cg.a_call_name(exprasmlist,'FPC_POPADDRSTACK');
          tg.ungetpersistanttempreference(exprasmlist,tempaddr);
          tg.ungetpersistanttempreference(exprasmlist,tempbuf);
 
@@ -670,41 +673,41 @@ implementation
            end;
          { deallocate eax }
          exprasmList.concat(Tairegalloc.DeAlloc(R_EAX));
-         emitlab(reraiselabel);
-         emitcall('FPC_RERAISE');
+         cg.a_label(exprasmlist,reraiselabel);
+         cg.a_call_name(exprasmlist,'FPC_RERAISE');
          { do some magic for exit,break,continue in the try block }
          if fc_exit in tryflowcontrol then
            begin
-              emitlab(exitfinallylabel);
+              cg.a_label(exprasmlist,exitfinallylabel);
               { allocate eax }
               exprasmList.concat(Tairegalloc.Alloc(R_EAX));
               emit_reg(A_POP,S_L,R_EAX);
               exprasmList.concat(Tairegalloc.Alloc(R_EAX));
               emit_const(A_PUSH,S_L,2);
-              emitjmp(C_NONE,finallylabel);
+              cg.a_jmp_always(exprasmlist,finallylabel);
            end;
          if fc_break in tryflowcontrol then
           begin
-             emitlab(breakfinallylabel);
+             cg.a_label(exprasmlist,breakfinallylabel);
              { allocate eax }
              exprasmList.concat(Tairegalloc.Alloc(R_EAX));
              emit_reg(A_POP,S_L,R_EAX);
              { deallocate eax }
              exprasmList.concat(Tairegalloc.DeAlloc(R_EAX));
              emit_const(A_PUSH,S_L,3);
-             emitjmp(C_NONE,finallylabel);
+             cg.a_jmp_always(exprasmlist,finallylabel);
            end;
          if fc_continue in tryflowcontrol then
            begin
-              emitlab(continuefinallylabel);
+              cg.a_label(exprasmlist,continuefinallylabel);
               exprasmList.concat(Tairegalloc.Alloc(R_EAX));
               emit_reg(A_POP,S_L,R_EAX);
               exprasmList.concat(Tairegalloc.Alloc(R_EAX));
               emit_const(A_PUSH,S_L,4);
-              emitjmp(C_NONE,finallylabel);
+              cg.a_jmp_always(exprasmlist,finallylabel);
            end;
 
-         emitlab(endfinallylabel);
+         cg.a_label(exprasmlist,endfinallylabel);
 
          aktexitlabel:=oldaktexitlabel;
          aktexit2label:=oldaktexit2label;
@@ -723,7 +726,7 @@ implementation
 
     procedure ti386failnode.pass_2;
       begin
-        emitjmp(C_None,faillabel);
+        cg.a_jmp_always(exprasmlist,faillabel);
       end;
 
 
@@ -736,7 +739,24 @@ begin
 end.
 {
   $Log$
-  Revision 1.22  2002-04-04 19:06:11  peter
+  Revision 1.23  2002-05-12 16:53:17  peter
+    * moved entry and exitcode to ncgutil and cgobj
+    * foreach gets extra argument for passing local data to the
+      iterator function
+    * -CR checks also class typecasts at runtime by changing them
+      into as
+    * fixed compiler to cycle with the -CR option
+    * fixed stabs with elf writer, finally the global variables can
+      be watched
+    * removed a lot of routines from cga unit and replaced them by
+      calls to cgobj
+    * u32bit-s32bit updates for and,or,xor nodes. When one element is
+      u32bit then the other is typecasted also to u32bit without giving
+      a rangecheck warning/error.
+    * fixed pascal calling method with reversing also the high tree in
+      the parast, detected by tcalcst3 test
+
+  Revision 1.22  2002/04/04 19:06:11  peter
     * removed unused units
     * use tlocation.size in cg.a_*loc*() routines
 

+ 45 - 28
compiler/i386/n386inl.pas

@@ -39,7 +39,7 @@ implementation
     uses
       globtype,systems,
       cutils,verbose,globals,fmodule,
-      symconst,symtype,symdef,aasm,types,
+      symconst,symdef,aasm,types,
       cginfo,cgbase,pass_1,pass_2,
       cpubase,
       nbas,ncon,ncal,ncnv,nld,
@@ -88,26 +88,26 @@ implementation
                  getlabel(truelabel);
                  getlabel(falselabel);
                  secondpass(tcallparanode(left).left);
-                 maketojumpbool(tcallparanode(left).left,lr_load_regvars);
-                 emitlab(falselabel);
+                 maketojumpbool(exprasmlist,tcallparanode(left).left,lr_load_regvars);
+                 cg.a_label(exprasmlist,falselabel);
                  { erroraddr }
-                 emit_reg(A_PUSH,S_L,R_EBP);
+                 cg.a_param_reg(exprasmlist,OS_ADDR,R_EBP,4);
                  { lineno }
-                 emit_const(A_PUSH,S_L,aktfilepos.line);
+                 cg.a_param_const(exprasmlist,OS_INT,aktfilepos.line,3);
                  { filename string }
                  hp2:=cstringconstnode.createstr(current_module.sourcefiles.get_file_name(aktfilepos.fileindex),st_shortstring);
                  firstpass(hp2);
                  secondpass(hp2);
                  if codegenerror then
                   exit;
-                 emitpushreferenceaddr(hp2.location.reference);
+                 cg.a_paramaddr_ref(exprasmlist,hp2.location.reference,2);
                  hp2.free;
                  { push msg }
                  secondpass(tcallparanode(tcallparanode(left).right).left);
-                 emitpushreferenceaddr(tcallparanode(tcallparanode(left).right).left.location.reference);
+                 cg.a_paramaddr_ref(exprasmlist,tcallparanode(tcallparanode(left).right).left.location.reference,1);
                  { call }
-                 emitcall('FPC_ASSERT');
-                 emitlab(truelabel);
+                 cg.a_call_name(exprasmlist,'FPC_ASSERT');
+                 cg.a_label(exprasmlist,truelabel);
                  truelabel:=otlabel;
                  falselabel:=oflabel;
               end;
@@ -118,27 +118,28 @@ implementation
                  { for both cases load vmt }
                  if left.nodetype=typen then
                    begin
-                      location.register:=rg.getregisterint(exprasmlist);
-                      emit_sym_ofs_reg(A_MOV,
-                        S_L,newasmsymbol(tobjectdef(left.resulttype.def).vmt_mangledname),0,
-                        location.register);
+                      hregister:=rg.getaddressregister(exprasmlist);
+                      reference_reset_symbol(href,newasmsymbol(tobjectdef(left.resulttype.def).vmt_mangledname),0);
+                      cg.a_loadaddr_ref_reg(exprasmlist,href,hregister);
                    end
                  else
                    begin
                       secondpass(left);
                       location_release(exprasmlist,left.location);
-                      location.register:=rg.getregisterint(exprasmlist);
+                      hregister:=rg.getaddressregister(exprasmlist);
                       { load VMT pointer }
-                      inc(left.location.reference.offset,
-                        tobjectdef(left.resulttype.def).vmt_offset);
-                      emit_ref_reg(A_MOV,S_L,left.location.reference,location.register);
+                      inc(left.location.reference.offset,tobjectdef(left.resulttype.def).vmt_offset);
+                      cg.a_load_ref_reg(exprasmlist,OS_ADDR,left.location.reference,hregister);
                    end;
                  { in sizeof load size }
                  if inlinenumber=in_sizeof_x then
                    begin
-                      reference_reset_base(href,location.register,0);
-                      emit_ref_reg(A_MOV,S_L,href,location.register);
+                      reference_reset_base(href,hregister,0);
+                      rg.ungetaddressregister(exprasmlist,hregister);
+                      hregister:=rg.getregisterint(exprasmlist);
+                      cg.a_load_ref_reg(exprasmlist,OS_INT,href,hregister);
                    end;
+                 location.register:=hregister;
               end;
             in_length_x :
               begin
@@ -155,12 +156,11 @@ implementation
                      end
                     else
                      hregister:=left.location.register;
-                    reference_reset_base(href,hregister,-8);
                     getlabel(lengthlab);
-                    emit_reg_reg(A_OR,S_L,hregister,hregister);
-                    emitjmp(C_Z,lengthlab);
-                    emit_ref_reg(A_MOV,S_L,href,hregister);
-                    emitlab(lengthlab);
+                    cg.a_cmp_const_reg_label(exprasmlist,OS_ADDR,OC_EQ,0,hregister,lengthlab);
+                    reference_reset_base(href,hregister,-8);
+                    cg.a_load_ref_reg(exprasmlist,OS_INT,href,hregister);
+                    cg.a_label(exprasmlist,lengthlab);
                     location_reset(location,LOC_REGISTER,OS_INT);
                     location.register:=hregister;
                   end
@@ -182,7 +182,7 @@ implementation
 
                  { we need a value in a register }
                  location_copy(location,left.location);
-                 location_force_reg(location,cgsize,false);
+                 location_force_reg(exprasmlist,location,cgsize,false);
 
                  if cgsize in [OS_64,OS_S64] then
                   tcg64f32(cg).a_op64_const_reg(exprasmlist,cgop,1,0,
@@ -229,7 +229,7 @@ implementation
                     addvalue:=addvalue*get_ordinal_value(tcallparanode(tcallparanode(left).right).left)
                    else
                     begin
-                      location_force_reg(tcallparanode(tcallparanode(left).right).left.location,cgsize,false);
+                      location_force_reg(exprasmlist,tcallparanode(tcallparanode(left).right).left.location,cgsize,false);
                       hregister:=tcallparanode(tcallparanode(left).right).left.location.register;
                       hregisterhi:=tcallparanode(tcallparanode(left).right).left.location.registerhigh;
                       { insert multiply with addvalue if its >1 }
@@ -411,7 +411,7 @@ implementation
                          emitjmp(C_NP,l1);
                          emit_reg(A_FSTP,S_NO,R_ST0);
                          emit_none(A_FLDZ,S_NO);
-                         emitlab(l1);
+                         cg.a_label(exprasmlist,l1);
                          }
                       end;
                     in_arctan_extended:
@@ -468,7 +468,24 @@ begin
 end.
 {
   $Log$
-  Revision 1.39  2002-04-23 19:16:35  peter
+  Revision 1.40  2002-05-12 16:53:17  peter
+    * moved entry and exitcode to ncgutil and cgobj
+    * foreach gets extra argument for passing local data to the
+      iterator function
+    * -CR checks also class typecasts at runtime by changing them
+      into as
+    * fixed compiler to cycle with the -CR option
+    * fixed stabs with elf writer, finally the global variables can
+      be watched
+    * removed a lot of routines from cga unit and replaced them by
+      calls to cgobj
+    * u32bit-s32bit updates for and,or,xor nodes. When one element is
+      u32bit then the other is typecasted also to u32bit without giving
+      a rangecheck warning/error.
+    * fixed pascal calling method with reversing also the high tree in
+      the parast, detected by tcalcst3 test
+
+  Revision 1.39  2002/04/23 19:16:35  peter
     * add pinline unit that inserts compiler supported functions using
       one or more statements
     * moved finalize and setlength from ninl to pinline

+ 27 - 10
compiler/i386/n386ld.pas

@@ -48,11 +48,11 @@ implementation
     uses
       systems,
       cutils,verbose,globals,
-      symconst,symtype,symdef,symsym,symtable,aasm,types,
+      symconst,symdef,symsym,symtable,aasm,types,
       cginfo,cgbase,pass_2,
       nmem,ncon,ncnv,
       cpubase,cpuasm,
-      cga,tgobj,n386util,ncgutil,regvars,cgobj,cg64f32,rgobj,rgcpu;
+      cga,tgobj,n386util,regvars,cgobj,cg64f32,rgobj,rgcpu;
 
 {*****************************************************************************
                              SecondLoad
@@ -127,7 +127,7 @@ implementation
                          emit_ref(A_PUSH,S_L,href);
                          { the called procedure isn't allowed to change }
                          { any register except EAX                    }
-                         emitcall('FPC_RELOCATE_THREADVAR');
+                         cg.a_call_name(exprasmlist,'FPC_RELOCATE_THREADVAR');
 
                          location.reference.base:=rg.getregisterint(exprasmlist);
                          emit_reg_reg(A_MOV,S_L,R_EAX,location.reference.base);
@@ -567,8 +567,8 @@ implementation
                     LOC_REFERENCE,
                     LOC_CREFERENCE :
                       begin
-                        concatcopy(right.location.reference,
-                                   left.location.reference,left.resulttype.def.size,true,false);
+                        cg.g_concatcopy(exprasmlist,right.location.reference,
+                                        left.location.reference,left.resulttype.def.size,true,false);
                         { right.location is already released by concatcopy }
                         releaseright:=false;
                       end;
@@ -619,7 +619,7 @@ implementation
                   getlabel(hlabel);
                   { generate the leftnode for the true case, and
                     release the location }
-                  emitlab(truelabel);
+                  cg.a_label(exprasmlist,truelabel);
                   pushed:=maybe_push(left.registers32,right,false);
                   secondpass(left);
                   if pushed then
@@ -628,9 +628,9 @@ implementation
                     exit;
                   cg.a_load_const_loc(exprasmlist,1,left.location);
                   location_release(exprasmlist,left.location);
-                  emitjmp(C_None,hlabel);
+                  cg.a_jmp_always(exprasmlist,hlabel);
                   { generate the leftnode for the false case }
-                  emitlab(falselabel);
+                  cg.a_label(exprasmlist,falselabel);
                   pushed:=maybe_push(left.registers32,right,false);
                   secondpass(left);
                   if pushed then
@@ -638,7 +638,7 @@ implementation
                   if codegenerror then
                     exit;
                   cg.a_load_const_loc(exprasmlist,0,left.location);
-                  emitlab(hlabel);
+                  cg.a_label(exprasmlist,hlabel);
                 end;
               LOC_FLAGS :
                 begin
@@ -723,7 +723,24 @@ begin
 end.
 {
   $Log$
-  Revision 1.40  2002-04-26 15:19:05  peter
+  Revision 1.41  2002-05-12 16:53:17  peter
+    * moved entry and exitcode to ncgutil and cgobj
+    * foreach gets extra argument for passing local data to the
+      iterator function
+    * -CR checks also class typecasts at runtime by changing them
+      into as
+    * fixed compiler to cycle with the -CR option
+    * fixed stabs with elf writer, finally the global variables can
+      be watched
+    * removed a lot of routines from cga unit and replaced them by
+      calls to cgobj
+    * u32bit-s32bit updates for and,or,xor nodes. When one element is
+      u32bit then the other is typecasted also to u32bit without giving
+      a rangecheck warning/error.
+    * fixed pascal calling method with reversing also the high tree in
+      the parast, detected by tcalcst3 test
+
+  Revision 1.40  2002/04/26 15:19:05  peter
     * use saveregisters for incr routines, saves also problems with
       the optimizer
 

+ 37 - 20
compiler/i386/n386mat.pas

@@ -90,7 +90,7 @@ implementation
          else
            begin
               { put numerator in register }
-              location_force_reg(left.location,OS_INT,false);
+              location_force_reg(exprasmlist,left.location,OS_INT,false);
               hreg1:=left.location.register;
 
               if (nodetype=divn) and
@@ -144,7 +144,7 @@ implementation
                             emit_reg(A_INC,S_L,hreg1)
                           else
                             emit_const_reg(A_ADD,S_L,tordconstnode(right).value-1,hreg1);
-                          emitlab(hl);
+                          cg.a_label(exprasmlist,hl);
                           emit_const_reg(A_SAR,S_L,power,hreg1);
                         end
                     End
@@ -294,7 +294,7 @@ implementation
               location_reset(location,LOC_REGISTER,OS_64);
 
               { load left operator in a register }
-              location_force_reg(left.location,OS_64,false);
+              location_force_reg(exprasmlist,left.location,OS_64,false);
               hregisterhigh:=left.location.registerhigh;
               hregisterlow:=left.location.registerlow;
 
@@ -404,8 +404,8 @@ implementation
                         emitjmp(C_L,l1);
                         emit_reg_reg(A_XOR,S_L,hregisterlow,hregisterlow);
                         emit_reg_reg(A_XOR,S_L,hregisterhigh,hregisterhigh);
-                        emitjmp(C_None,l3);
-                        emitlab(l1);
+                        cg.a_jmp_always(exprasmlist,l3);
+                        cg.a_label(exprasmlist,l1);
                         emit_const_reg(A_CMP,S_L,32,R_ECX);
                         emitjmp(C_L,l2);
                         emit_const_reg(A_SUB,S_L,32,R_ECX);
@@ -413,13 +413,13 @@ implementation
                           hregisterlow);
                         emit_reg_reg(A_MOV,S_L,hregisterlow,hregisterhigh);
                         emit_reg_reg(A_XOR,S_L,hregisterlow,hregisterlow);
-                        emitjmp(C_None,l3);
-                        emitlab(l2);
+                        cg.a_jmp_always(exprasmlist,l3);
+                        cg.a_label(exprasmlist,l2);
                         emit_reg_reg_reg(A_SHLD,S_L,R_CL,
                           hregisterlow,hregisterhigh);
                         emit_reg_reg(A_SHL,S_L,R_CL,
                           hregisterlow);
-                        emitlab(l3);
+                        cg.a_label(exprasmlist,l3);
                      end
                    else
                      begin
@@ -430,8 +430,8 @@ implementation
                         emitjmp(C_L,l1);
                         emit_reg_reg(A_XOR,S_L,hregisterlow,hregisterlow);
                         emit_reg_reg(A_XOR,S_L,hregisterhigh,hregisterhigh);
-                        emitjmp(C_None,l3);
-                        emitlab(l1);
+                        cg.a_jmp_always(exprasmlist,l3);
+                        cg.a_label(exprasmlist,l1);
                         emit_const_reg(A_CMP,S_L,32,R_ECX);
                         emitjmp(C_L,l2);
                         emit_const_reg(A_SUB,S_L,32,R_ECX);
@@ -439,13 +439,13 @@ implementation
                           hregisterhigh);
                         emit_reg_reg(A_MOV,S_L,hregisterhigh,hregisterlow);
                         emit_reg_reg(A_XOR,S_L,hregisterhigh,hregisterhigh);
-                        emitjmp(C_None,l3);
-                        emitlab(l2);
+                        cg.a_jmp_always(exprasmlist,l3);
+                        cg.a_label(exprasmlist,l2);
                         emit_reg_reg_reg(A_SHRD,S_L,R_CL,
                           hregisterhigh,hregisterlow);
                         emit_reg_reg(A_SHR,S_L,R_CL,
                           hregisterhigh);
-                        emitlab(l3);
+                        cg.a_label(exprasmlist,l3);
 
                      end;
 
@@ -463,7 +463,7 @@ implementation
            begin
               { load left operators in a register }
               location_copy(location,left.location);
-              location_force_reg(location,OS_INT,false);
+              location_force_reg(exprasmlist,location,OS_INT,false);
 
               { shifting by a constant directly coded: }
               if (right.nodetype=ordconstn) then
@@ -618,7 +618,7 @@ implementation
 
               { load left operator in a register }
               location_copy(location,left.location);
-              location_force_reg(location,OS_64,false);
+              location_force_reg(exprasmlist,location,OS_64,false);
 
               emit_reg(A_NOT,S_L,location.registerhigh);
               emit_reg(A_NEG,S_L,location.registerlow);
@@ -738,7 +738,7 @@ implementation
                   truelabel:=falselabel;
                   falselabel:=hl;
                   secondpass(left);
-                  maketojumpbool(left,lr_load_regvars);
+                  maketojumpbool(exprasmlist,left,lr_load_regvars);
                   hl:=truelabel;
                   truelabel:=falselabel;
                   falselabel:=hl;
@@ -755,7 +755,7 @@ implementation
               LOC_REFERENCE,
               LOC_CREFERENCE :
                 begin
-                  location_force_reg(left.location,def_cgsize(resulttype.def),true);
+                  location_force_reg(exprasmlist,left.location,def_cgsize(resulttype.def),true);
                   location_release(exprasmlist,left.location);
                   emit_reg_reg(A_TEST,opsize,left.location.register,left.location.register);
                   location_reset(location,LOC_FLAGS,OS_NO);
@@ -806,7 +806,7 @@ implementation
            begin
               secondpass(left);
               location_copy(location,left.location);
-              location_force_reg(location,OS_64,false);
+              location_force_reg(exprasmlist,location,OS_64,false);
 
               emit_reg(A_NOT,S_L,location.registerlow);
               emit_reg(A_NOT,S_L,location.registerhigh);
@@ -815,7 +815,7 @@ implementation
           begin
             secondpass(left);
             location_copy(location,left.location);
-            location_force_reg(location,def_cgsize(resulttype.def),false);
+            location_force_reg(exprasmlist,location,def_cgsize(resulttype.def),false);
 
             opsize:=def_opsize(resulttype.def);
             emit_reg(A_NOT,opsize,location.register);
@@ -831,7 +831,24 @@ begin
 end.
 {
   $Log$
-  Revision 1.26  2002-04-04 19:06:12  peter
+  Revision 1.27  2002-05-12 16:53:17  peter
+    * moved entry and exitcode to ncgutil and cgobj
+    * foreach gets extra argument for passing local data to the
+      iterator function
+    * -CR checks also class typecasts at runtime by changing them
+      into as
+    * fixed compiler to cycle with the -CR option
+    * fixed stabs with elf writer, finally the global variables can
+      be watched
+    * removed a lot of routines from cga unit and replaced them by
+      calls to cgobj
+    * u32bit-s32bit updates for and,or,xor nodes. When one element is
+      u32bit then the other is typecasted also to u32bit without giving
+      a rangecheck warning/error.
+    * fixed pascal calling method with reversing also the high tree in
+      the parast, detected by tcalcst3 test
+
+  Revision 1.26  2002/04/04 19:06:12  peter
     * removed unused units
     * use tlocation.size in cg.a_*loc*() routines
 

+ 56 - 43
compiler/i386/n386mem.pas

@@ -53,7 +53,7 @@ implementation
       symconst,symtype,symdef,symsym,symtable,aasm,types,
       cginfo,cgbase,pass_2,
       pass_1,nld,ncon,nadd,
-      cpuinfo,cpubase,
+      cpubase,
       cgobj,cga,tgobj,rgobj,ncgutil,n386util;
 
 {*****************************************************************************
@@ -75,18 +75,21 @@ implementation
 *****************************************************************************}
 
     procedure ti386derefnode.pass_2;
-
+      var
+        oldglobalswitches : tglobalswitches;
       begin
+         oldglobalswitches:=aktglobalswitches;
+         exclude(aktglobalswitches,cs_checkpointer);
          inherited pass_2;
+         aktglobalswitches:=oldglobalswitches;
          if tpointerdef(left.resulttype.def).is_far then
           location.reference.segment:=R_FS;
          if not tpointerdef(left.resulttype.def).is_far and
             (cs_gdb_heaptrc in aktglobalswitches) and
             (cs_checkpointer in aktglobalswitches) then
           begin
-             emit_reg(
-               A_PUSH,S_L,location.reference.base);
-             emitcall('FPC_CHECKPOINTER');
+            cg.a_param_reg(exprasmlist, OS_ADDR,location.reference.base,1);
+            cg.a_call_name(exprasmlist,'FPC_CHECKPOINTER');
           end;
       end;
 
@@ -162,13 +165,10 @@ implementation
                         exit;
                      end;
                    rg.saveusedregisters(exprasmlist,pushed,all_registers);
-                   emitpushreferenceaddr(left.location.reference);
+                   cg.a_paramaddr_ref(exprasmlist,left.location.reference,1);
                    rg.saveregvars(exprasmlist,all_registers);
-                   if is_ansistring(left.resulttype.def) then
-                     emitcall('FPC_ANSISTR_UNIQUE')
-                   else
-                     emitcall('FPC_WIDESTR_UNIQUE');
-                   maybe_loadself;
+                   cg.a_call_name(exprasmlist,'FPC_'+Upper(tstringdef(left.resulttype.def).stringtypname)+'_UNIQUE');
+                   cg.g_maybe_loadself(exprasmlist);
                    rg.restoreusedregisters(exprasmlist,pushed);
                 end;
 
@@ -181,8 +181,7 @@ implementation
                   begin
                     location_release(exprasmlist,left.location);
                     location.reference.base:=rg.getregisterint(exprasmlist);
-                    emit_ref_reg(A_MOV,S_L,
-                      left.location.reference,location.reference.base);
+                    cg.a_load_ref_reg(exprasmlist,OS_ADDR,left.location.reference,location.reference.base);
                   end;
                 else
                   internalerror(2002032218);
@@ -193,10 +192,10 @@ implementation
               if (cs_check_range in aktlocalswitches) then
                 begin
                    rg.saveusedregisters(exprasmlist,pushed,all_registers);
-                   emit_reg(A_PUSH,S_L,location.reference.base);
+                   cg.a_param_reg(exprasmlist,OS_ADDR,location.reference.base,1);
                    rg.saveregvars(exprasmlist,all_registers);
-                   emitcall('FPC_ANSISTR_CHECKZERO');
-                   maybe_loadself;
+                   cg.a_call_name(exprasmlist,'FPC_'+Upper(tstringdef(left.resulttype.def).stringtypname)+'_CHECKZERO');
+                   cg.g_maybe_loadself(exprasmlist);
                    rg.restoreusedregisters(exprasmlist,pushed);
                 end;
 
@@ -237,8 +236,8 @@ implementation
                    rg.saveusedregisters(exprasmlist,pushed,all_registers);
                    emit_reg(A_PUSH,S_L,location.reference.base);
                    rg.saveregvars(exprasmlist,all_registers);
-                   emitcall('FPC_ANSISTR_CHECKZERO');
-                   maybe_loadself;
+                   cg.a_call_name(exprasmlist,'FPC_ANSISTR_CHECKZERO');
+                   cg.g_maybe_loadself(exprasmlist);
                    rg.restoreusedregisters(exprasmlist,pushed);
                 end;
 
@@ -283,24 +282,26 @@ implementation
                 end
               else if (left.resulttype.def.deftype=stringdef) then
                 begin
-                   if (tordconstnode(right).value=0) and not(is_shortstring(left.resulttype.def)) then
+                   if (tordconstnode(right).value=0) and
+                      not(is_shortstring(left.resulttype.def)) then
                      CGMessage(cg_e_can_access_element_zero);
 
                    if (cs_check_range in aktlocalswitches) then
-                     case tstringdef(left.resulttype.def).string_typ of
+                    begin
+                      case tstringdef(left.resulttype.def).string_typ of
                         { it's the same for ansi- and wide strings }
                         st_widestring,
                         st_ansistring:
                           begin
                              rg.saveusedregisters(exprasmlist,pushed,all_registers);
-                             push_int(tordconstnode(right).value);
+                             cg.a_param_const(exprasmlist,OS_INT,tordconstnode(right).value,2);
                              href:=location.reference;
                              dec(href.offset,7);
-                             emit_ref(A_PUSH,S_L,href);
+                             cg.a_param_ref(exprasmlist,OS_INT,href,1);
                              rg.saveregvars(exprasmlist,all_registers);
-                             emitcall('FPC_ANSISTR_RANGECHECK');
+                             cg.a_call_name(exprasmlist,'FPC_'+Upper(tstringdef(left.resulttype.def).stringtypname)+'_RANGECHECK');
                              rg.restoreusedregisters(exprasmlist,pushed);
-                             maybe_loadself;
+                             cg.g_maybe_loadself(exprasmlist);
                           end;
 
                         st_shortstring:
@@ -312,30 +313,25 @@ implementation
                           begin
                              {!!!!!!!!!!!!!!!!!}
                           end;
-                     end;
+                      end;
+                    end;
                 end;
               inc(left.location.reference.offset,
                   get_mul_size*tordconstnode(right).value);
               if nf_memseg in flags then
                 left.location.reference.segment:=R_FS;
-              {
-              left.resulttype:=resulttype.def;
-              disposetree(right);
-              _p:=left;
-              putnode(p);
-              p:=_p;
-              }
+
               location_copy(location,left.location);
            end
          else
          { not nodetype=ordconstn }
            begin
               if (cs_regalloc in aktglobalswitches) and
-              { if we do range checking, we don't }
-              { need that fancy code (it would be }
-              { buggy)                            }
-                not(cs_check_range in aktlocalswitches) and
-                (left.resulttype.def.deftype=arraydef) then
+                 { if we do range checking, we don't }
+                 { need that fancy code (it would be }
+                 { buggy)                            }
+                 not(cs_check_range in aktlocalswitches) and
+                 (left.resulttype.def.deftype=arraydef) then
                 begin
                    extraoffset:=0;
                    if (right.nodetype=addn) then
@@ -433,7 +429,7 @@ implementation
                    end;
                end;
 
-              location_force_reg(right.location,OS_32,false);
+              location_force_reg(exprasmlist,right.location,OS_32,false);
 
               if isjump then
                begin
@@ -456,14 +452,14 @@ implementation
                          st_ansistring:
                            begin
                               rg.saveusedregisters(exprasmlist,pushed,all_registers);
-                              emit_reg(A_PUSH,S_L,right.location.register);
+                              cg.a_param_reg(exprasmlist,OS_INT,right.location.register,1);
                               href:=location.reference;
                               dec(href.offset,7);
-                              emit_ref(A_PUSH,S_L,href);
+                              cg.a_param_ref(exprasmlist,OS_INT,href,1);
                               rg.saveregvars(exprasmlist,all_registers);
-                              emitcall('FPC_ANSISTR_RANGECHECK');
+                              cg.a_call_name(exprasmlist,'FPC_'+Upper(tstringdef(left.resulttype.def).stringtypname)+'_RANGECHECK');
                               rg.restoreusedregisters(exprasmlist,pushed);
-                              maybe_loadself;
+                              cg.g_maybe_loadself(exprasmlist);
                            end;
                          st_shortstring:
                            begin
@@ -525,7 +521,24 @@ begin
 end.
 {
   $Log$
-  Revision 1.28  2002-04-21 19:02:07  peter
+  Revision 1.29  2002-05-12 16:53:17  peter
+    * moved entry and exitcode to ncgutil and cgobj
+    * foreach gets extra argument for passing local data to the
+      iterator function
+    * -CR checks also class typecasts at runtime by changing them
+      into as
+    * fixed compiler to cycle with the -CR option
+    * fixed stabs with elf writer, finally the global variables can
+      be watched
+    * removed a lot of routines from cga unit and replaced them by
+      calls to cgobj
+    * u32bit-s32bit updates for and,or,xor nodes. When one element is
+      u32bit then the other is typecasted also to u32bit without giving
+      a rangecheck warning/error.
+    * fixed pascal calling method with reversing also the high tree in
+      the parast, detected by tcalcst3 test
+
+  Revision 1.28  2002/04/21 19:02:07  peter
     * removed newn and disposen nodes, the code is now directly
       inlined from pexpr
     * -an option that will write the secondpass nodes to the .s file, this

+ 21 - 6
compiler/i386/n386obj.pas

@@ -37,7 +37,7 @@ uses
   fmodule,
   nobj,
   cpubase,
-  cga,tgobj,rgobj;
+  cga,tgobj,rgobj,cgobj;
 
    type
      ti386classheader=class(tclassheader)
@@ -122,7 +122,7 @@ procedure ti386classheader.cgintfwrapper(asmlist: TAAsmoutput; procdef: tprocdef
   begin
     { mov offset(%esp),%eax }
     reference_reset_base(href,R_ESP,getselfoffsetfromsp(procdef));
-    emit_ref_reg(A_MOV,S_L,href,R_EAX);
+    cg.a_load_ref_reg(exprasmlist,OS_ADDR,href,R_EAX);
   end;
 
   procedure loadvmttoeax;
@@ -195,9 +195,7 @@ begin
           op_oneaxmethodaddr(A_CALL);
         end
       else { case 1 }
-        begin
-          emitcall(procdef.mangledname);
-        end;
+        cg.a_call_name(exprasmlist,procdef.mangledname);
       { restore param1 value self to interface }
       adjustselfvalue(-ioffset);
     end
@@ -239,7 +237,24 @@ initialization
 end.
 {
   $Log$
-  Revision 1.6  2002-04-02 17:11:36  peter
+  Revision 1.7  2002-05-12 16:53:17  peter
+    * moved entry and exitcode to ncgutil and cgobj
+    * foreach gets extra argument for passing local data to the
+      iterator function
+    * -CR checks also class typecasts at runtime by changing them
+      into as
+    * fixed compiler to cycle with the -CR option
+    * fixed stabs with elf writer, finally the global variables can
+      be watched
+    * removed a lot of routines from cga unit and replaced them by
+      calls to cgobj
+    * u32bit-s32bit updates for and,or,xor nodes. When one element is
+      u32bit then the other is typecasted also to u32bit without giving
+      a rangecheck warning/error.
+    * fixed pascal calling method with reversing also the high tree in
+      the parast, detected by tcalcst3 test
+
+  Revision 1.6  2002/04/02 17:11:36  peter
     * tlocation,treference update
     * LOC_CONSTANT added for better constant handling
     * secondadd splitted in multiple routines

+ 43 - 20
compiler/i386/n386opt.pas

@@ -41,8 +41,13 @@ type
 
 implementation
 
-uses pass_1, types, htypechk, cginfo, cgbase, cpubase, cga,
-     tgobj, aasm, ncnv, ncon, pass_2, symdef, rgobj, cgobj;
+uses
+  pass_1, types, htypechk,
+  symdef,
+  aasm,
+  ncnv, ncon, pass_2,
+  cginfo, cgbase, cpubase,
+  tgobj, rgobj, cgobj, n386util;
 
 
 {*****************************************************************************
@@ -86,6 +91,7 @@ var
   href,href2 :  treference;
   hreg, lengthreg: tregister;
   checklength: boolean;
+  len : integer;
 begin
   { first, we have to more or less replicate some code from }
   { ti386addnode.pass_2                                     }
@@ -118,15 +124,15 @@ begin
         reference_release(exprasmlist,right.location.reference);
         { get register for the char }
         hreg := rg.makeregsize(rg.getregisterint(exprasmlist),OS_8);
-        emit_ref_reg(A_MOV,S_B,right.location.reference,hreg);
-       { I don't think a temp char exists, but it won't hurt (JM) }
-       tg.ungetiftemp(exprasmlist,right.location.reference);
+        cg.a_load_ref_reg(exprasmlist,OS_8,right.location.reference,hreg);
+        { I don't think a temp char exists, but it won't hurt (JM) }
+        tg.ungetiftemp(exprasmlist,right.location.reference);
       end
     else hreg := right.location.register;
 
   { load the current string length }
   lengthreg := rg.getregisterint(exprasmlist);
-  emit_ref_reg(A_MOVZX,S_BL,left.location.reference,lengthreg);
+  cg.a_load_ref_reg(exprasmlist,OS_8,left.location.reference,lengthreg);
 
   { do we have to check the length ? }
   if tg.istemp(left.location.reference) then
@@ -138,10 +144,10 @@ begin
       { is it already maximal? }
       getlabel(l);
       if tg.istemp(left.location.reference) then
-        emit_const_reg(A_CMP,S_L,255,lengthreg)
+        len:=255
       else
-        emit_const_reg(A_CMP,S_L,tstringdef(left.resulttype.def).len,lengthreg);
-      emitjmp(C_E,l);
+        len:=tstringdef(left.resulttype.def).len;
+      cg.a_cmp_const_reg_label(exprasmlist,OS_INT,OC_EQ,len,lengthreg,l)
     end;
 
   { no, so increase the length and add the new character }
@@ -156,7 +162,7 @@ begin
       { they're not free, so add the base reg to       }
       { the string length (since the index can         }
       { have a scalefactor) and use lengthreg as base  }
-      emit_reg_reg(A_ADD,S_L,href2.base,lengthreg);
+      cg.a_op_reg_reg(exprasmlist,OP_ADD,OS_INT,href2.base,lengthreg);
       href2.base := lengthreg;
     end
   else
@@ -175,17 +181,17 @@ begin
     begin
       { no new_reference(href2) because it's only }
       { used once (JM)                            }
-      emit_reg_ref(A_MOV,S_B,hreg,href2);
+      cg.a_load_reg_ref(exprasmlist,OS_8,hreg,href2);
       rg.ungetregister(exprasmlist,hreg);
     end
   else
-    emit_const_ref(A_MOV,S_B,tordconstnode(right).value,href2);
+    cg.a_load_const_ref(exprasmlist,OS_8,tordconstnode(right).value,href2);
   { increase the string length }
-  emit_reg(A_INC,S_B,rg.makeregsize(lengthreg,OS_8));
-  emit_reg_ref(A_MOV,S_B,rg.makeregsize(lengthreg,OS_8),left.location.reference);
+  cg.a_op_const_reg(exprasmlist,OP_ADD,1,rg.makeregsize(lengthreg,OS_8));
+  cg.a_load_reg_ref(exprasmlist,OS_8,rg.makeregsize(lengthreg,OS_8),left.location.reference);
   rg.ungetregisterint(exprasmlist,lengthreg);
   if checklength then
-    emitlab(l);
+    cg.a_label(exprasmlist,l);
   location_copy(location,left.location);
 end;
 
@@ -220,17 +226,17 @@ begin
   remove_non_regvars_from_loc(right.location,regstopush);
   rg.saveusedregisters(exprasmlist,pushedregs,regstopush);
   { push the maximum possible length of the result }
-  emitpushreferenceaddr(left.location.reference);
+  cg.a_paramaddr_ref(exprasmlist,left.location.reference,2);
   { the optimizer can more easily put the          }
   { deallocations in the right place if it happens }
   { too early than when it happens too late (if    }
   { the pushref needs a "lea (..),edi; push edi")  }
   reference_release(exprasmlist,right.location.reference);
-  emitpushreferenceaddr(right.location.reference);
+  cg.a_paramaddr_ref(exprasmlist,right.location.reference,1);
   rg.saveregvars(exprasmlist,regstopush);
-  emitcall('FPC_SHORTSTR_CONCAT');
+  cg.a_call_name(exprasmlist,'FPC_SHORTSTR_CONCAT');
   tg.ungetiftemp(exprasmlist,right.location.reference);
-  maybe_loadself;
+  cg.g_maybe_loadself(exprasmlist);
   rg.restoreusedregisters(exprasmlist,pushedregs);
   location_copy(location,left.location);
 end;
@@ -242,7 +248,24 @@ end.
 
 {
   $Log$
-  Revision 1.12  2002-04-25 20:16:40  peter
+  Revision 1.13  2002-05-12 16:53:17  peter
+    * moved entry and exitcode to ncgutil and cgobj
+    * foreach gets extra argument for passing local data to the
+      iterator function
+    * -CR checks also class typecasts at runtime by changing them
+      into as
+    * fixed compiler to cycle with the -CR option
+    * fixed stabs with elf writer, finally the global variables can
+      be watched
+    * removed a lot of routines from cga unit and replaced them by
+      calls to cgobj
+    * u32bit-s32bit updates for and,or,xor nodes. When one element is
+      u32bit then the other is typecasted also to u32bit without giving
+      a rangecheck warning/error.
+    * fixed pascal calling method with reversing also the high tree in
+      the parast, detected by tcalcst3 test
+
+  Revision 1.12  2002/04/25 20:16:40  peter
     * moved more routines from cga/n386util
 
   Revision 1.11  2002/04/21 15:36:40  carl

+ 41 - 24
compiler/i386/n386set.pas

@@ -44,7 +44,7 @@ interface
 implementation
 
     uses
-      globtype,systems,cpuinfo,
+      globtype,systems,
       verbose,globals,
       symconst,symdef,aasm,types,
       cginfo,cgbase,pass_2,
@@ -66,7 +66,7 @@ implementation
        { load first value in 32bit register }
          secondpass(left);
          if left.location.loc in [LOC_REGISTER,LOC_CREGISTER] then
-           location_force_reg(left.location,OS_32,false);
+           location_force_reg(exprasmlist,left.location,OS_32,false);
 
        { also a second value ? }
          if assigned(right) then
@@ -78,7 +78,7 @@ implementation
              if pushed then
                restore(left,false);
              if right.location.loc in [LOC_REGISTER,LOC_CREGISTER] then
-              location_force_reg(right.location,OS_32,false);
+              location_force_reg(exprasmlist,right.location,OS_32,false);
            end;
 
          { we doesn't modify the left side, we check only the type }
@@ -313,7 +313,7 @@ implementation
                   { it's always true since "in" is only allowed for bytes }
                   begin
                     emit_none(A_STC,S_NO);
-                    emitjmp(C_NONE,l);
+                    cg.a_jmp_always(exprasmlist,l);
                   end;
               end
              else
@@ -335,7 +335,7 @@ implementation
              { To compensate for not doing a second pass }
              right.location.reference.symbol:=nil;
              { Now place the end label }
-             emitlab(l);
+             cg.a_label(exprasmlist,l);
              case left.location.loc of
                LOC_REGISTER,
                LOC_CREGISTER :
@@ -457,8 +457,8 @@ implementation
                           emitjmp(C_NA,l);
                         { reset carry flag }
                           emit_none(A_CLC,S_NO);
-                          emitjmp(C_NONE,l2);
-                          emitlab(l);
+                          cg.a_jmp_always(exprasmlist,l2);
+                          cg.a_label(exprasmlist,l);
                         { We have to load the value into a register because
                           btl does not accept values only refs or regs (PFV) }
                           hr2:=rg.getregisterint(exprasmlist);
@@ -483,8 +483,8 @@ implementation
                        emitjmp(C_NA,l);
                      { reset carry flag }
                        emit_none(A_CLC,S_NO);
-                       emitjmp(C_NONE,l2);
-                       emitlab(l);
+                       cg.a_jmp_always(exprasmlist,l2);
+                       cg.a_label(exprasmlist,l);
                        location_release(exprasmlist,left.location);
                        hr:=rg.getregisterint(exprasmlist);
                        emit_ref_reg(A_MOV,S_L,left.location.reference,hr);
@@ -497,7 +497,7 @@ implementation
                        rg.ungetregisterint(exprasmlist,hr2);
                     end;
                   end;
-                  emitlab(l2);
+                  cg.a_label(exprasmlist,l2);
                 end { of right.location.loc=LOC_CONSTANT }
                { do search in a normal set which could have >32 elementsm
                  but also used if the left side contains higher values > 32 }
@@ -555,7 +555,7 @@ implementation
            lesslabel,greaterlabel : tasmlabel;
 
        begin
-         emitlab(p^._at);
+         cg.a_label(exprasmlist,p^._at);
          { calculate labels for left and right }
          if (p^.less=nil) then
            lesslabel:=elselabel
@@ -577,7 +577,7 @@ implementation
                    emitjmp(jmp_le,lesslabel);
                    emitjmp(jmp_gt,greaterlabel);
                 end;
-              emitjmp(C_None,p^.statement);
+              cg.a_jmp_always(exprasmlist,p^.statement);
            end
          else
            begin
@@ -585,7 +585,7 @@ implementation
               emitjmp(jmp_le,lesslabel);
               emit_const_reg(A_CMP,opsize,p^._high,hregister);
               emitjmp(jmp_gt,greaterlabel);
-              emitjmp(C_None,p^.statement);
+              cg.a_jmp_always(exprasmlist,p^.statement);
            end;
           if assigned(p^.less) then
            gentreejmp(p^.less);
@@ -616,7 +616,7 @@ implementation
                        emitjmp(C_NZ,l1);
                        emit_const_reg(A_CMP,S_L,longint(lo(int64(t^._low))),hregister);
                        emitjmp(C_Z,t^.statement);
-                       emitlab(l1);
+                       cg.a_label(exprasmlist,l1);
                     end
                   else
                     begin
@@ -641,7 +641,7 @@ implementation
                             emit_const_reg(A_CMP,S_L,longint(lo(int64(t^._low))),hregister);
                             { the comparisation of the low dword must be always unsigned! }
                             emitjmp(C_B,elselabel);
-                            emitlab(l1);
+                            cg.a_label(exprasmlist,l1);
                          end
                        else
                          begin
@@ -659,7 +659,7 @@ implementation
                        emit_const_reg(A_CMP,S_L,longint(lo(int64(t^._high))),hregister);
                        { the comparisation of the low dword must be always unsigned! }
                        emitjmp(C_BE,t^.statement);
-                       emitlab(l1);
+                       cg.a_label(exprasmlist,l1);
                     end
                   else
                     begin
@@ -678,7 +678,7 @@ implementation
            last:=0;
            first:=true;
            genitem(hp);
-           emitjmp(C_None,elselabel);
+           cg.a_jmp_always(exprasmlist,elselabel);
         end;
 
       procedure genlinearlist(hp : pcaserecord);
@@ -725,7 +725,7 @@ implementation
                     begin
                        { have we to ajust the first value ? }
                        if (t^._low>get_min_value(left.resulttype.def)) then
-                         gensub(t^._low);
+                         gensub(longint(t^._low));
                     end
                   else
                     begin
@@ -756,7 +756,7 @@ implementation
                 last:=0;
                 first:=true;
                 genitem(hp);
-                emitjmp(C_None,elselabel);
+                cg.a_jmp_always(exprasmlist,elselabel);
              end;
         end;
 
@@ -881,7 +881,7 @@ implementation
          { determines the size of the operand }
          opsize:=bytes2Sxx[left.resulttype.def.size];
          { copy the case expression to a register }
-         location_force_reg(left.location,def_cgsize(left.resulttype.def),false);
+         location_force_reg(exprasmlist,left.location,def_cgsize(left.resulttype.def),false);
          if opsize=S_Q then
           begin
             hregister:=left.location.registerlow;
@@ -997,10 +997,10 @@ implementation
               { don't come back to case line }
               aktfilepos:=exprasmList.getlasttaifilepos^;
               load_all_regvars(exprasmlist);
-              emitjmp(C_None,endlabel);
+              cg.a_jmp_always(exprasmlist,endlabel);
               hp:=tbinarynode(hp).left;
            end;
-         emitlab(elselabel);
+         cg.a_label(exprasmlist,elselabel);
          { ...and the else block }
          if assigned(elseblock) then
            begin
@@ -1008,7 +1008,7 @@ implementation
               secondpass(elseblock);
               load_all_regvars(exprasmlist);
            end;
-         emitlab(endlabel);
+         cg.a_label(exprasmlist,endlabel);
       end;
 
 
@@ -1019,7 +1019,24 @@ begin
 end.
 {
   $Log$
-  Revision 1.26  2002-04-25 20:16:40  peter
+  Revision 1.27  2002-05-12 16:53:17  peter
+    * moved entry and exitcode to ncgutil and cgobj
+    * foreach gets extra argument for passing local data to the
+      iterator function
+    * -CR checks also class typecasts at runtime by changing them
+      into as
+    * fixed compiler to cycle with the -CR option
+    * fixed stabs with elf writer, finally the global variables can
+      be watched
+    * removed a lot of routines from cga unit and replaced them by
+      calls to cgobj
+    * u32bit-s32bit updates for and,or,xor nodes. When one element is
+      u32bit then the other is typecasted also to u32bit without giving
+      a rangecheck warning/error.
+    * fixed pascal calling method with reversing also the high tree in
+      the parast, detected by tcalcst3 test
+
+  Revision 1.26  2002/04/25 20:16:40  peter
     * moved more routines from cga/n386util
 
   Revision 1.25  2002/04/21 19:02:07  peter

+ 48 - 7
compiler/i386/n386util.pas

@@ -38,25 +38,26 @@ interface
 {$ifdef TEMPS_NOT_PUSH}
     procedure restorefromtemp(p : tnode;isint64 : boolean);
 {$endif TEMPS_NOT_PUSH}
+    procedure remove_non_regvars_from_loc(const t: tlocation; var regs: tregisterset);
     procedure push_value_para(p:tnode;inlined,is_cdecl:boolean;
                               para_offset:longint;alignment : longint);
 
     procedure emitoverflowcheck(p:tnode);
     procedure firstcomplex(p : tbinarynode);
 
+
 implementation
 
     uses
        globtype,globals,systems,verbose,
        cutils,
        aasm,cpuasm,
-       symconst,symdef,symsym,symtable,
+       symconst,symdef,
 {$ifdef GDB}
        gdb,
 {$endif GDB}
        types,
        ncgutil,ncon,nld,
-       pass_1,pass_2,
        cgbase,tgobj,
        cga,regvars,cgobj,cg64f32,rgobj,rgcpu,cgcpu;
 
@@ -142,7 +143,7 @@ implementation
            begin
              if p.location.loc = LOC_FPUREGISTER then
                begin
-                 location_force_mem(p.location);
+                 location_force_mem(exprasmlist,p.location);
                  maybe_pushfpu:=true;
                end
              else
@@ -295,6 +296,29 @@ implementation
       end;
 {$endif TEMPS_NOT_PUSH}
 
+    { only usefull in startup code }
+    procedure remove_non_regvars_from_loc(const t: tlocation; var regs: tregisterset);
+      begin
+        case t.loc of
+          LOC_REGISTER:
+            begin
+              { can't be a regvar, since it would be LOC_CREGISTER then }
+              exclude(regs,t.register);
+              if t.registerhigh <> R_NO then
+                exclude(regs,t.registerhigh);
+            end;
+          LOC_CREFERENCE,LOC_REFERENCE:
+            begin
+              if not(cs_regalloc in aktglobalswitches) or
+                 (t.reference.base in rg.usableregsint) then
+                exclude(regs,t.reference.base);
+              if not(cs_regalloc in aktglobalswitches) or
+                 (t.reference.index in rg.usableregsint) then
+              exclude(regs,t.reference.index);
+            end;
+        end;
+      end;
+
 
     procedure push_value_para(p:tnode;inlined,is_cdecl:boolean;
                                 para_offset:longint;alignment : longint);
@@ -308,7 +332,7 @@ implementation
       begin
         { Move flags and jump in register to make it less complex }
         if p.location.loc in [LOC_FLAGS,LOC_JUMP] then
-         location_force_reg(p.location,def_cgsize(p.resulttype.def),false);
+         location_force_reg(exprasmlist,p.location,def_cgsize(p.resulttype.def),false);
 
         { Handle Floating point types differently }
         if p.resulttype.def.deftype=floatdef then
@@ -483,8 +507,8 @@ implementation
            emitjmp(C_NO,hl)
          else
            emitjmp(C_NB,hl);
-         emitcall('FPC_OVERFLOW');
-         emitlab(hl);
+         cg.a_call_name(exprasmlist,'FPC_OVERFLOW');
+         cg.a_label(exprasmlist,hl);
       end;
 
    { DO NOT RELY on the fact that the tnode is not yet swaped
@@ -530,7 +554,24 @@ implementation
 end.
 {
   $Log$
-  Revision 1.35  2002-04-25 20:16:40  peter
+  Revision 1.36  2002-05-12 16:53:18  peter
+    * moved entry and exitcode to ncgutil and cgobj
+    * foreach gets extra argument for passing local data to the
+      iterator function
+    * -CR checks also class typecasts at runtime by changing them
+      into as
+    * fixed compiler to cycle with the -CR option
+    * fixed stabs with elf writer, finally the global variables can
+      be watched
+    * removed a lot of routines from cga unit and replaced them by
+      calls to cgobj
+    * u32bit-s32bit updates for and,or,xor nodes. When one element is
+      u32bit then the other is typecasted also to u32bit without giving
+      a rangecheck warning/error.
+    * fixed pascal calling method with reversing also the high tree in
+      the parast, detected by tcalcst3 test
+
+  Revision 1.35  2002/04/25 20:16:40  peter
     * moved more routines from cga/n386util
 
   Revision 1.34  2002/04/21 15:39:41  carl

+ 21 - 4
compiler/i386/optbase.pas

@@ -1,7 +1,7 @@
 {
     $Id$
     Copyright (c) 1998-2002 by the Free Pascal development team
-    
+
     This routine contains the basic tables and information
     for the generic optimizers and cpu specific optimizations.
 
@@ -23,7 +23,7 @@
 }
 {# This unit should define cpu specific information which is required
    for the optimizers.
-}   
+}
 unit optbase;
 
 interface
@@ -79,7 +79,24 @@ end.
 
 {
   $Log$
-  Revision 1.1  2002-04-20 21:50:14  carl
+  Revision 1.2  2002-05-12 16:53:18  peter
+    * moved entry and exitcode to ncgutil and cgobj
+    * foreach gets extra argument for passing local data to the
+      iterator function
+    * -CR checks also class typecasts at runtime by changing them
+      into as
+    * fixed compiler to cycle with the -CR option
+    * fixed stabs with elf writer, finally the global variables can
+      be watched
+    * removed a lot of routines from cga unit and replaced them by
+      calls to cgobj
+    * u32bit-s32bit updates for and,or,xor nodes. When one element is
+      u32bit then the other is typecasted also to u32bit without giving
+      a rangecheck warning/error.
+    * fixed pascal calling method with reversing also the high tree in
+      the parast, detected by tcalcst3 test
+
+  Revision 1.1  2002/04/20 21:50:14  carl
   + optimization cpu specific information base file
 
-}  
+}

+ 45 - 25
compiler/i386/popt386.pas

@@ -41,7 +41,7 @@ Uses
 {$ifdef finaldestdebug}
   cobjects,
 {$endif finaldestdebug}
-  tainst,cpubase,optbase,cpuasm,DAOpt386,cginfo,rgobj;
+  tainst,cpuinfo,cpubase,cpuasm,DAOpt386,cginfo,rgobj;
 
 Function RegUsedAfterInstruction(Reg: TRegister; p: Tai; Var UsedRegs: TRegSet): Boolean;
 Begin
@@ -102,7 +102,7 @@ end;
 Procedure PrePeepHoleOpts(AsmL: TAAsmOutput; BlockStart, BlockEnd: Tai);
 var
   p,hp1: Tai;
-  l: longint;
+  l: Aword;
   tmpRef: treference;
 Begin
   P := BlockStart;
@@ -344,7 +344,7 @@ Begin
                             Taicpu(hp1).opcode := A_AND;
                             l := (1 shl (Taicpu(hp1).oper[0].val)) - 1;
                             Case Taicpu(p).opsize Of
-                              S_L: Taicpu(hp1).LoadConst(0,l Xor longint(-1));
+                              S_L: Taicpu(hp1).LoadConst(0,l Xor aword($ffffffff));
                               S_B: Taicpu(hp1).LoadConst(0,l Xor $ff);
                               S_W: Taicpu(hp1).LoadConst(0,l Xor $ffff);
                             End;
@@ -361,7 +361,7 @@ Begin
                                 Taicpu(p).opcode := A_AND;
                                 l := (1 shl (Taicpu(p).oper[0].val))-1;
                                 Case Taicpu(p).opsize Of
-                                  S_L: Taicpu(p).LoadConst(0,l Xor longint($ffffffff));
+                                  S_L: Taicpu(p).LoadConst(0,l Xor aword($ffffffff));
                                   S_B: Taicpu(p).LoadConst(0,l Xor $ff);
                                   S_W: Taicpu(p).LoadConst(0,l Xor $ffff);
                                 End;
@@ -377,7 +377,7 @@ Begin
                                   Case Taicpu(p).opsize Of
                                     S_B: Taicpu(p).LoadConst(0,l Xor $ff);
                                     S_W: Taicpu(p).LoadConst(0,l Xor $ffff);
-                                    S_L: Taicpu(p).LoadConst(0,l Xor longint($ffffffff));
+                                    S_L: Taicpu(p).LoadConst(0,l Xor aword($ffffffff));
                                   End;
                                   asml.remove(hp1);
                                   hp1.free;
@@ -563,7 +563,7 @@ Var
               (Taicpu(hp1).oper[1].typ = top_reg) And
               (Taicpu(hp1).oper[1].reg = Taicpu(p).oper[1].reg) Then
              Begin
-               Taicpu(p).LoadConst(0,Taicpu(p).oper[0].val-Taicpu(hp1).oper[0].val);
+               Taicpu(p).LoadConst(0,AWord(int64(Taicpu(p).oper[0].val)-int64(Taicpu(hp1).oper[0].val)));
                asml.Remove(hp1);
                hp1.free;
                If (Taicpu(p).oper[0].val = 0) Then
@@ -870,21 +870,24 @@ Begin
                           if (Base = Taicpu(p).oper[1].reg) then
                             begin
                               l := offset+offsetfixup;
-                              case l of
-                                1,-1:
-                                  begin
-                                    if l = 1 then
-                                      Taicpu(p).opcode := A_INC
-                                    else Taicpu(p).opcode := A_DEC;
-                                    Taicpu(p).loadreg(0,Taicpu(p).oper[1].reg);
-                                    Taicpu(p).ops := 1;
-                                  end;
-                                else
-                                  begin
-                                    Taicpu(p).opcode := A_ADD;
-                                    Taicpu(p).loadconst(0,offset+offsetfixup);
-                                  end;
-                              end;
+                              if (l=1) then
+                               begin
+                                 Taicpu(p).opcode := A_INC;
+                                 Taicpu(p).loadreg(0,Taicpu(p).oper[1].reg);
+                                 Taicpu(p).ops := 1
+                               end
+                              else
+                               if (l=-1) then
+                                begin
+                                  Taicpu(p).opcode := A_DEC;
+                                  Taicpu(p).loadreg(0,Taicpu(p).oper[1].reg);
+                                  Taicpu(p).ops := 1;
+                                end
+                              else
+                               begin
+                                 Taicpu(p).opcode := A_ADD;
+                                 Taicpu(p).loadconst(0,aword(l));
+                               end;
                             end;
                 End;
               A_MOV:
@@ -1213,7 +1216,7 @@ Begin
                       Case Taicpu(p).opsize of
                         S_BW:
                           Begin
-                            If (Taicpu(p).oper[0].reg = rg.makeregsize(Taicpu(p).oper[1].reg,OS_8)) And
+                            If (rg.makeregsize(Taicpu(p).oper[0].reg,OS_16)=Taicpu(p).oper[1].reg) And
                                Not(CS_LittleSize In aktglobalswitches)
                               Then
                                 {Change "movzbw %al, %ax" to "andw $0x0ffh, %ax"}
@@ -1241,7 +1244,7 @@ Begin
                           End;
                         S_BL:
                           Begin
-                            If (Taicpu(p).oper[0].reg = rg.makeregsize(Taicpu(p).oper[1].reg,OS_8)) And
+                            If (rg.makeregsize(Taicpu(p).oper[0].reg,OS_32)=Taicpu(p).oper[1].reg) And
                                Not(CS_LittleSize in aktglobalswitches)
                               Then
                                 {Change "movzbl %al, %eax" to "andl $0x0ffh, %eax"}
@@ -1269,7 +1272,7 @@ Begin
                           End;
                         S_WL:
                           Begin
-                            If (Taicpu(p).oper[0].reg = rg.makeregsize(Taicpu(p).oper[1].reg,OS_16)) And
+                            If (rg.makeregsize(Taicpu(p).oper[0].reg,OS_32)=Taicpu(p).oper[1].reg) And
                                Not(CS_LittleSize In aktglobalswitches)
                               Then
                                {Change "movzwl %ax, %eax" to "andl $0x0ffffh, %eax"}
@@ -2040,7 +2043,24 @@ End.
 
 {
   $Log$
-  Revision 1.23  2002-04-21 15:40:49  carl
+  Revision 1.24  2002-05-12 16:53:18  peter
+    * moved entry and exitcode to ncgutil and cgobj
+    * foreach gets extra argument for passing local data to the
+      iterator function
+    * -CR checks also class typecasts at runtime by changing them
+      into as
+    * fixed compiler to cycle with the -CR option
+    * fixed stabs with elf writer, finally the global variables can
+      be watched
+    * removed a lot of routines from cga unit and replaced them by
+      calls to cgobj
+    * u32bit-s32bit updates for and,or,xor nodes. When one element is
+      u32bit then the other is typecasted also to u32bit without giving
+      a rangecheck warning/error.
+    * fixed pascal calling method with reversing also the high tree in
+      the parast, detected by tcalcst3 test
+
+  Revision 1.23  2002/04/21 15:40:49  carl
   * changeregsize -> rg.makeregsize
 
   Revision 1.22  2002/04/20 21:37:07  carl

+ 19 - 2
compiler/i386/ra386.pas

@@ -65,7 +65,7 @@ const
   AsmOverride : array[0..AsmOverrides-1] of TasmOP =(
     A_SEGCS,A_SEGES,A_SEGDS,A_SEGFS,A_SEGGS,A_SEGSS
   );
-  
+
   CondAsmOps=3;
   CondAsmOp:array[0..CondAsmOps-1] of TasmOp=(
     A_CMOVcc, A_Jcc, A_SETcc
@@ -668,7 +668,24 @@ end;
 end.
 {
   $Log$
-  Revision 1.17  2002-04-15 19:12:09  carl
+  Revision 1.18  2002-05-12 16:53:18  peter
+    * moved entry and exitcode to ncgutil and cgobj
+    * foreach gets extra argument for passing local data to the
+      iterator function
+    * -CR checks also class typecasts at runtime by changing them
+      into as
+    * fixed compiler to cycle with the -CR option
+    * fixed stabs with elf writer, finally the global variables can
+      be watched
+    * removed a lot of routines from cga unit and replaced them by
+      calls to cgobj
+    * u32bit-s32bit updates for and,or,xor nodes. When one element is
+      u32bit then the other is typecasted also to u32bit without giving
+      a rangecheck warning/error.
+    * fixed pascal calling method with reversing also the high tree in
+      the parast, detected by tcalcst3 test
+
+  Revision 1.17  2002/04/15 19:12:09  carl
   + target_info.size_of_pointer -> pointer_size
   + some cleanup of unused types/variables
   * move several constants from cpubase to their specific units

+ 19 - 2
compiler/i386/ra386dir.pas

@@ -40,7 +40,7 @@ interface
        globals,verbose,
        systems,
        { aasm }
-       cpubase,aasm,
+       aasm,
        { symtable }
        symconst,symbase,symtype,symsym,symtable,types,
        { pass 1 }
@@ -304,7 +304,24 @@ initialization
 end.
 {
   $Log$
-  Revision 1.14  2002-04-15 19:12:09  carl
+  Revision 1.15  2002-05-12 16:53:18  peter
+    * moved entry and exitcode to ncgutil and cgobj
+    * foreach gets extra argument for passing local data to the
+      iterator function
+    * -CR checks also class typecasts at runtime by changing them
+      into as
+    * fixed compiler to cycle with the -CR option
+    * fixed stabs with elf writer, finally the global variables can
+      be watched
+    * removed a lot of routines from cga unit and replaced them by
+      calls to cgobj
+    * u32bit-s32bit updates for and,or,xor nodes. When one element is
+      u32bit then the other is typecasted also to u32bit without giving
+      a rangecheck warning/error.
+    * fixed pascal calling method with reversing also the high tree in
+      the parast, detected by tcalcst3 test
+
+  Revision 1.14  2002/04/15 19:12:09  carl
   + target_info.size_of_pointer -> pointer_size
   + some cleanup of unused types/variables
   * move several constants from cpubase to their specific units

+ 23 - 6
compiler/i386/rgcpu.pas

@@ -47,10 +47,10 @@ unit rgcpu;
           procedure ungetregisterfpu(list: taasmoutput; r : tregister); override;
 
           procedure ungetreference(list: taasmoutput; const ref : treference); override;
-          
-          {# Returns a subset register of the register r with the specified size. 
+
+          {# Returns a subset register of the register r with the specified size.
              WARNING: There is no clearing of the upper parts of the register,
-             if a 8-bit / 16-bit register is converted to a 32-bit register. 
+             if a 8-bit / 16-bit register is converted to a 32-bit register.
              It is up to the code generator to correctly zero fill the register
           }
           function makeregsize(reg: tregister; size: tcgsize): tregister; override;
@@ -80,7 +80,7 @@ unit rgcpu;
     uses
        systems,
        globals,verbose,
-       tgobj,cga;
+       tgobj;
 
 {************************************************************************}
 {                         routine helpers                                }
@@ -399,7 +399,7 @@ unit rgcpu;
 
 
     function trgcpu.makeregsize(reg: tregister; size: tcgsize): tregister;
-  
+
       var
         _result : topsize;
       begin
@@ -430,7 +430,24 @@ end.
 
 {
   $Log$
-  Revision 1.5  2002-04-21 15:43:32  carl
+  Revision 1.6  2002-05-12 16:53:18  peter
+    * moved entry and exitcode to ncgutil and cgobj
+    * foreach gets extra argument for passing local data to the
+      iterator function
+    * -CR checks also class typecasts at runtime by changing them
+      into as
+    * fixed compiler to cycle with the -CR option
+    * fixed stabs with elf writer, finally the global variables can
+      be watched
+    * removed a lot of routines from cga unit and replaced them by
+      calls to cgobj
+    * u32bit-s32bit updates for and,or,xor nodes. When one element is
+      u32bit then the other is typecasted also to u32bit without giving
+      a rangecheck warning/error.
+    * fixed pascal calling method with reversing also the high tree in
+      the parast, detected by tcalcst3 test
+
+  Revision 1.5  2002/04/21 15:43:32  carl
   * changeregsize -> rg.makeregsize
   * changeregsize moved from cpubase to here
 

+ 19 - 2
compiler/i386/rropt386.pas

@@ -35,7 +35,7 @@ Implementation
 
 Uses
   {$ifdef replaceregdebug}cutils,{$endif}
-  verbose,globals,cpuinfo,cpubase,cpuasm,daopt386,csopt386,cginfo,rgobj;
+  verbose,globals,cpubase,cpuasm,daopt386,csopt386,cginfo,rgobj;
 
 function canBeFirstSwitch(p: Taicpu; reg: tregister): boolean;
 { checks whether an operation on reg can be switched to another reg without an }
@@ -350,7 +350,24 @@ End.
 
 {
   $Log$
-  Revision 1.13  2002-04-21 15:42:17  carl
+  Revision 1.14  2002-05-12 16:53:18  peter
+    * moved entry and exitcode to ncgutil and cgobj
+    * foreach gets extra argument for passing local data to the
+      iterator function
+    * -CR checks also class typecasts at runtime by changing them
+      into as
+    * fixed compiler to cycle with the -CR option
+    * fixed stabs with elf writer, finally the global variables can
+      be watched
+    * removed a lot of routines from cga unit and replaced them by
+      calls to cgobj
+    * u32bit-s32bit updates for and,or,xor nodes. When one element is
+      u32bit then the other is typecasted also to u32bit without giving
+      a rangecheck warning/error.
+    * fixed pascal calling method with reversing also the high tree in
+      the parast, detected by tcalcst3 test
+
+  Revision 1.13  2002/04/21 15:42:17  carl
   * changeregsize -> rg.makeregsize
 
   Revision 1.12  2002/04/20 21:37:08  carl

+ 3 - 0
compiler/msg/errore.msg

@@ -1110,6 +1110,9 @@ type_e_array_index_enums_with_assign_not_possible=04038_E_enums with assignments
 %   Tenum = (a,b,e:=5);
 % \end{verbatim}
 % you cannot use it as index of an array.
+type_e_classes_not_related=04039_E_Class types "$1" and "$2" are not related
+type_w_classes_not_related=04040_W_Class types "$1" and "$2" are not related
+type_e_class_or_interface_type_expected=04041_E_class or interface type expected, but got "$1"
 % \end{description}
 #
 # Symtable

+ 5 - 2
compiler/msgidx.inc

@@ -300,6 +300,9 @@ const
   type_w_mixed_signed_unsigned2=04036;
   type_e_typecast_wrong_size_for_assignment=04037;
   type_e_array_index_enums_with_assign_not_possible=04038;
+  type_e_classes_not_related=04039;
+  type_w_classes_not_related=04040;
+  type_e_class_or_interface_type_expected=04041;
   sym_e_id_not_found=05000;
   sym_f_internal_error_in_symtablestack=05001;
   sym_e_duplicate_id=05002;
@@ -604,9 +607,9 @@ const
   option_info=11024;
   option_help_pages=11025;
 
-  MsgTxtSize = 33931;
+  MsgTxtSize = 34086;
 
   MsgIdxMax : array[1..20] of longint=(
-    17,62,184,39,41,41,98,17,35,42,
+    17,62,184,42,41,41,98,17,35,42,
     30,1,1,1,1,1,1,1,1,1
   );

+ 178 - 176
compiler/msgtxt.inc

@@ -1,7 +1,7 @@
 {$ifdef Delphi}
-const msgtxt : array[0..000141] of string[240]=(
+const msgtxt : array[0..000142] of string[240]=(
 {$else Delphi}
-const msgtxt : array[0..000141,1..240] of char=(
+const msgtxt : array[0..000142,1..240] of char=(
 {$endif Delphi}
   '01000_T_Compiler: $1'#000+
   '01001_D_Compiler OS: $1'#000+
@@ -340,497 +340,499 @@ const msgtxt : array[0..000141,1..240] of char=(
   ' check error'#000+
   '04037_E_Typecast has different size ($1 -> $2) in assignment'#000+
   '04038_E_enums with assignments can'#039't be used as array index'#000+
-  '05000_E_Identifier no','t found "$1"'#000+
+  '04039_E_Class types "','$1" and "$2" are not related'#000+
+  '04040_W_Class types "$1" and "$2" are not related'#000+
+  '04041_E_class or interface type expected, but got "$1"'#000+
+  '05000_E_Identifier not found "$1"'#000+
   '05001_F_Internal Error in SymTableStack()'#000+
-  '05002_E_Duplicate identifier "$1"'#000+
+  '05002_E_Duplicate identifier "','$1"'#000+
   '05003_H_Identifier already defined in $1 at line $2'#000+
   '05004_E_Unknown identifier "$1"'#000+
   '05005_E_Forward declaration not solved "$1"'#000+
-  '05006_F_Identifier type',' already defined as type'#000+
+  '05006_F_Identifier type already defined as type'#000+
   '05007_E_Error in type definition'#000+
-  '05008_E_Type identifier not defined'#000+
+  '05008_E_Type identifier not',' defined'#000+
   '05009_E_Forward type not resolved "$1"'#000+
   '05010_E_Only static variables can be used in static methods or outside'+
   ' methods'#000+
-  '05011_E_Invalid call to tvar','sym.mangledname()'#000+
+  '05011_E_Invalid call to tvarsym.mangledname()'#000+
   '05012_F_record or class type expected'#000+
-  '05013_E_Instances of classes or objects with an abstract method are no'+
-  't allowed'#000+
+  '05013_E_Instances of classes ','or objects with an abstract method are '+
+  'not allowed'#000+
   '05014_W_Label not defined "$1"'#000+
   '05015_E_Label used but not defined "$1"'#000+
-  '05016_E_Illegal label declaration',#000+
+  '05016_E_Illegal label declaration'#000+
   '05017_E_GOTO and LABEL are not supported (use switch -Sg)'#000+
   '05018_E_Label not found'#000+
-  '05019_E_identifier isn'#039't a label'#000+
+  '05','019_E_identifier isn'#039't a label'#000+
   '05020_E_label already defined'#000+
   '05021_E_illegal type declaration of set elements'#000+
-  '05022_E_Forward class definition not resolved',' "$1"'#000+
+  '05022_E_Forward class definition not resolved "$1"'#000+
   '05023_H_Unit "$1" not used in $2'#000+
   '05024_H_Parameter "$1" not used'#000+
-  '05025_N_Local variable "$1" not used'#000+
+  '05025_N_Local ','variable "$1" not used'#000+
   '05026_H_Value parameter "$1" is assigned but never used'#000+
   '05027_N_Local variable "$1" is assigned but never used'#000+
-  '05028_H_Local $1 "$2"',' is not used'#000+
+  '05028_H_Local $1 "$2" is not used'#000+
   '05029_N_Private field "$1.$2" is never used'#000+
-  '05030_N_Private field "$1.$2" is assigned but never used'#000+
+  '05030_N_Private field "$1.$2','" is assigned but never used'#000+
   '05031_N_Private method "$1.$2" never used'#000+
   '05032_E_Set type expected'#000+
   '05033_W_Function result does not seem to be set'#000+
-  '05034_W_Ty','pe "$1" is not aligned correctly in current record for C'#000+
-  '05035_E_Unknown record field identifier "$1"'#000+
+  '05034_W_Type "$1" is not aligned correctly in current record for C'#000+
+  '05035_E_Unknown record field',' identifier "$1"'#000+
   '05036_W_Local variable "$1" does not seem to be initialized'#000+
   '05037_W_Variable "$1" does not seem to be initialized'#000+
-  '05038_E_identifier ident','s no member "$1"'#000+
+  '05038_E_identifier idents no member "$1"'#000+
   '05039_B_Found declaration: $1'#000+
-  '05040_E_Data segment too large (max. 2GB)'#000+
+  '05040_E_Data segment too large (max. 2','GB)'#000+
   '06000_E_BREAK not allowed'#000+
   '06001_E_CONTINUE not allowed'#000+
   '06002_E_Expression too complicated - FPU stack overflow'#000+
   '06003_E_Illegal expression'#000+
-  '06004_E_Inval','id integer expression'#000+
+  '06004_E_Invalid integer expression'#000+
   '06005_E_Illegal qualifier'#000+
-  '06006_E_High range limit < low range limit'#000+
+  '06006_E_High range limit < low range ','limit'#000+
   '06007_E_Illegal counter variable'#000+
   '06008_E_Can'#039't determine which overloaded function to call'#000+
   '06009_E_Parameter list size exceeds 65535 bytes'#000+
-  '06010_E_Il','legal type conversion'#000+
-  '06011_D_Conversion between ordinals and pointers is not portable acros'+
-  's platforms'#000+
+  '06010_E_Illegal type conversion'#000+
+  '06011_D_Conversion between ordinals and pointers is not portabl','e acr'+
+  'oss platforms'#000+
   '06012_E_File types must be var parameters'#000+
   '06013_E_The use of a far pointer isn'#039't allowed there'#000+
-  '06014_E_illegal call by reference paramet','ers'#000+
+  '06014_E_illegal call by reference parameters'#000+
   '06015_E_EXPORT declared functions can'#039't be called'#000+
-  '06016_W_Possible illegal call of constructor or destructor (doesn'#039't'+
-  ' match to this context)'#000+
+  '06016_W_Possible illegal call o','f constructor or destructor (doesn'#039+
+  't match to this context)'#000+
   '06017_N_Inefficient code'#000+
   '06018_W_unreachable code'#000+
-  '06019_E_procedure call with stackframe ESP/SP',#000+
+  '06019_E_procedure call with stackframe ESP/SP'#000+
   '06020_E_Abstract methods can'#039't be called directly'#000+
-  '06021_F_Internal Error in getfloatreg(), allocation failure'#000+
+  '06021_F_Internal Error in getfloat','reg(), allocation failure'#000+
   '06022_F_Unknown float type'#000+
   '06023_F_SecondVecn() base defined twice'#000+
   '06024_F_Extended cg68k not supported'#000+
-  '06025_F_32-bit unsigned n','ot supported in MC68000 mode'#000+
+  '06025_F_32-bit unsigned not supported in MC68000 mode'#000+
   '06026_F_Internal Error in secondinline()'#000+
-  '06027_D_Register $1 weight $2 $3'#000+
+  '06027_D_Registe','r $1 weight $2 $3'#000+
   '06028_E_Stack limit excedeed in local routine'#000+
   '06029_D_Stack frame is omitted'#000+
   '06031_E_Object or class methods can'#039't be inline.'#000+
-  '06032_E_Pro','cvar calls can'#039't be inline.'#000+
+  '06032_E_Procvar calls can'#039't be inline.'#000+
   '06033_E_No code for inline procedure stored'#000+
-  '06034_E_Direct call of interrupt procedure "$1" is not possible'#000+
+  '06034_E_Direc','t call of interrupt procedure "$1" is not possible'#000+
   '06035_E_Element zero of an ansi/wide- or longstring can'#039't be acces'+
   'sed, use (set)length instead'#000+
-  '06036_E_I','nclude and exclude not implemented in this case'#000+
-  '06037_E_Constructors or destructors can not be called inside a '#039'wi'+
-  'th'#039' clause'#000+
+  '06036_E_Include and exclude not implemented in this case'#000+
+  '06037_E_Constructors or destructors c','an not be called inside a '#039'w'+
+  'ith'#039' clause'#000+
   '06038_E_Cannot call message handler method directly'#000+
   '06039_E_Jump in or outside of an exception block'#000+
-  '06040_E_Contro','l flow statements aren'#039't allowed in a finally bloc'+
-  'k'#000+
-  '07000_D_Starting $1 styled assembler parsing'#000+
+  '06040_E_Control flow statements aren'#039't allowed in a finally block'#000+
+  '07000_D_Starting $1 styled assemb','ler parsing'#000+
   '07001_D_Finished $1 styled assembler parsing'#000+
   '07002_E_Non-label pattern contains @'#000+
   '07003_W_Override operator not supported'#000+
-  '07004_E_Error buildin','g record offset'#000+
+  '07004_E_Error building record offset'#000+
   '07005_E_OFFSET used without identifier'#000+
-  '07006_E_TYPE used without identifier'#000+
+  '07006_E_TYPE used without iden','tifier'#000+
   '07007_E_Cannot use local variable or parameters here'#000+
   '07008_E_need to use OFFSET here'#000+
   '07009_E_need to use $ here'#000+
-  '07010_E_Cannot use multiple relocata','ble symbols'#000+
+  '07010_E_Cannot use multiple relocatable symbols'#000+
   '07011_E_Relocatable symbol can only be added'#000+
-  '07012_E_Invalid constant expression'#000+
+  '07012_E_Invalid constant exp','ression'#000+
   '07013_E_Relocatable symbol is not allowed'#000+
   '07014_E_Invalid reference syntax'#000+
   '07015_E_You can not reach $1 from that code'#000+
-  '07016_E_Local symbols/labels',' aren'#039't allowed as references'#000+
+  '07016_E_Local symbols/labels aren'#039't allowed as references'#000+
   '07017_E_Invalid base and index register usage'#000+
-  '07018_W_Possible error in object field handling'#000+
+  '07018_W_P','ossible error in object field handling'#000+
   '07019_E_Wrong scale factor specified'#000+
   '07020_E_Multiple index register usage'#000+
   '07021_E_Invalid operand type'#000+
-  '07022_E_Inva','lid string as opcode operand: $1'#000+
+  '07022_E_Invalid string as opcode operand: $1'#000+
   '07023_W_@CODE and @DATA not supported'#000+
-  '07024_E_Null label references are not allowed'#000+
+  '07024_E_Null l','abel references are not allowed'#000+
   '07025_E_Divide by zero in asm evaluator'#000+
   '07026_E_Illegal expression'#000+
   '07027_E_escape sequence ignored: $1'#000+
-  '07028_E_Invalid symb','ol reference'#000+
+  '07028_E_Invalid symbol reference'#000+
   '07029_W_Fwait can cause emulation problems with emu387'#000+
-  '07030_W_$1 without operand translated into $1P'#000+
+  '07030_W_$1 withou','t operand translated into $1P'#000+
   '07031_W_ENTER instruction is not supported by Linux kernel'#000+
   '07032_W_Calling an overload function in assembler'#000+
-  '07033_E_Unsuppor','ted symbol type for operand'#000+
+  '07033_E_Unsupported symbol type for operand'#000+
   '07034_E_Constant value out of bounds'#000+
-  '07035_E_Error converting decimal $1'#000+
+  '07035_E_Error conver','ting decimal $1'#000+
   '07036_E_Error converting octal $1'#000+
   '07037_E_Error converting binary $1'#000+
   '07038_E_Error converting hexadecimal $1'#000+
   '07039_H_$1 translated to $2'#000+
-  '07','040_W_$1 is associated to an overloaded function'#000+
-  '07041_E_Cannot use SELF outside a method'#000+
+  '07040_W_$1 is associated to an overloaded function'#000+
+  '07041_E_Cannot use SELF outside a me','thod'#000+
   '07042_E_Cannot use OLDEBP outside a nested procedure'#000+
   '07043_W_Procedures can'#039't return any value in asm code'#000+
   '07044_E_SEG not supported'#000+
-  '07045_E_Size suff','ix and destination or source size do not match'#000+
-  '07046_W_Size suffix and destination or source size do not match'#000+
+  '07045_E_Size suffix and destination or source size do not match'#000+
+  '07046_W_Size suffix and destination or',' source size do not match'#000+
   '07047_E_Assembler syntax error'#000+
   '07048_E_Invalid combination of opcode and operands'#000+
   '07049_E_Assembler syntax error in operand'#000+
-  '07050','_E_Assembler syntax error in constant'#000+
+  '07050_E_Assembler syntax error in constant'#000+
   '07051_E_Invalid String expression'#000+
-  '07052_W_constant with symbol $1 for not 32bit address'#000+
+  '07052_W_const','ant with symbol $1 for not 32bit address'#000+
   '07053_E_Unrecognized opcode $1'#000+
   '07054_E_Invalid or missing opcode'#000+
-  '07055_E_Invalid combination of prefix and opcode:',' $1'#000+
+  '07055_E_Invalid combination of prefix and opcode: $1'#000+
   '07056_E_Invalid combination of override and opcode: $1'#000+
-  '07057_E_Too many operands on line'#000+
+  '07057_E_Too many operands ','on line'#000+
   '07058_W_NEAR ignored'#000+
   '07059_W_FAR ignored'#000+
   '07060_E_Duplicate local symbol $1'#000+
   '07061_E_Undefined local symbol $1'#000+
   '07062_E_Unknown label identifier $1'#000+
-  '07','063_E_Invalid register name'#000+
+  '07063_E_Invalid register name'#000+
   '07064_E_Invalid floating point register name'#000+
-  '07065_E_NOR not supported'#000+
+  '07065_E_NOR ','not supported'#000+
   '07066_W_Modulo not supported'#000+
   '07067_E_Invalid floating point constant $1'#000+
   '07068_E_Invalid floating point expression'#000+
   '07069_E_Wrong symbol type'#000+
-  '0','7070_E_Cannot index a local var or parameter with a register'#000+
-  '07071_E_Invalid segment override expression'#000+
+  '07070_E_Cannot index a local var or parameter with a register'#000+
+  '07071_E_Invalid segment ','override expression'#000+
   '07072_W_Identifier $1 supposed external'#000+
   '07073_E_Strings not allowed as constants'#000+
   '07074_No type of variable specified'#000+
-  '07075_E_assembler ','code not returned to text section'#000+
+  '07075_E_assembler code not returned to text section'#000+
   '07076_E_Not a directive or local symbol $1'#000+
-  '07077_E_Using a defined name as a local label'#000+
+  '07077_E_','Using a defined name as a local label'#000+
   '07078_E_Dollar token is used without an identifier'#000+
   '07079_W_32bit constant created for address'#000+
-  '07080_N_.align is targe','t specific, use .balign or .p2align'#000+
-  '07081_E_Can'#039't access fields directly for parameters'#000+
+  '07080_N_.align is target specific, use .balign or .p2align'#000+
+  '07081_E_Can'#039't access fields directly for paramete','rs'#000+
   '07082_E_Can'#039't access fields of objects/classes directly'#000+
   '07083_E_No size specified and unable to determine the size of the oper'+
   'ands'#000+
-  '07084_E_Cannot use RE','SULT in this function'#000+
+  '07084_E_Cannot use RESULT in this function'#000+
   '07085_H_RESULT is register $1'#000+
-  '07086_W_"$1" without operand translated into "$1 %st,%st(1)"'#000+
+  '07086_W_"$1" without operand tran','slated into "$1 %st,%st(1)"'#000+
   '07087_W_"$1 %st(n)" translated into "$1 %st,%st(n)"'#000+
   '07088_W_"$1 %st(n)" translated into "$1 %st(n),%st"'#000+
-  '07089_E_Char < not allo','wed here'#000+
+  '07089_E_Char < not allowed here'#000+
   '07090_E_Char > not allowed here'#000+
   '07091_W_XDEF not supported'#000+
-  '07092_E_Invalid XDEF syntax'#000+
+  '07092_E_Invalid X','DEF syntax'#000+
   '07093_W_ALIGN not supported'#000+
   '07094_E_Inc and Dec cannot be together'#000+
   '07095_E_Invalid reglist for movem'#000+
   '07096_E_Reglist invalid for opcode'#000+
-  '07097_E_','68020 mode required'#000+
+  '07097_E_68020 mode required'#000+
   '08000_F_Too many assembler files'#000+
-  '08001_F_Selected assembler output not supported'#000+
+  '08001_F_Selected assembler outpu','t not supported'#000+
   '08002_F_Comp not supported'#000+
   '08003_F_Direct not support for binary writers'#000+
   '08004_E_Allocating of data is only allowed in bss section'#000+
-  '08005_F_','No binary writer selected'#000+
+  '08005_F_No binary writer selected'#000+
   '08006_E_Asm: Opcode $1 not in table'#000+
-  '08007_E_Asm: $1 invalid combination of opcode and operands'#000+
+  '08007_E_Asm: $1 invalid',' combination of opcode and operands'#000+
   '08008_E_Asm: 16 Bit references not supported'#000+
   '08009_E_Asm: Invalid effective address'#000+
-  '08010_E_Asm: Immediate or reference',' expected'#000+
+  '08010_E_Asm: Immediate or reference expected'#000+
   '08011_E_Asm: $1 value exceeds bounds $2'#000+
-  '08012_E_Asm: Short jump is out of range $1'#000+
+  '08012_E_Asm: Short jump is out of r','ange $1'#000+
   '08013_E_Asm: Undefined label $1'#000+
   '08014_E_Asm: Comp type not supported for this target'#000+
   '08015_E_Asm: Extended type not supported for this target'#000+
-  '08016','_E_Asm: Duplicate label $1'#000+
+  '08016_E_Asm: Duplicate label $1'#000+
   '09000_W_Source operating system redefined'#000+
-  '09001_I_Assembling (pipe) $1'#000+
+  '09001_I_Assembli','ng (pipe) $1'#000+
   '09002_E_Can'#039't create assember file: $1'#000+
   '09003_E_Can'#039't create object file: $1'#000+
   '09004_E_Can'#039't create archive file: $1'#000+
-  '09005_E_Assembler $1 not fou','nd, switching to external assembling'#000+
+  '09005_E_Assembler $1 not found, switching to external assembling'#000+
   '09006_T_Using assembler: $1'#000+
-  '09007_E_Error while assembling exitcode $1'#000+
+  '09007_E_Error while ','assembling exitcode $1'#000+
   '09008_E_Can'#039't call the assembler, error $1 switching to external a'+
   'ssembling'#000+
   '09009_I_Assembling $1'#000+
   '09010_I_Assembling smartlink $1'#000+
-  '09','011_W_Object $1 not found, Linking may fail !'#000+
-  '09012_W_Library $1 not found, Linking may fail !'#000+
+  '09011_W_Object $1 not found, Linking may fail !'#000+
+  '09012_W_Library $1 not found, Linking m','ay fail !'#000+
   '09013_E_Error while linking'#000+
   '09014_E_Can'#039't call the linker, switching to external linking'#000+
   '09015_I_Linking $1'#000+
-  '09016_E_Util $1 not found, switching ','to external linking'#000+
+  '09016_E_Util $1 not found, switching to external linking'#000+
   '09017_T_Using util $1'#000+
-  '09018_E_Creation of Executables not supported'#000+
+  '09018_E_Creation of Executables not support','ed'#000+
   '09019_E_Creation of Dynamic/Shared Libraries not supported'#000+
   '09020_I_Closing script $1'#000+
   '09021_E_resource compiler not found, switching to external mode'#000+
-  '090','22_I_Compiling resource $1'#000+
-  '09023_T_unit $1 can'#039't be static linked, switching to smart linking'+
-  #000+
+  '09022_I_Compiling resource $1'#000+
+  '09023_T_unit $1 can'#039't be static linked, switching to smart',' linki'+
+  'ng'#000+
   '09024_T_unit $1 can'#039't be smart linked, switching to static linking'+
   #000+
   '09025_T_unit $1 can'#039't be shared linked, switching to static linkin'+
   'g'#000+
-  '09026_E_uni','t $1 can'#039't be smart or static linked'#000+
-  '09027_E_unit $1 can'#039't be shared or static linked'#000+
+  '09026_E_unit $1 can'#039't be smart or static linked'#000+
+  '09027_E_unit $1 can'#039't be shared or static linked',#000+
   '09028_F_Can'#039't post process executable $1'#000+
   '09029_F_Can'#039't open executable $1'#000+
   '09030_X_Size of Code: $1 bytes'#000+
   '09031_X_Size of initialized data: $1 bytes'#000+
-  '09032_','X_Size of uninitialized data: $1 bytes'#000+
+  '09032_X_Size of uninitialized data: $1 bytes'#000+
   '09033_X_Stack space reserved: $1 bytes'#000+
-  '09034_X_Stack space commited: $1 bytes'#000+
+  '09034_X','_Stack space commited: $1 bytes'#000+
   '10000_T_Unitsearch: $1'#000+
   '10001_T_PPU Loading $1'#000+
   '10002_U_PPU Name: $1'#000+
   '10003_U_PPU Flags: $1'#000+
   '10004_U_PPU Crc: $1'#000+
-  '10005_U_PPU Ti','me: $1'#000+
+  '10005_U_PPU Time: $1'#000+
   '10006_U_PPU File too short'#000+
   '10007_U_PPU Invalid Header (no PPU at the begin)'#000+
-  '10008_U_PPU Invalid Version $1'#000+
+  '10','008_U_PPU Invalid Version $1'#000+
   '10009_U_PPU is compiled for an other processor'#000+
   '10010_U_PPU is compiled for an other target'#000+
   '10011_U_PPU Source: $1'#000+
-  '10012_U_Writ','ing $1'#000+
+  '10012_U_Writing $1'#000+
   '10013_F_Can'#039't Write PPU-File'#000+
   '10014_F_Error reading PPU-File'#000+
-  '10015_F_unexpected end of PPU-File'#000+
+  '10015_F_unexpected',' end of PPU-File'#000+
   '10016_F_Invalid PPU-File entry: $1'#000+
   '10017_F_PPU Dbx count problem'#000+
   '10018_E_Illegal unit name: $1'#000+
   '10019_F_Too much units'#000+
-  '10020_F_Circular uni','t reference between $1 and $2'#000+
+  '10020_F_Circular unit reference between $1 and $2'#000+
   '10021_F_Can'#039't compile unit $1, no sources available'#000+
-  '10022_F_Can'#039't find unit $1'#000+
+  '100','22_F_Can'#039't find unit $1'#000+
   '10023_W_Unit $1 was not found but $2 exists'#000+
   '10024_F_Unit $1 searched but $2 found'#000+
-  '10025_W_Compiling the system unit requires the -U','s switch'#000+
+  '10025_W_Compiling the system unit requires the -Us switch'#000+
   '10026_F_There were $1 errors compiling module, stopping'#000+
-  '10027_U_Load from $1 ($2) unit $3'#000+
+  '10027_U_Load from $1',' ($2) unit $3'#000+
   '10028_U_Recompiling $1, checksum changed for $2'#000+
   '10029_U_Recompiling $1, source found only'#000+
-  '10030_U_Recompiling unit, static lib is older than ','ppufile'#000+
+  '10030_U_Recompiling unit, static lib is older than ppufile'#000+
   '10031_U_Recompiling unit, shared lib is older than ppufile'#000+
-  '10032_U_Recompiling unit, obj and asm are older than ppufile'#000+
+  '10032_U_Recompilin','g unit, obj and asm are older than ppufile'#000+
   '10033_U_Recompiling unit, obj is older than asm'#000+
   '10034_U_Parsing interface of $1'#000+
-  '10035_U_Parsing implementation o','f $1'#000+
+  '10035_U_Parsing implementation of $1'#000+
   '10036_U_Second load for unit $1'#000+
   '10037_U_PPU Check file $1 time $2'#000+
-  '10038_H_Conditional $1 was not set at startup in last compilation of $'+
-  '2'#000+
+  '10038_H_Condit','ional $1 was not set at startup in last compilation of'+
+  ' $2'#000+
   '10039_H_Conditional $1 was set at startup in last compilation of $2'#000+
-  '10040_W_Can'#039't recompile unit ','$1, but found modifed include files'+
-  #000+
-  '10041_H_File $1 is newer than Release PPU file $2'#000+
+  '10040_W_Can'#039't recompile unit $1, but found modifed include files'#000+
+  '10041_H_File $1 is newer than Release PPU file $2',#000+
   '11000_$1 [options] <inputfile> [options]'#000+
   '11001_W_Only one source file supported'#000+
   '11002_W_DEF file can be created only for OS/2'#000+
-  '11003_E_nested response file','s are not supported'#000+
+  '11003_E_nested response files are not supported'#000+
   '11004_F_No source file name in command line'#000+
-  '11005_N_No option inside $1 config file'#000+
+  '11005_N_No option ins','ide $1 config file'#000+
   '11006_E_Illegal parameter: $1'#000+
   '11007_H_-? writes help pages'#000+
   '11008_F_Too many config files nested'#000+
   '11009_F_Unable to open file $1'#000+
-  '11010_D_R','eading further options from $1'#000+
+  '11010_D_Reading further options from $1'#000+
   '11011_W_Target is already set to: $1'#000+
-  '11012_W_Shared libs not supported on DOS platform, reverting to static'+
-  #000+
+  '11012_W_Shared li','bs not supported on DOS platform, reverting to stat'+
+  'ic'#000+
   '11013_F_too many IF(N)DEFs'#000+
   '11014_F_too many ENDIFs'#000+
   '11015_F_open conditional at the end of the file'#000+
-  '11','016_W_Debug information generation is not supported by this execut'+
-  'able'#000+
-  '11017_H_Try recompiling with -dGDB'#000+
+  '11016_W_Debug information generation is not supported by this executab'+
+  'le'#000+
+  '11017_H_Try re','compiling with -dGDB'#000+
   '11018_E_You are using the obsolete switch $1'#000+
   '11019_E_You are using the obsolete switch $1, please use $2'#000+
-  '11020_N_Switching assembler t','o default source writing assembler'#000+
-  '11021_W_Assembler output selected "$1" is not compatible with "$2"'#000+
+  '11020_N_Switching assembler to default source writing assembler'#000+
+  '11021_W_Assembler output selected "$1" is not comp','atible with "$2"'#000+
   '11022_W_"$1" assembler use forced'#000+
   '11026_T_Reading options from file $1'#000+
   '11027_T_Reading options from environment $1'#000+
-  '11028_D_Handling option',' "$1"'#000+
+  '11028_D_Handling option "$1"'#000+
   '11029__*** press enter ***'#000+
-  '11023_Free Pascal Compiler version $FPCVER [$FPCDATE] for $FPCTARGET'#010+
+  '11023_Free Pascal Compiler version $FPCVER [$FPCDATE','] for $FPCTARGET'+
+  #010+
   'Copyright (c) 1993-2002 by Florian Klaempfl'#000+
   '11024_Free Pascal Compiler version $FPCVER'#010+
   #010+
   'Compiler Date  : $FPCDATE'#010+
-  'Compiler Target: $FPCTAR','GET'#010+
+  'Compiler Target: $FPCTARGET'#010+
   #010+
   'Supported targets:'#010+
   '  $OSTARGETS'#010+
   #010+
-  'This program comes under the GNU General Public Licence'#010+
+  'This program comes under the GNU General Public',' Licence'#010+
   'For more information read COPYING.FPC'#010+
   #010+
   'Report bugs,suggestions etc to:'#010+
   '                 [email protected]'#000+
-  '11025_**0*_put + after a boolean swi','tch option to enable it, - to di'+
-  'sable it'#010+
-  '**1a_the compiler doesn'#039't delete the generated assembler file'#010+
+  '11025_**0*_put + after a boolean switch option to enable it, - to disa'+
+  'ble it'#010+
+  '**1a_the compiler doesn'#039't delete the generat','ed assembler file'#010+
   '**2al_list sourcecode lines in assembler file'#010+
   '**2ar_list register allocation/release info in assembler file'#010+
-  '**2at_list temp allocation/re','lease info in assembler file'#010+
+  '**2at_list temp allocation/release info in assembler file'#010+
   '**1b_generate browser info'#010+
-  '**2bl_generate local symbol info'#010+
+  '**2bl_generate local symbol i','nfo'#010+
   '**1B_build all modules'#010+
   '**1C<x>_code generation options:'#010+
   '**2CD_create also dynamic library (not supported)'#010+
-  '**2Ch<n>_<n> bytes heap (between 1023 and 671','07840)'#010+
+  '**2Ch<n>_<n> bytes heap (between 1023 and 67107840)'#010+
   '**2Ci_IO-checking'#010+
   '**2Cn_omit linking stage'#010+
-  '**2Co_check overflow of integer operations'#010+
+  '**2Co_check overflow of integer ope','rations'#010+
   '**2Cr_range checking'#010+
   '**2CR_verify object method call validity'#010+
   '**2Cs<n>_set stack size to <n>'#010+
   '**2Ct_stack checking'#010+
-  '**2CX_create also smartlinked lib','rary'#010+
+  '**2CX_create also smartlinked library'#010+
   '**1d<x>_defines the symbol <x>'#010+
   '*O1D_generate a DEF file'#010+
-  '*O2Dd<x>_set description to <x>'#010+
+  '*O2Dd<x>_set description',' to <x>'#010+
   '*O2Dw_PM application'#010+
   '**1e<x>_set path to executable'#010+
   '**1E_same as -Cn'#010+
   '**1F<x>_set file names and paths:'#010+
-  '**2FD<x>_sets the directory where to search ','for compiler utilities'#010+
+  '**2FD<x>_sets the directory where to search for compiler utilities'#010+
   '**2Fe<x>_redirect error output to <x>'#010+
-  '**2FE<x>_set exe/unit output path to <x>'#010+
+  '**2FE<x>_set exe/unit ou','tput path to <x>'#010+
   '**2Fi<x>_adds <x> to include path'#010+
   '**2Fl<x>_adds <x> to library path'#010+
   '*L2FL<x>_uses <x> as dynamic linker'#010+
   '**2Fo<x>_adds <x> to object path'#010+
-  '*','*2Fr<x>_load error message file <x>'#010+
+  '**2Fr<x>_load error message file <x>'#010+
   '**2Fu<x>_adds <x> to unit path'#010+
-  '**2FU<x>_set unit output path to <x>, overrides -FE'#010+
+  '**2FU<x>_set unit ','output path to <x>, overrides -FE'#010+
   '*g1g_generate debugger information:'#010+
   '*g2gg_use gsym'#010+
   '*g2gd_use dbx'#010+
   '*g2gh_use heap trace unit (for memory leak debugging)'#010+
-  '*g','2gl_use line info unit to show more info for backtraces'#010+
-  '*g2gc_generate checks for pointers'#010+
+  '*g2gl_use line info unit to show more info for backtraces'#010+
+  '*g2gc_generate checks for poi','nters'#010+
   '**1i_information'#010+
   '**2iD_return compiler date'#010+
   '**2iV_return compiler version'#010+
   '**2iSO_return compiler OS'#010+
   '**2iSP_return compiler processor'#010+
-  '**2iTO_return ta','rget OS'#010+
+  '**2iTO_return target OS'#010+
   '**2iTP_return target processor'#010+
   '**1I<x>_adds <x> to include path'#010+
-  '**1k<x>_Pass <x> to the linker'#010+
+  '**1k<x>_Pass ','<x> to the linker'#010+
   '**1l_write logo'#010+
   '**1n_don'#039't read the default config file'#010+
   '**1o<x>_change the name of the executable produced to <x>'#010+
-  '**1pg_generate profile ','code for gprof (defines FPC_PROFILE)'#010+
-  '*L1P_use pipes instead of creating temporary assembler files'#010+
+  '**1pg_generate profile code for gprof (defines FPC_PROFILE)'#010+
+  '*L1P_use pipes instead of creating temporary ass','embler files'#010+
   '**1S<x>_syntax options:'#010+
   '**2S2_switch some Delphi 2 extensions on'#010+
   '**2Sc_supports operators like C (*=,+=,/= and -=)'#010+
-  '**2Sa_include assertion cod','e.'#010+
+  '**2Sa_include assertion code.'#010+
   '**2Sd_tries to be Delphi compatible'#010+
-  '**2Se<x>_compiler stops after the <x> errors (default is 1)'#010+
+  '**2Se<x>_compiler stops after the <x> errors (','default is 1)'#010+
   '**2Sg_allow LABEL and GOTO'#010+
   '**2Sh_Use ansistrings'#010+
   '**2Si_support C++ styled INLINE'#010+
   '**2Sm_support macros like C (global)'#010+
-  '**2So_tries to be TP/BP',' 7.0 compatible'#010+
+  '**2So_tries to be TP/BP 7.0 compatible'#010+
   '**2Sp_tries to be gpc compatible'#010+
-  '**2Ss_constructor name must be init (destructor must be done)'#010+
+  '**2Ss_constructor name must be init ','(destructor must be done)'#010+
   '**2St_allow static keyword in objects'#010+
   '**1s_don'#039't call assembler and linker (only with -a)'#010+
-  '**2st_Generate script to link on target',#010+
+  '**2st_Generate script to link on target'#010+
   '**2sh_Generate script to link on host'#010+
   '**1u<x>_undefines the symbol <x>'#010+
-  '**1U_unit options:'#010+
+  '**1U_unit opt','ions:'#010+
   '**2Un_don'#039't check the unit name'#010+
   '**2Ur_generate release unit files'#010+
   '**2Us_compile a system unit'#010+
-  '**1v<x>_Be verbose. <x> is a combination of the followi','ng letters:'#010+
+  '**1v<x>_Be verbose. <x> is a combination of the following letters:'#010+
   '**2*_e : Show errors (default)       d : Show debug info'#010+
-  '**2*_w : Show warnings               u : Show unit info'#010+
+  '**2*_w : Show wa','rnings               u : Show unit info'#010+
   '**2*_n : Show notes                  t : Show tried/used files'#010+
-  '**2*_h : Show hints                  m : Show define','d macros'#010+
+  '**2*_h : Show hints                  m : Show defined macros'#010+
   '**2*_i : Show general info           p : Show compiled procedures'#010+
-  '**2*_l : Show linenumbers            c : Show conditionals'#010+
+  '**2*_l : S','how linenumbers            c : Show conditionals'#010+
   '**2*_a : Show everything             0 : Show nothing (except errors)'#010+
-  '**2*_b : Show all procedure         ',' r : Rhide/GCC compatibility mod'+
-  'e'#010+
-  '**2*_    declarations if an error    x : Executable info (Win32 only)'#010+
+  '**2*_b : Show all procedure          r : Rhide/GCC compatibility mode'#010+
+  '**2*_    declarations if an error    x : Executable',' info (Win32 only'+
+  ')'#010+
   '**2*_    occurs'#010+
   '**1X_executable options:'#010+
   '*L2Xc_link with the c library'#010+
   '**2Xs_strip all symbols from executable'#010+
-  '**2XD_try to link dynamic','          (defines FPC_LINK_DYNAMIC)'#010+
-  '**2XS_try to link static (default) (defines FPC_LINK_STATIC)'#010+
+  '**2XD_try to link dynamic          (defines FPC_LINK_DYNAMIC)'#010+
+  '**2XS_try to link static (default) (defines FPC_','LINK_STATIC)'#010+
   '**2XX_try to link smart            (defines FPC_LINK_SMART)'#010+
   '**0*_Processor specific options:'#010+
   '3*1A<x>_output format:'#010+
-  '3*2Aas_assemble using GNU ','AS'#010+
+  '3*2Aas_assemble using GNU AS'#010+
   '3*2Aasaout_assemble using GNU AS for aout (Go32v1)'#010+
-  '3*2Anasmcoff_coff (Go32v2) file using Nasm'#010+
+  '3*2Anasmcoff_coff (Go32v2) file',' using Nasm'#010+
   '3*2Anasmelf_elf32 (Linux) file using Nasm'#010+
   '3*2Anasmobj_obj file using Nasm'#010+
   '3*2Amasm_obj file using Masm (Microsoft)'#010+
-  '3*2Atasm_obj file using Tasm',' (Borland)'#010+
+  '3*2Atasm_obj file using Tasm (Borland)'#010+
   '3*2Acoff_coff (Go32v2) using internal writer'#010+
-  '3*2Apecoff_pecoff (Win32) using internal writer'#010+
+  '3*2Apecoff_pecoff (Win32) usi','ng internal writer'#010+
   '3*1R<x>_assembler reading style:'#010+
   '3*2Ratt_read AT&T style assembler'#010+
   '3*2Rintel_read Intel style assembler'#010+
-  '3*2Rdirect_copy assembler text d','irectly to assembler file'#010+
+  '3*2Rdirect_copy assembler text directly to assembler file'#010+
   '3*1O<x>_optimizations:'#010+
   '3*2Og_generate smaller code'#010+
-  '3*2OG_generate faster code (default)'#010+
+  '3*2OG_ge','nerate faster code (default)'#010+
   '3*2Or_keep certain variables in registers'#010+
   '3*2Ou_enable uncertain optimizations (see docs)'#010+
-  '3*2O1_level 1 optimizations (quick o','ptimizations)'#010+
+  '3*2O1_level 1 optimizations (quick optimizations)'#010+
   '3*2O2_level 2 optimizations (-O1 + slower optimizations)'#010+
-  '3*2O3_level 3 optimizations (-O2 repeatedly, max 5 times)'#010+
+  '3*2O3_level 3 ','optimizations (-O2 repeatedly, max 5 times)'#010+
   '3*2Op<x>_target processor:'#010+
   '3*3Op1_set target processor to 386/486'#010+
-  '3*3Op2_set target processor to Pentium/Pentiu','mMMX (tm)'#010+
+  '3*3Op2_set target processor to Pentium/PentiumMMX (tm)'#010+
   '3*3Op3_set target processor to PPro/PII/c6x86/K6 (tm)'#010+
-  '3*1T<x>_Target operating system:'#010+
+  '3*1T<x>_Target operat','ing system:'#010+
   '3*2TGO32V2_version 2 of DJ Delorie DOS extender'#010+
   '3*2TWDOSX DOS 32 Bit Extender'#010+
   '3*2TLINUX_Linux'#010+
-  '3*2Tnetware_Novell Netware Module (experimental)'#010,
+  '3*2Tnetware_Novell Netware Module (experimental)'#010+
   '3*2TOS2_OS/2 2.x'#010+
   '3*2TSUNOS_SunOS/Solaris'#010+
   '3*2TWin32_Windows 32 Bit'#010+
-  '3*1W<x>_Win32 target options'#010+
+  '3*1W<x>_Win32 targe','t options'#010+
   '3*2WB<x>_Set Image base to Hexadecimal <x> value'#010+
   '3*2WC_Specify console type application'#010+
   '3*2WD_Use DEFFILE to export functions of DLL or EXE'#010+
-  '3*2WF','_Specify full-screen type application (OS/2 only)'#010+
-  '3*2WG_Specify graphic type application'#010+
+  '3*2WF_Specify full-screen type application (OS/2 only)'#010+
+  '3*2WG_Specify graphic type applicat','ion'#010+
   '3*2WN_Do not generate relocation code (necessary for debugging)'#010+
   '3*2WR_Generate relocation code'#010+
   '6*1A<x>_output format'#010+
   '6*2Aas_Unix o-file using GNU AS'#010+
-  '6*','2Agas_GNU Motorola assembler'#010+
+  '6*2Agas_GNU Motorola assembler'#010+
   '6*2Amit_MIT Syntax (old GAS)'#010+
-  '6*2Amot_Standard Motorola assembler'#010+
+  '6*2Amot_Standard Motorola a','ssembler'#010+
   '6*1O_optimizations:'#010+
   '6*2Oa_turn on the optimizer'#010+
   '6*2Og_generate smaller code'#010+
   '6*2OG_generate faster code (default)'#010+
-  '6*2Ox_optimize maximum (still BUG','GY!!!)'#010+
+  '6*2Ox_optimize maximum (still BUGGY!!!)'#010+
   '6*2O2_set target processor to a MC68020+'#010+
   '6*1R<x>_assembler reading style:'#010+
-  '6*2RMOT_read motorola style assembler'#010+
+  '6*2R','MOT_read motorola style assembler'#010+
   '6*1T<x>_Target operating system:'#010+
   '6*2TAMIGA_Commodore Amiga'#010+
   '6*2TATARI_Atari ST/STe/TT'#010+
   '6*2TMACOS_Macintosh m68k'#010+
-  '6*2TLINUX_L','inux-68k'#010+
+  '6*2TLINUX_Linux-68k'#010+
   '6*2TPALMOS_PalmOS'#010+
   '**1*_'#010+
   '**1?_shows this help'#010+
-  '**1h_shows this help without waiting'#000
+  '**1h_shows this help without wa','iting'#000
 );

+ 52 - 19
compiler/nadd.pas

@@ -58,7 +58,6 @@ implementation
       globtype,systems,
       cutils,verbose,globals,widestr,
       symconst,symtype,symdef,symsym,symtable,types,
-      cpuinfo,
       cgbase,
       htypechk,pass_1,
       nmat,ncnv,nld,ncon,nset,nopt,ncal,ninl,
@@ -112,12 +111,12 @@ implementation
            possible for array constructors }
          if is_array_constructor(left.resulttype.def) then
           begin
-            arrayconstructor_to_set(tarrayconstructornode(left));
+            arrayconstructor_to_set(left);
             resulttypepass(left);
           end;
          if is_array_constructor(right.resulttype.def) then
           begin
-            arrayconstructor_to_set(tarrayconstructornode(right));
+            arrayconstructor_to_set(right);
             resulttypepass(right);
           end;
 
@@ -210,9 +209,12 @@ implementation
                 end
               else if (lt=ordconstn) and (rt=ordconstn) then
                 begin
-                  { make left const type the biggest, this type will be used
-                    for orn,andn,xorn }
-                  if rd.size>ld.size then
+                  { make left const type the biggest (u32bit is bigger than
+                    s32bit for or,and,xor) }
+                  if (rd.size>ld.size) or
+                     ((torddef(rd).typ=u32bit) and
+                      (torddef(ld).typ=s32bit) and
+                      (nodetype in [orn,andn,xorn])) then
                     inserttypeconv(left,right.resulttype);
                 end;
 
@@ -671,12 +673,19 @@ implementation
                    end
                  else
                    begin
-                     if is_signed(ld) and
-                        not(is_constintnode(left) and
-                            (tordconstnode(left).value >= 0)) and
-                        (cs_check_range in aktlocalswitches) then
-                       CGMessage(type_w_mixed_signed_unsigned2);
-                     inserttypeconv(left,u32bittype);
+                     { and,or,xor work on bit patterns and don't care
+                       about the sign }
+                     if nodetype in [andn,orn,xorn] then
+                      inserttypeconv_explicit(left,u32bittype)
+                     else
+                      begin
+                        if is_signed(ld) and
+                           not(is_constintnode(left) and
+                               (tordconstnode(left).value >= 0)) and
+                           (cs_check_range in aktlocalswitches) then
+                          CGMessage(type_w_mixed_signed_unsigned2);
+                        inserttypeconv(left,u32bittype);
+                      end;
 
                      if is_signed(rd) and
                         { then ld = u32bit }
@@ -693,12 +702,19 @@ implementation
                        end
                      else
                        begin
-                         if is_signed(rd) and
-                            not(is_constintnode(right) and
-                                (tordconstnode(right).value >= 0)) and
-                            (cs_check_range in aktlocalswitches) then
-                           CGMessage(type_w_mixed_signed_unsigned2);
-                         inserttypeconv(right,u32bittype);
+                         { and,or,xor work on bit patterns and don't care
+                           about the sign }
+                         if nodetype in [andn,orn,xorn] then
+                          inserttypeconv_explicit(left,u32bittype)
+                         else
+                          begin
+                            if is_signed(rd) and
+                               not(is_constintnode(right) and
+                                   (tordconstnode(right).value >= 0)) and
+                               (cs_check_range in aktlocalswitches) then
+                              CGMessage(type_w_mixed_signed_unsigned2);
+                            inserttypeconv(right,u32bittype);
+                          end;
                        end;
                    end;
                end
@@ -1601,7 +1617,24 @@ begin
 end.
 {
   $Log$
-  Revision 1.46  2002-04-23 19:16:34  peter
+  Revision 1.47  2002-05-12 16:53:06  peter
+    * moved entry and exitcode to ncgutil and cgobj
+    * foreach gets extra argument for passing local data to the
+      iterator function
+    * -CR checks also class typecasts at runtime by changing them
+      into as
+    * fixed compiler to cycle with the -CR option
+    * fixed stabs with elf writer, finally the global variables can
+      be watched
+    * removed a lot of routines from cga unit and replaced them by
+      calls to cgobj
+    * u32bit-s32bit updates for and,or,xor nodes. When one element is
+      u32bit then the other is typecasted also to u32bit without giving
+      a rangecheck warning/error.
+    * fixed pascal calling method with reversing also the high tree in
+      the parast, detected by tcalcst3 test
+
+  Revision 1.46  2002/04/23 19:16:34  peter
     * add pinline unit that inserts compiler supported functions using
       one or more statements
     * moved finalize and setlength from ninl to pinline

+ 26 - 4
compiler/ncal.pas

@@ -742,7 +742,7 @@ implementation
       var
          hp,procs,hp2 : pprocdefcoll;
          pd : pprocdeflist;
-         oldcallprocdef : tprocdef;
+         oldcallprocdef : tabstractprocdef;
          def_from,def_to,conv_to : tdef;
          hpt : tnode;
          pt : tcallparanode;
@@ -1543,7 +1543,7 @@ implementation
          { insert type conversions }
          if assigned(left) then
           begin
-            aktcallprocdef:=tprocdef(procdefinition);
+            aktcallprocdef:=procdefinition;
             tcallparanode(left).insert_typeconv(tparaitem(procdefinition.Para.first),true);
           end;
 
@@ -1725,7 +1725,12 @@ implementation
                      { but for R^.Assign, R must be valid !! }
                      if (procdefinition.proctypeoption=potype_constructor) or
                         ((methodpointer.nodetype=loadn) and
-                        (not(oo_has_virtual in tobjectdef(methodpointer.resulttype.def).objectoptions))) then
+                         ((methodpointer.resulttype.def.deftype=classrefdef) or
+                          ((methodpointer.resulttype.def.deftype=objectdef) and
+                           not(oo_has_virtual in tobjectdef(methodpointer.resulttype.def).objectoptions)
+                          )
+                         )
+                        ) then
                        method_must_be_valid:=false
                      else
                        method_must_be_valid:=true;
@@ -1865,7 +1870,24 @@ begin
 end.
 {
   $Log$
-  Revision 1.72  2002-04-25 20:16:38  peter
+  Revision 1.73  2002-05-12 16:53:06  peter
+    * moved entry and exitcode to ncgutil and cgobj
+    * foreach gets extra argument for passing local data to the
+      iterator function
+    * -CR checks also class typecasts at runtime by changing them
+      into as
+    * fixed compiler to cycle with the -CR option
+    * fixed stabs with elf writer, finally the global variables can
+      be watched
+    * removed a lot of routines from cga unit and replaced them by
+      calls to cgobj
+    * u32bit-s32bit updates for and,or,xor nodes. When one element is
+      u32bit then the other is typecasted also to u32bit without giving
+      a rangecheck warning/error.
+    * fixed pascal calling method with reversing also the high tree in
+      the parast, detected by tcalcst3 test
+
+  Revision 1.72  2002/04/25 20:16:38  peter
     * moved more routines from cga/n386util
 
   Revision 1.71  2002/04/20 21:32:23  carl

+ 83 - 139
compiler/ncgbas.pas

@@ -1,6 +1,6 @@
 {
     $Id$
-    Copyright (c) 2000-2002 by Florian Klaempfl
+    Copyright (c) 2000 by Florian Klaempfl
 
     This unit implements some basic nodes
 
@@ -22,7 +22,7 @@
 }
 unit ncgbas;
 
-{$i fpcdefs.inc}
+{$i defines.inc}
 
 interface
 
@@ -63,10 +63,10 @@ interface
     uses
       globtype,systems,
       cutils,verbose,globals,
-      aasmbase,aasmtai,aasmcpu,symsym,
-      cpubase,
+      aasm,symsym,
+      cpubase,cpuasm,
       nflw,pass_2,
-      cgbase,cginfo,cgobj,tgobj,rgobj
+      cgbase,cgobj,tgobj,rgobj
       ;
 
 {*****************************************************************************
@@ -75,8 +75,6 @@ interface
 
     procedure tcgnothingnode.pass_2;
       begin
-         location_reset(location,LOC_VOID,OS_NO);
-
          { avoid an abstract rte }
       end;
 
@@ -87,23 +85,19 @@ interface
 
     procedure tcgstatementnode.pass_2;
       var
-         hp : tstatementnode;
+         hp : tnode;
       begin
-         location_reset(location,LOC_VOID,OS_NO);
-
          hp:=self;
          while assigned(hp) do
           begin
-            if assigned(hp.left) then
+            if assigned(tstatementnode(hp).right) then
              begin
-             {$ifndef newra}
                rg.cleartempgen;
-             {$endif newra}
-               secondpass(hp.left);
+               secondpass(tstatementnode(hp).right);
                { Compiler inserted blocks can return values }
-               location_copy(hp.location,hp.left.location);
+               location_copy(location,tstatementnode(hp).right.location);
              end;
-            hp:=tstatementnode(hp.right);
+            hp:=tstatementnode(hp).left;
           end;
       end;
 
@@ -116,14 +110,21 @@ interface
 
       procedure ReLabel(var p:tasmsymbol);
         begin
-          { Only relabel local tasmlabels }
-          if (p.defbind = AB_LOCAL) and
-             (p is tasmlabel) then
+          if p.proclocal then
            begin
              if not assigned(p.altsymbol) then
-               objectlibrary.GenerateAltSymbol(p);
+              begin
+                { generatealtsymbol will also increase the refs }
+                p.GenerateAltSymbol;
+                UsedAsmSymbolListInsert(p);
+              end
+             else
+              begin
+                { increase the refs, they will be decreased when the
+                  asmnode is destroyed }
+                inc(p.refs);
+              end;
              p:=p.altsymbol;
-             p.increfs;
            end;
         end;
 
@@ -133,11 +134,9 @@ interface
         i : longint;
         skipnode : boolean;
       begin
-         location_reset(location,LOC_VOID,OS_NO);
-
          if inlining_procedure then
            begin
-             objectlibrary.CreateUsedAsmSymbolList;
+             CreateUsedAsmSymbolList;
              localfixup:=aktprocdef.localst.address_fixup;
              parafixup:=aktprocdef.parast.address_fixup;
              hp:=tai(p_asm.first);
@@ -160,11 +159,7 @@ interface
                      begin
                        { remove cached insentry, because the new code can
                          require an other less optimized instruction }
-{$ifdef i386}
-{$ifndef NOAG386BIN}
                        taicpu(hp2).ResetPass1;
-{$endif}
-{$endif}
                        { fixup the references }
                        for i:=1 to taicpu(hp2).ops do
                         begin
@@ -205,8 +200,8 @@ interface
                 hp:=tai(hp.next);
               end;
              { restore used symbols }
-             objectlibrary.UsedAsmSymbolListResetAltSym;
-             objectlibrary.DestroyUsedAsmSymbolList;
+             UsedAsmSymbolListResetAltSym;
+             DestroyUsedAsmSymbolList;
            end
          else
            begin
@@ -217,6 +212,8 @@ interface
              else
                exprasmList.concatlist(p_asm);
            end;
+         if not (nf_object_preserved in flags) then
+           cg.g_maybe_loadself(exprasmlist);
        end;
 
 
@@ -225,29 +222,13 @@ interface
 *****************************************************************************}
 
     procedure tcgblocknode.pass_2;
-      var
-        hp : tstatementnode;
       begin
-        location_reset(location,LOC_VOID,OS_NO);
-
         { do second pass on left node }
         if assigned(left) then
          begin
-           hp:=tstatementnode(left);
-           while assigned(hp) do
-            begin
-              if assigned(hp.left) then
-               begin
-               {$ifndef newra}
-                 if nf_releasetemps in flags then
-                   rg.cleartempgen;
-               {$endif newra}
-                 secondpass(hp.left);
-                 location_copy(hp.location,hp.left.location);
-               end;
-              location_copy(location,hp.location);
-              hp:=tstatementnode(hp.right);
-            end;
+           secondpass(left);
+           { Compiler inserted blocks can return values }
+           location_copy(location,left.location);
          end;
       end;
 
@@ -256,21 +237,16 @@ interface
 *****************************************************************************}
 
     procedure tcgtempcreatenode.pass_2;
-      var
-        temptype : ttemptype;
       begin
-        location_reset(location,LOC_VOID,OS_NO);
-
         { if we're secondpassing the same tcgtempcreatenode twice, we have a bug }
         if tempinfo^.valid then
           internalerror(200108222);
 
         { get a (persistent) temp }
         if persistent then
-          temptype:=tt_persistant
+          tg.gettempofsizereferencepersistant(exprasmlist,size,tempinfo^.ref)
         else
-          temptype:=tt_normal;
-        tg.GetTemp(exprasmlist,size,temptype,tempinfo^.ref);
+          tg.gettempofsizereference(exprasmlist,size,tempinfo^.ref);
         tempinfo^.valid := true;
       end;
 
@@ -296,12 +272,10 @@ interface
 
     procedure tcgtempdeletenode.pass_2;
       begin
-        location_reset(location,LOC_VOID,OS_NO);
-
         if release_to_normal then
-          tg.ChangeTempType(exprasmlist,tempinfo^.ref,tt_normal)
+          tg.persistanttemptonormal(tempinfo^.ref.offset)
         else
-          tg.UnGetTemp(exprasmlist,tempinfo^.ref);
+          tg.ungetpersistanttempreference(exprasmlist,tempinfo^.ref);
       end;
 
 
@@ -316,85 +290,7 @@ begin
 end.
 {
   $Log$
-  Revision 1.32  2002-04-25 20:15:39  florian
-    * block nodes within expressions shouldn't release the used registers,
-      fixed using a flag till the new rg is ready
-
-  Revision 1.31  2003/04/22 23:50:22  peter
-    * firstpass uses expectloc
-    * checks if there are differences between the expectloc and
-      location.loc from secondpass in EXTDEBUG
-
-  Revision 1.30  2003/04/17 07:50:24  daniel
-    * Some work on interference graph construction
-
-  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)
-
-  Revision 1.27  2002/11/27 02:37:13  peter
-    * case statement inlining added
-    * fixed inlining of write()
-    * switched statementnode left and right parts so the statements are
-      processed in the correct order when getcopy is used. This is
-      required for tempnodes
-
-  Revision 1.26  2002/11/17 16:31:56  carl
-    * memory optimization (3-4%) : cleanup of tai fields,
-       cleanup of tdef and tsym fields.
-    * make it work for m68k
-
-  Revision 1.25  2002/11/15 16:29:30  peter
-    * made tasmsymbol.refs private (merged)
-
-  Revision 1.24  2002/11/15 01:58:51  peter
-    * merged changes from 1.0.7 up to 04-11
-      - -V option for generating bug report tracing
-      - more tracing for option parsing
-      - errors for cdecl and high()
-      - win32 import stabs
-      - win32 records<=8 are returned in eax:edx (turned off by default)
-      - heaptrc update
-      - more info for temp management in .s file with EXTDEBUG
-
-  Revision 1.23  2002/08/23 16:14:48  peter
-    * tempgen cleanup
-    * tt_noreuse temp type added that will be used in genentrycode
-
-  Revision 1.22  2002/08/11 14:32:26  peter
-    * renamed current_library to objectlibrary
-
-  Revision 1.21  2002/08/11 13:24:11  peter
-    * saving of asmsymbols in ppu supported
-    * asmsymbollist global is removed and moved into a new class
-      tasmlibrarydata that will hold the info of a .a file which
-      corresponds with a single module. Added librarydata to tmodule
-      to keep the library info stored for the module. In the future the
-      objectfiles will also be stored to the tasmlibrarydata class
-    * all getlabel/newasmsymbol and friends are moved to the new class
-
-  Revision 1.20  2002/07/01 18:46:22  peter
-    * internal linker
-    * reorganized aasm layer
-
-  Revision 1.19  2002/05/18 13:34:09  peter
-    * readded missing revisions
-
-  Revision 1.18  2002/05/16 19:46:37  carl
-  + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
-  + try to fix temp allocation (still in ifdef)
-  + generic constructor calls
-  + start of tassembler / tmodulebase class cleanup
-
-  Revision 1.16  2002/05/13 19:54:37  peter
-    * removed n386ld and n386util units
-    * maybe_save/maybe_restore added instead of the old maybe_push
-
-  Revision 1.15  2002/05/12 16:53:07  peter
+  Revision 1.15  2002-05-12 16:53:07  peter
     * moved entry and exitcode to ncgutil and cgobj
     * foreach gets extra argument for passing local data to the
       iterator function
@@ -444,4 +340,52 @@ end.
     - list field removed of the tnode class because it's not used currently
       and can cause hard-to-find bugs
 
+  Revision 1.10  2001/12/31 16:54:14  peter
+    * fixed inline crash with assembler routines
+
+  Revision 1.9  2001/11/02 22:58:01  peter
+    * procsym definition rewrite
+
+  Revision 1.8  2001/10/25 21:22:35  peter
+    * calling convention rewrite
+
+  Revision 1.7  2001/08/26 13:36:39  florian
+    * some cg reorganisation
+    * some PPC updates
+
+  Revision 1.6  2001/08/24 13:47:27  jonas
+    * moved "reverseparameters" from ninl.pas to ncal.pas
+    + support for non-persistent temps in ttempcreatenode.create, for use
+      with typeconversion nodes
+
+  Revision 1.5  2001/08/23 14:28:35  jonas
+    + tempcreate/ref/delete nodes (allows the use of temps in the
+      resulttype and first pass)
+    * made handling of read(ln)/write(ln) processor independent
+    * moved processor independent handling for str and reset/rewrite-typed
+      from firstpass to resulttype pass
+    * changed names of helpers in text.inc to be generic for use as
+      compilerprocs + added "iocheck" directive for most of them
+    * reading of ordinals is done by procedures instead of functions
+      because otherwise FPC_IOCHECK overwrote the result before it could
+      be stored elsewhere (range checking still works)
+    * compilerprocs can now be used in the system unit before they are
+      implemented
+    * added note to errore.msg that booleans can't be read using read/readln
+
+  Revision 1.4  2001/06/02 19:22:15  peter
+    * refs count for relabeled asmsymbols fixed
+
+  Revision 1.3  2001/05/18 22:31:06  peter
+    * tasmnode.pass_2 is independent of cpu, moved to ncgbas
+    * include ncgbas for independent nodes
+
+  Revision 1.2  2001/04/13 01:22:08  peter
+    * symtable change to classes
+    * range check generation and errors fixed, make cycle DEBUG=1 works
+    * memory leaks fixed
+
+  Revision 1.1  2000/10/14 10:14:50  peter
+    * moehrendorf oct 2000 rewrite
+
 }

+ 50 - 6
compiler/ncgcnv.pas

@@ -54,6 +54,10 @@ interface
          procedure pass_2;override;
        end;
 
+       tcgasnode = class(tasnode)
+         procedure pass_2;override;
+       end;
+
   implementation
 
     uses
@@ -63,7 +67,7 @@ interface
       cpubase,cpuinfo,
       pass_2,
       cginfo,cgbase,
-      cga,cgobj,cgcpu,
+      cgobj,cgcpu,
       ncgutil,
       tgobj,rgobj
       ;
@@ -84,7 +88,7 @@ interface
           begin
             { reuse the left location by default }
             location_copy(location,left.location);
-            location_force_reg(location,newsize,false);
+            location_force_reg(exprasmlist,location,newsize,false);
           end
         else
           begin
@@ -267,7 +271,7 @@ interface
 
       begin
         { method pointer ? }
-        if assigned(tcallnode(left).left) then
+        if assigned(tunarynode(left).left) then
           begin
              location_copy(location,left.location);
           end
@@ -296,7 +300,7 @@ interface
          if not((nf_explizit in flags) and
                 (left.resulttype.def.size=resulttype.def.size) and
                 (left.location.loc in [LOC_REFERENCE,LOC_CREFERENCE,LOC_CREGISTER])) then
-           location_force_reg(location,def_cgsize(resulttype.def),false);
+           location_force_reg(exprasmlist,location,def_cgsize(resulttype.def),false);
          truelabel:=oldtruelabel;
          falselabel:=oldfalselabel;
       end;
@@ -395,7 +399,7 @@ interface
           moving to memory before the new size is set }
         if (resulttype.def.deftype=floatdef) and
            (location.loc=LOC_CONSTANT) then
-         location_force_mem(location);
+         location_force_mem(exprasmlist,location);
 
         { but use the new size, but we don't know the size of all arrays }
         location.size:=def_cgsize(resulttype.def);
@@ -435,13 +439,53 @@ interface
 {$endif TESTOBJEXT2}
       end;
 
+
+    procedure tcgasnode.pass_2;
+      var
+        pushed : tpushedsaved;
+      begin
+        { instance to check }
+        secondpass(left);
+        rg.saveusedregisters(exprasmlist,pushed,all_registers);
+        cg.a_param_loc(exprasmlist,left.location,2);
+        { type information }
+        secondpass(right);
+        cg.a_param_loc(exprasmlist,right.location,1);
+        location_release(exprasmlist,right.location);
+        { call helper }
+        cg.a_call_name(exprasmlist,'FPC_DO_AS');
+        cg.g_maybe_loadself(exprasmlist);
+        rg.restoreusedregisters(exprasmlist,pushed);
+
+        location_copy(location,left.location);
+      end;
+
+
 begin
   ctypeconvnode := tcgtypeconvnode;
+  casnode := tcgasnode;
 end.
 
 {
   $Log$
-  Revision 1.11  2002-04-21 19:02:03  peter
+  Revision 1.12  2002-05-12 16:53:07  peter
+    * moved entry and exitcode to ncgutil and cgobj
+    * foreach gets extra argument for passing local data to the
+      iterator function
+    * -CR checks also class typecasts at runtime by changing them
+      into as
+    * fixed compiler to cycle with the -CR option
+    * fixed stabs with elf writer, finally the global variables can
+      be watched
+    * removed a lot of routines from cga unit and replaced them by
+      calls to cgobj
+    * u32bit-s32bit updates for and,or,xor nodes. When one element is
+      u32bit then the other is typecasted also to u32bit without giving
+      a rangecheck warning/error.
+    * fixed pascal calling method with reversing also the high tree in
+      the parast, detected by tcalcst3 test
+
+  Revision 1.11  2002/04/21 19:02:03  peter
     * removed newn and disposen nodes, the code is now directly
       inlined from pexpr
     * -an option that will write the secondpass nodes to the .s file, this

+ 22 - 5
compiler/ncgflw.pas

@@ -71,7 +71,7 @@ implementation
       cginfo,cgbase,pass_2,
       cpubase,cpuasm,cpuinfo,
       nld,ncon,
-      cga,tgobj,rgobj,
+      tgobj,rgobj,
       ncgutil,
       regvars,cgobj,cgcpu,cg64f32;
 
@@ -128,7 +128,7 @@ implementation
          rg.cleartempgen;
          secondpass(left);
 
-         maketojumpbool(left,lr_load_regvars);
+         maketojumpbool(exprasmlist,left,lr_load_regvars);
          cg.a_label(exprasmlist,lbreak);
          truelabel:=otlabel;
          falselabel:=oflabel;
@@ -171,7 +171,7 @@ implementation
              org_list := exprasmlist;
              exprasmlist := taasmoutput.create;
            end;
-         maketojumpbool(left,lr_dont_load_regvars);
+         maketojumpbool(exprasmlist,left,lr_dont_load_regvars);
 
          if cs_regalloc in aktglobalswitches then
            org_regvar_loaded := rg.regvar_loaded;
@@ -330,7 +330,7 @@ implementation
          { produce start assignment }
          rg.cleartempgen;
          secondpass(left);
-         count_var_is_signed:=is_signed(torddef(t2.resulttype.def));
+         count_var_is_signed:=is_signed(t2.resulttype.def);
 
          if nf_backward in flags then
            if count_var_is_signed then
@@ -611,7 +611,24 @@ begin
 end.
 {
   $Log$
-  Revision 1.13  2002-04-21 15:24:38  carl
+  Revision 1.14  2002-05-12 16:53:07  peter
+    * moved entry and exitcode to ncgutil and cgobj
+    * foreach gets extra argument for passing local data to the
+      iterator function
+    * -CR checks also class typecasts at runtime by changing them
+      into as
+    * fixed compiler to cycle with the -CR option
+    * fixed stabs with elf writer, finally the global variables can
+      be watched
+    * removed a lot of routines from cga unit and replaced them by
+      calls to cgobj
+    * u32bit-s32bit updates for and,or,xor nodes. When one element is
+      u32bit then the other is typecasted also to u32bit without giving
+      a rangecheck warning/error.
+    * fixed pascal calling method with reversing also the high tree in
+      the parast, detected by tcalcst3 test
+
+  Revision 1.13  2002/04/21 15:24:38  carl
   + a_jmp_cond -> a_jmp_always (a_jmp_cond is NOT portable)
   + changeregsize -> rg.makeregsize
 

+ 23 - 6
compiler/ncgld.pas

@@ -40,10 +40,10 @@ implementation
     uses
       systems,
       verbose,globals,
-      symconst,symtype,symdef,symsym,symtable,aasm,types,
+      symconst,symtype,symdef,aasm,types,
       cginfo,cgbase,pass_2,
-      cpubase,cpuasm,
-      cga,tgobj,ncgutil,regvars,cgobj,cg64f32,rgobj,rgcpu;
+      cpubase,
+      tgobj,ncgutil,cgobj,cg64f32,rgobj,rgcpu;
 
 {*****************************************************************************
                            SecondArrayConstruct
@@ -186,7 +186,7 @@ implementation
                   begin
                     if vaddr then
                      begin
-                       location_force_mem(hp.left.location);
+                       location_force_mem(exprasmlist,hp.left.location);
                        cg.a_paramaddr_ref(exprasmlist,hp.left.location.reference,-1);
                        location_release(exprasmlist,hp.left.location);
                        if freetemp then
@@ -202,7 +202,7 @@ implementation
                     inc(href.offset,4);
                     if vaddr then
                      begin
-                       location_force_mem(hp.left.location);
+                       location_force_mem(exprasmlist,hp.left.location);
                        tmpreg:=cg.get_scratch_reg(exprasmlist);
                        cg.a_loadaddr_ref_reg(exprasmlist,hp.left.location.reference,tmpreg);
                        cg.a_load_reg_ref(exprasmlist,cg.reg_cgsize(tmpreg),tmpreg,href);
@@ -260,7 +260,24 @@ begin
 end.
 {
   $Log$
-  Revision 1.2  2002-04-21 15:24:38  carl
+  Revision 1.3  2002-05-12 16:53:07  peter
+    * moved entry and exitcode to ncgutil and cgobj
+    * foreach gets extra argument for passing local data to the
+      iterator function
+    * -CR checks also class typecasts at runtime by changing them
+      into as
+    * fixed compiler to cycle with the -CR option
+    * fixed stabs with elf writer, finally the global variables can
+      be watched
+    * removed a lot of routines from cga unit and replaced them by
+      calls to cgobj
+    * u32bit-s32bit updates for and,or,xor nodes. When one element is
+      u32bit then the other is typecasted also to u32bit without giving
+      a rangecheck warning/error.
+    * fixed pascal calling method with reversing also the high tree in
+      the parast, detected by tcalcst3 test
+
+  Revision 1.2  2002/04/21 15:24:38  carl
   + a_jmp_cond -> a_jmp_always (a_jmp_cond is NOT portable)
   + changeregsize -> rg.makeregsize
 

+ 25 - 9
compiler/ncgmem.pas

@@ -73,7 +73,7 @@ implementation
       globtype,systems,
       cutils,verbose,globals,
       symconst,symdef,symsym,aasm,
-      cginfo,cgbase,pass_2,
+      cgbase,pass_2,
       nld,ncon,nadd,
       cpuinfo,cpubase,cgobj,cgcpu,
       tgobj,rgobj
@@ -83,7 +83,6 @@ implementation
   {$else}
       ,strings
   {$endif}
-      ,cga
       ,symbase
       ,gdb
 {$endif GDB}
@@ -239,10 +238,10 @@ implementation
          end;
          if (cs_gdb_heaptrc in aktglobalswitches) and
             (cs_checkpointer in aktglobalswitches) then
-              begin
-                 cg.a_param_reg(exprasmlist, OS_ADDR,location.reference.base,1);
-                 cg.a_call_name(exprasmlist,'FPC_CHECKPOINTER',0);
-              end;
+          begin
+            cg.a_param_reg(exprasmlist, OS_ADDR,location.reference.base,1);
+            cg.a_call_name(exprasmlist,'FPC_CHECKPOINTER');
+          end;
       end;
 
 
@@ -393,7 +392,7 @@ implementation
                       inc(withlevel);
                       getaddrlabel(withstartlabel);
                       getaddrlabel(withendlabel);
-                      emitlab(withstartlabel);
+                      cg.a_label(exprasmlist,withstartlabel);
                       withdebugList.concat(Tai_stabs.Create(strpnew(
                          '"with'+tostr(withlevel)+':'+tostr(symtablestack.getnewtypecount)+
                          '=*'+tstoreddef(left.resulttype.def).numberstring+'",'+
@@ -421,7 +420,7 @@ implementation
 {$ifdef GDB}
                    if (cs_debuginfo in aktmoduleswitches) then
                      begin
-                       emitlab(withendlabel);
+                       cg.a_label(exprasmlist,withendlabel);
                        strpcopy(pp,'224,0,0,'+withendlabel.name);
                       if (target_info.use_function_relative_addresses) then
                         begin
@@ -455,7 +454,24 @@ begin
 end.
 {
   $Log$
-  Revision 1.8  2002-04-20 21:32:23  carl
+  Revision 1.9  2002-05-12 16:53:07  peter
+    * moved entry and exitcode to ncgutil and cgobj
+    * foreach gets extra argument for passing local data to the
+      iterator function
+    * -CR checks also class typecasts at runtime by changing them
+      into as
+    * fixed compiler to cycle with the -CR option
+    * fixed stabs with elf writer, finally the global variables can
+      be watched
+    * removed a lot of routines from cga unit and replaced them by
+      calls to cgobj
+    * u32bit-s32bit updates for and,or,xor nodes. When one element is
+      u32bit then the other is typecasted also to u32bit without giving
+      a rangecheck warning/error.
+    * fixed pascal calling method with reversing also the high tree in
+      the parast, detected by tcalcst3 test
+
+  Revision 1.8  2002/04/20 21:32:23  carl
   + generic FPC_CHECKPOINTER
   + first parameter offset in stack now portable
   * rename some constants

+ 963 - 81
compiler/ncgutil.pas

@@ -28,23 +28,42 @@ interface
 
     uses
       node,
-      cginfo,
-      cpubase;
+      cginfo,cpubase,aasm;
 
     type
       tloadregvars = (lr_dont_load_regvars, lr_load_regvars);
 
-    procedure location_force_reg(var l:tlocation;dst_size:TCGSize;maybeconst:boolean);
-    procedure location_force_mem(var l:tlocation);
+    procedure location_force_reg(list: TAAsmoutput;var l:tlocation;dst_size:TCGSize;maybeconst:boolean);
+    procedure location_force_mem(list: TAAsmoutput;var l:tlocation);
+
+    procedure maketojumpbool(list:TAAsmoutput; p : tnode; loadregvars: tloadregvars);
+
+
+    procedure genentrycode(list : TAAsmoutput;
+                           make_global:boolean;
+                           stackframe:longint;
+                           var parasize:longint;var nostackframe:boolean;
+                           inlined : boolean);
+   procedure genexitcode(list : TAAsmoutput;parasize:longint;nostackframe,inlined:boolean);
+   procedure genimplicitunitinit(list : TAAsmoutput);
+   procedure genimplicitunitfinal(list : TAAsmoutput);
 
-    procedure maketojumpbool(p : tnode; loadregvars: tloadregvars);
 
 implementation
 
   uses
-    globals,systems,verbose,
-    types,
-    aasm,cgbase,regvars,
+{$ifdef Delphi}
+    Sysutils,
+{$else}
+    strings,
+{$endif}
+    cutils,cclasses,globtype,globals,systems,verbose,
+    symbase,symconst,symtype,symsym,symdef,symtable,types,
+    fmodule,
+    cgbase,regvars,tainst,cpuasm,
+{$ifdef GDB}
+    gdb,
+{$endif GDB}
     ncon,
     tgobj,cpuinfo,cgobj,cgcpu,rgobj,cg64f32;
 
@@ -54,7 +73,7 @@ implementation
 *****************************************************************************}
 
     { 32-bit version }
-    procedure location_force_reg32(var l:tlocation;dst_size:TCGSize;maybeconst:boolean);
+    procedure location_force_reg32(list: TAAsmoutput;var l:tlocation;dst_size:TCGSize;maybeconst:boolean);
       var
         hregister,
         hregisterhi : tregister;
@@ -69,44 +88,44 @@ implementation
               if l.loc=LOC_REGISTER then
                hregister:=rg.makeregsize(l.registerlow,OS_INT)
               else
-               hregister:=rg.getregisterint(exprasmlist);
+               hregister:=rg.getregisterint(list);
               { load value in low register }
               case l.loc of
                 LOC_FLAGS :
-                  cg.g_flags2reg(exprasmlist,l.resflags,hregister);
+                  cg.g_flags2reg(list,l.resflags,hregister);
                 LOC_JUMP :
                   begin
-                    cg.a_label(exprasmlist,truelabel);
-                    cg.a_load_const_reg(exprasmlist,OS_INT,1,hregister);
+                    cg.a_label(list,truelabel);
+                    cg.a_load_const_reg(list,OS_INT,1,hregister);
                     getlabel(hl);
-                    cg.a_jmp_always(exprasmlist,hl);
-                    cg.a_label(exprasmlist,falselabel);
-                    cg.a_load_const_reg(exprasmlist,OS_INT,0,hregister);
-                    cg.a_label(exprasmlist,hl);
+                    cg.a_jmp_always(list,hl);
+                    cg.a_label(list,falselabel);
+                    cg.a_load_const_reg(list,OS_INT,0,hregister);
+                    cg.a_label(list,hl);
                   end;
                 else
-                  cg.a_load_loc_reg(exprasmlist,l,hregister);
+                  cg.a_load_loc_reg(list,l,hregister);
               end;
               { reset hi part, take care of the signed bit of the current value }
-              hregisterhi:=rg.getregisterint(exprasmlist);
+              hregisterhi:=rg.getregisterint(list);
               if (dst_size=OS_S64) and
                  (l.size in [OS_S8,OS_S16,OS_S32]) then
                begin
                  if l.loc=LOC_CONSTANT then
                   begin
                     if (longint(l.value)<0) then
-                     cg.a_load_const_reg(exprasmlist,OS_32,$ffffffff,hregisterhi)
+                     cg.a_load_const_reg(list,OS_32,$ffffffff,hregisterhi)
                     else
-                     cg.a_load_const_reg(exprasmlist,OS_32,0,hregisterhi);
+                     cg.a_load_const_reg(list,OS_32,0,hregisterhi);
                   end
                  else
                   begin
-                    cg.a_load_reg_reg(exprasmlist,OS_32,hregister,hregisterhi);
-                    cg.a_op_const_reg(exprasmlist,OP_SAR,31,hregisterhi);
+                    cg.a_load_reg_reg(list,OS_32,hregister,hregisterhi);
+                    cg.a_op_const_reg(list,OP_SAR,31,hregisterhi);
                   end;
                end
               else
-               cg.a_load_const_reg(exprasmlist,OS_32,0,hregisterhi);
+               cg.a_load_const_reg(list,OS_32,0,hregisterhi);
               location_reset(l,LOC_REGISTER,dst_size);
               l.registerlow:=hregister;
               l.registerhigh:=hregisterhi;
@@ -122,11 +141,11 @@ implementation
                end
               else
                begin
-                 hregister:=rg.getregisterint(exprasmlist);
-                 hregisterhi:=rg.getregisterint(exprasmlist);
+                 hregister:=rg.getregisterint(list);
+                 hregisterhi:=rg.getregisterint(list);
                end;
               { load value in new register }
-              tcg64f32(cg).a_load64_loc_reg(exprasmlist,l,hregister,hregisterhi);
+              tcg64f32(cg).a_load64_loc_reg(list,l,hregister,hregisterhi);
               location_reset(l,LOC_REGISTER,dst_size);
               l.registerlow:=hregister;
               l.registerhigh:=hregisterhi;
@@ -140,7 +159,7 @@ implementation
               { if the previous was 64bit release the high register }
               if l.size in [OS_64,OS_S64] then
                begin
-                 rg.ungetregisterint(exprasmlist,l.registerhigh);
+                 rg.ungetregisterint(list,l.registerhigh);
                  l.registerhigh:=R_NO;
                end;
               hregister:=l.register;
@@ -153,22 +172,22 @@ implementation
                  (TCGSize2Size[dst_size]=TCGSize2Size[l.size]) then
                hregister:=l.register
               else
-               hregister:=rg.getregisterint(exprasmlist);
+               hregister:=rg.getregisterint(list);
             end;
            hregister:=rg.makeregsize(hregister,dst_size);
            { load value in new register }
            case l.loc of
              LOC_FLAGS :
-               cg.g_flags2reg(exprasmlist,l.resflags,hregister);
+               cg.g_flags2reg(list,l.resflags,hregister);
              LOC_JUMP :
                begin
-                 cg.a_label(exprasmlist,truelabel);
-                 cg.a_load_const_reg(exprasmlist,dst_size,1,hregister);
+                 cg.a_label(list,truelabel);
+                 cg.a_load_const_reg(list,dst_size,1,hregister);
                  getlabel(hl);
-                 cg.a_jmp_always(exprasmlist,hl);
-                 cg.a_label(exprasmlist,falselabel);
-                 cg.a_load_const_reg(exprasmlist,dst_size,0,hregister);
-                 cg.a_label(exprasmlist,hl);
+                 cg.a_jmp_always(list,hl);
+                 cg.a_label(list,falselabel);
+                 cg.a_load_const_reg(list,dst_size,0,hregister);
+                 cg.a_label(list,hl);
                end;
              else
                begin
@@ -181,7 +200,7 @@ implementation
                      l.register:=rg.makeregsize(l.register,dst_size);
                     l.size:=dst_size;
                   end;
-                 cg.a_load_loc_reg(exprasmlist,l,hregister);
+                 cg.a_load_loc_reg(list,l,hregister);
                end;
            end;
            location_reset(l,LOC_REGISTER,dst_size);
@@ -190,10 +209,9 @@ implementation
      end;
 
     { 64-bit version }
-    procedure location_force_reg64(var l:tlocation;dst_size:TCGSize;maybeconst:boolean);
+    procedure location_force_reg64(list: TAAsmoutput;var l:tlocation;dst_size:TCGSize;maybeconst:boolean);
       var
-        hregister,
-        hregisterhi : tregister;
+        hregister : tregister;
         hl : tasmlabel;
      begin
         { handle transformations to 64bit separate }
@@ -203,23 +221,23 @@ implementation
               if l.loc=LOC_REGISTER then
                hregister:=rg.makeregsize(l.register,OS_INT)
               else
-               hregister:=rg.getregisterint(exprasmlist);
+               hregister:=rg.getregisterint(list);
               { load value in low register }
               case l.loc of
                 LOC_FLAGS :
-                  cg.g_flags2reg(exprasmlist,l.resflags,hregister);
+                  cg.g_flags2reg(list,l.resflags,hregister);
                 LOC_JUMP :
                   begin
-                    cg.a_label(exprasmlist,truelabel);
-                    cg.a_load_const_reg(exprasmlist,OS_INT,1,hregister);
+                    cg.a_label(list,truelabel);
+                    cg.a_load_const_reg(list,OS_INT,1,hregister);
                     getlabel(hl);
-                    cg.a_jmp_always(exprasmlist,hl);
-                    cg.a_label(exprasmlist,falselabel);
-                    cg.a_load_const_reg(exprasmlist,OS_INT,0,hregister);
-                    cg.a_label(exprasmlist,hl);
+                    cg.a_jmp_always(list,hl);
+                    cg.a_label(list,falselabel);
+                    cg.a_load_const_reg(list,OS_INT,0,hregister);
+                    cg.a_label(list,hl);
                   end;
                 else
-                  cg.a_load_loc_reg(exprasmlist,l,hregister);
+                  cg.a_load_loc_reg(list,l,hregister);
               end;
               location_reset(l,LOC_REGISTER,dst_size);
               l.register:=hregister;
@@ -239,22 +257,22 @@ implementation
                  (TCGSize2Size[dst_size]=TCGSize2Size[l.size]) then
                hregister:=l.register
               else
-               hregister:=rg.getregisterint(exprasmlist);
+               hregister:=rg.getregisterint(list);
             end;
            hregister:=rg.makeregsize(hregister,dst_size);
            { load value in new register }
            case l.loc of
              LOC_FLAGS :
-               cg.g_flags2reg(exprasmlist,l.resflags,hregister);
+               cg.g_flags2reg(list,l.resflags,hregister);
              LOC_JUMP :
                begin
-                 cg.a_label(exprasmlist,truelabel);
-                 cg.a_load_const_reg(exprasmlist,dst_size,1,hregister);
+                 cg.a_label(list,truelabel);
+                 cg.a_load_const_reg(list,dst_size,1,hregister);
                  getlabel(hl);
-                 cg.a_jmp_always(exprasmlist,hl);
-                 cg.a_label(exprasmlist,falselabel);
-                 cg.a_load_const_reg(exprasmlist,dst_size,0,hregister);
-                 cg.a_label(exprasmlist,hl);
+                 cg.a_jmp_always(list,hl);
+                 cg.a_label(list,falselabel);
+                 cg.a_load_const_reg(list,dst_size,0,hregister);
+                 cg.a_label(list,hl);
                end;
              else
                begin
@@ -267,7 +285,7 @@ implementation
                      l.register:=rg.makeregsize(l.register,dst_size);
                     l.size:=dst_size;
                   end;
-                 cg.a_load_loc_reg(exprasmlist,l,hregister);
+                 cg.a_load_loc_reg(list,l,hregister);
                end;
            end;
            location_reset(l,LOC_REGISTER,dst_size);
@@ -275,22 +293,22 @@ implementation
          end;
      end;
 
-    procedure location_force_reg(var l:tlocation;dst_size:TCGSize;maybeconst:boolean);
+    procedure location_force_reg(list: TAAsmoutput;var l:tlocation;dst_size:TCGSize;maybeconst:boolean);
       begin
         { release previous location before demanding a new register }
         if (l.loc in [LOC_REFERENCE,LOC_CREFERENCE]) then
          begin
-           location_freetemp(exprasmlist,l);
-           location_release(exprasmlist,l);
+           location_freetemp(list,l);
+           location_release(list,l);
          end;
         if sizeof(aword) < 8 then
-          location_force_reg32(l, dst_size, maybeconst)
+          location_force_reg32(list, l, dst_size, maybeconst)
         else
-          location_force_reg64(l, dst_size, maybeconst);
+          location_force_reg64(list, l, dst_size, maybeconst);
       end;
 
 
-    procedure location_force_mem(var l:tlocation);
+    procedure location_force_mem(list: TAAsmoutput;var l:tlocation);
       var
         r : treference;
       begin
@@ -298,8 +316,8 @@ implementation
           LOC_FPUREGISTER,
           LOC_CFPUREGISTER :
             begin
-              tg.gettempofsizereference(exprasmlist,TCGSize2Size[l.size],r);
-              cg.a_loadfpu_reg_ref(exprasmlist,l.size,l.register,r);
+              tg.gettempofsizereference(list,TCGSize2Size[l.size],r);
+              cg.a_loadfpu_reg_ref(list,l.size,l.register,r);
               location_reset(l,LOC_REFERENCE,l.size);
               l.reference:=r;
             end;
@@ -307,11 +325,11 @@ implementation
           LOC_REGISTER,
           LOC_CREGISTER :
             begin
-              tg.gettempofsizereference(exprasmlist,TCGSize2Size[l.size],r);
+              tg.gettempofsizereference(list,TCGSize2Size[l.size],r);
               if l.size in [OS_64,OS_S64] then
-               tcg64f32(cg).a_load64_loc_ref(exprasmlist,l,r)
+               tcg64f32(cg).a_load64_loc_ref(list,l,r)
               else
-               cg.a_load_loc_ref(exprasmlist,l,r);
+               cg.a_load_loc_ref(list,l,r);
               location_reset(l,LOC_REFERENCE,l.size);
               l.reference:=r;
             end;
@@ -323,7 +341,7 @@ implementation
       end;
 
 
-    procedure maketojumpbool(p : tnode; loadregvars: tloadregvars);
+    procedure maketojumpbool(list:TAAsmoutput; p : tnode; loadregvars: tloadregvars);
     {
       produces jumps to true respectively false labels using boolean expressions
 
@@ -343,13 +361,13 @@ implementation
          if is_boolean(p.resulttype.def) then
            begin
               if loadregvars = lr_load_regvars then
-                load_all_regvars(exprasmlist);
+                load_all_regvars(list);
               if is_constboolnode(p) then
                 begin
                    if tordconstnode(p).value<>0 then
-                     cg.a_jmp_always(exprasmlist,truelabel)
+                     cg.a_jmp_always(list,truelabel)
                    else
-                     cg.a_jmp_always(exprasmlist,falselabel)
+                     cg.a_jmp_always(list,falselabel)
                 end
               else
                 begin
@@ -358,18 +376,18 @@ implementation
                      LOC_CREGISTER,LOC_REGISTER,LOC_CREFERENCE,LOC_REFERENCE :
                        begin
                          if (p.location.loc = LOC_CREGISTER) then
-                           load_regvar_reg(exprasmlist,p.location.register);
-                         cg.a_cmp_const_loc_label(exprasmlist,opsize,OC_NE,
+                           load_regvar_reg(list,p.location.register);
+                         cg.a_cmp_const_loc_label(list,opsize,OC_NE,
                            0,p.location,truelabel);
                          { !!! should happen right after cmp (JM) }
-                         location_release(exprasmlist,p.location);
-                         cg.a_jmp_always(exprasmlist,falselabel);
+                         location_release(list,p.location);
+                         cg.a_jmp_always(list,falselabel);
                        end;
                      LOC_FLAGS :
                        begin
-                         cg.a_jmp_flags(exprasmlist,p.location.resflags,
+                         cg.a_jmp_flags(list,p.location.resflags,
                            truelabel);
-                         cg.a_jmp_always(exprasmlist,falselabel);
+                         cg.a_jmp_always(list,falselabel);
                        end;
                    end;
                 end;
@@ -379,11 +397,875 @@ implementation
          aktfilepos:=storepos;
       end;
 
-end.
 
+{****************************************************************************
+                                 Entry/Exit Code
+****************************************************************************}
+
+    procedure copyvalueparas(p : tnamedindexitem;arg:pointer);
+      var
+        href1,href2 : treference;
+        list : taasmoutput;
+      begin
+        list:=taasmoutput(arg);
+        if (tsym(p).typ=varsym) and
+           (tvarsym(p).varspez=vs_value) and
+           (push_addr_param(tvarsym(p).vartype.def)) then
+         begin
+           reference_reset_base(href1,procinfo^.framepointer,tvarsym(p).address+procinfo^.para_offset);
+           if is_open_array(tvarsym(p).vartype.def) or
+              is_array_of_const(tvarsym(p).vartype.def) then
+             cg.g_copyvaluepara_openarray(list,href1,tarraydef(tvarsym(p).vartype.def).elesize)
+           else
+            begin
+              reference_reset_base(href2,procinfo^.framepointer,-tvarsym(p).localvarsym.address+tvarsym(p).localvarsym.owner.address_fixup);
+              if is_shortstring(tvarsym(p).vartype.def) then
+               cg.g_copyshortstring(list,href1,href2,tstringdef(tvarsym(p).vartype.def).len,false,true)
+              else
+               cg.g_concatcopy(list,href1,href2,tvarsym(p).vartype.def.size,true,true);
+            end;
+         end;
+      end;
+
+
+    procedure initialize_threadvar(p : tnamedindexitem;arg:pointer);
+      var
+        href : treference;
+        list : taasmoutput;
+      begin
+        list:=taasmoutput(arg);
+        if (tsym(p).typ=varsym) and
+           (vo_is_thread_var in tvarsym(p).varoptions) then
+         begin
+           cg.a_param_const(list,OS_INT,tvarsym(p).getsize,2);
+           reference_reset_symbol(href,newasmsymbol(tvarsym(p).mangledname),0);
+           cg.a_paramaddr_ref(list,href,2);
+           rg.saveregvars(list,all_registers);
+           cg.a_call_name(list,'FPC_INIT_THREADVAR');
+         end;
+     end;
+
+
+    { generates the code for initialisation of local data }
+    procedure initialize_data(p : tnamedindexitem;arg:pointer);
+      var
+        href : treference;
+        list : taasmoutput;
+      begin
+        list:=taasmoutput(arg);
+        if (tsym(p).typ=varsym) and
+           assigned(tvarsym(p).vartype.def) and
+           not(is_class(tvarsym(p).vartype.def)) and
+           tvarsym(p).vartype.def.needs_inittable then
+         begin
+           if assigned(procinfo) then
+            procinfo^.flags:=procinfo^.flags or pi_needs_implicit_finally;
+           if tsym(p).owner.symtabletype in [localsymtable,inlinelocalsymtable] then
+            reference_reset_base(href,procinfo^.framepointer,-tvarsym(p).address+tvarsym(p).owner.address_fixup)
+           else
+            reference_reset_symbol(href,newasmsymbol(tvarsym(p).mangledname),0);
+           cg.g_initialize(list,tvarsym(p).vartype.def,href,false);
+         end;
+      end;
+
+
+    { generates the code for finalisation of local data }
+    procedure finalize_data(p : tnamedindexitem;arg:pointer);
+      var
+        href : treference;
+        list : taasmoutput;
+      begin
+        list:=taasmoutput(arg);
+        if (tsym(p).typ=varsym) and
+           assigned(tvarsym(p).vartype.def) and
+           not(is_class(tvarsym(p).vartype.def)) and
+           tvarsym(p).vartype.def.needs_inittable then
+         begin
+           if tsym(p).owner.symtabletype in [localsymtable,inlinelocalsymtable] then
+            reference_reset_base(href,procinfo^.framepointer,-tvarsym(p).address+tvarsym(p).owner.address_fixup)
+           else
+            reference_reset_symbol(href,newasmsymbol(tvarsym(p).mangledname),0);
+           cg.g_finalize(list,tvarsym(p).vartype.def,href,false);
+         end;
+      end;
+
+
+    { generates the code for incrementing the reference count of parameters and
+      initialize out parameters }
+    procedure init_paras(p : tnamedindexitem;arg:pointer);
+      var
+        href : treference;
+        tmpreg : tregister;
+        list : taasmoutput;
+      begin
+        list:=taasmoutput(arg);
+        if (tsym(p).typ=varsym) and
+           not is_class(tvarsym(p).vartype.def) and
+           tvarsym(p).vartype.def.needs_inittable then
+         begin
+           case tvarsym(p).varspez of
+             vs_value :
+               begin
+                 procinfo^.flags:=procinfo^.flags or pi_needs_implicit_finally;
+                 if assigned(tvarsym(p).localvarsym) then
+                  reference_reset_base(href,procinfo^.framepointer,
+                      -tvarsym(p).localvarsym.address+tvarsym(p).localvarsym.owner.address_fixup)
+                 else
+                  reference_reset_base(href,procinfo^.framepointer,tvarsym(p).address+procinfo^.para_offset);
+                 cg.g_incrrefcount(list,tvarsym(p).vartype.def,href);
+               end;
+             vs_out :
+               begin
+                 reference_reset_base(href,procinfo^.framepointer,tvarsym(p).address+procinfo^.para_offset);
+                 tmpreg:=cg.get_scratch_reg(list);
+                 cg.a_load_ref_reg(list,OS_ADDR,href,tmpreg);
+                 reference_reset_base(href,tmpreg,0);
+                 cg.g_initialize(list,tvarsym(p).vartype.def,href,false);
+               end;
+           end;
+         end;
+      end;
+
+
+    { generates the code for decrementing the reference count of parameters }
+    procedure final_paras(p : tnamedindexitem;arg:pointer);
+      var
+        href : treference;
+        list : taasmoutput;
+      begin
+        list:=taasmoutput(arg);
+        if (tsym(p).typ=varsym) and
+           not is_class(tvarsym(p).vartype.def) and
+           tvarsym(p).vartype.def.needs_inittable then
+         begin
+           if (tvarsym(p).varspez=vs_value) then
+            begin
+              if assigned(tvarsym(p).localvarsym) then
+               reference_reset_base(href,procinfo^.framepointer,
+                   -tvarsym(p).localvarsym.address+tvarsym(p).localvarsym.owner.address_fixup)
+              else
+               reference_reset_base(href,procinfo^.framepointer,tvarsym(p).address+procinfo^.para_offset);
+              cg.g_decrrefcount(list,tvarsym(p).vartype.def,href);
+            end;
+         end;
+      end;
+
+
+    { Initialize temp ansi/widestrings,interfaces }
+    procedure inittempvariables(list:taasmoutput);
+      var
+        hp : ptemprecord;
+        href : treference;
+      begin
+        hp:=tg.templist;
+        while assigned(hp) do
+         begin
+           if hp^.temptype in [tt_ansistring,tt_freeansistring,
+                               tt_widestring,tt_freewidestring,
+                               tt_interfacecom] then
+            begin
+              procinfo^.flags:=procinfo^.flags or pi_needs_implicit_finally;
+              reference_reset_base(href,procinfo^.framepointer,hp^.pos);
+              cg.a_load_const_ref(list,OS_ADDR,0,href);
+            end;
+           hp:=hp^.next;
+         end;
+      end;
+
+
+    procedure finalizetempvariables(list:taasmoutput);
+      var
+        hp : ptemprecord;
+        href : treference;
+      begin
+        hp:=tg.templist;
+        while assigned(hp) do
+         begin
+           case hp^.temptype of
+             tt_ansistring,
+             tt_freeansistring :
+               begin
+                 reference_reset_base(href,procinfo^.framepointer,hp^.pos);
+                 cg.a_paramaddr_ref(list,href,1);
+                 cg.a_call_name(list,'FPC_ANSISTR_DECR_REF');
+               end;
+             tt_widestring,
+             tt_freewidestring :
+               begin
+                 reference_reset_base(href,procinfo^.framepointer,hp^.pos);
+                 cg.a_paramaddr_ref(list,href,1);
+                 cg.a_call_name(list,'FPC_WIDESTR_DECR_REF');
+               end;
+             tt_interfacecom :
+               begin
+                 reference_reset_base(href,procinfo^.framepointer,hp^.pos);
+                 cg.a_paramaddr_ref(list,href,1);
+                 cg.a_call_name(list,'FPC_INTF_DECR_REF');
+               end;
+           end;
+           hp:=hp^.next;
+         end;
+      end;
+
+
+    procedure handle_return_value(list:TAAsmoutput; inlined : boolean;var uses_acc,uses_acchi : boolean);
+      var
+        href : treference;
+        hreg : tregister;
+        cgsize : TCGSize;
+      begin
+        if not is_void(aktprocdef.rettype.def) then
+         begin
+           if (tfuncretsym(aktprocdef.funcretsym).funcretstate<>vs_assigned) and
+              (not inlined) then
+            CGMessage(sym_w_function_result_not_set);
+           reference_reset_base(href,procinfo^.framepointer,procinfo^.return_offset);
+           cgsize:=def_cgsize(aktprocdef.rettype.def);
+           case aktprocdef.rettype.def.deftype of
+             orddef,
+             enumdef :
+               begin
+                 uses_acc:=true;
+                 cg.a_reg_alloc(list,accumulator);
+                 if cgsize in [OS_64,OS_S64] then
+                  begin
+                    uses_acchi:=true;
+                    cg.a_reg_alloc(list,accumulatorhigh);
+                    tcg64f32(cg).a_load64_ref_reg(list,href,accumulator,accumulatorhigh);
+                  end
+                 else
+                  begin
+                    hreg:=rg.makeregsize(accumulator,cgsize);
+                    cg.a_load_ref_reg(list,cgsize,href,hreg);
+                  end;
+               end;
+             floatdef :
+               begin
+                 cg.a_loadfpu_ref_reg(list,cgsize,href,R_ST);
+               end;
+             else
+               begin
+                 if ret_in_acc(aktprocdef.rettype.def) then
+                  begin
+                    uses_acc:=true;
+                    cg.a_reg_alloc(list,accumulator);
+                    cg.a_load_ref_reg(list,cgsize,href,accumulator);
+                   end
+               end;
+           end;
+         end;
+      end;
+
+
+    procedure handle_fast_exit_return_value(list:TAAsmoutput);
+      var
+        href : treference;
+        hreg : tregister;
+        cgsize : TCGSize;
+      begin
+        if not is_void(aktprocdef.rettype.def) then
+         begin
+           reference_reset_base(href,procinfo^.framepointer,procinfo^.return_offset);
+           cgsize:=def_cgsize(aktprocdef.rettype.def);
+           case aktprocdef.rettype.def.deftype of
+             orddef,
+             enumdef :
+               begin
+                 if cgsize in [OS_64,OS_S64] then
+                  tcg64f32(cg).a_load64_reg_ref(list,accumulator,accumulatorhigh,href)
+                 else
+                  begin
+                    hreg:=rg.makeregsize(accumulator,cgsize);
+                    cg.a_load_reg_ref(list,cgsize,hreg,href);
+                  end;
+               end;
+             floatdef :
+               begin
+                 cg.a_loadfpu_reg_ref(list,cgsize,R_ST,href);
+               end;
+             else
+               begin
+                 if ret_in_acc(aktprocdef.rettype.def) then
+                  cg.a_load_reg_ref(list,cgsize,accumulator,href);
+               end;
+           end;
+         end;
+      end;
+
+
+    procedure genentrycode(list : TAAsmoutput;
+                           make_global:boolean;
+                           stackframe:longint;
+                           var parasize:longint;var nostackframe:boolean;
+                           inlined : boolean);
+      var
+        hs : string;
+        href : treference;
+        p : tsymtable;
+        tempbuf : treference;
+      begin
+        { Insert alignment and assembler names }
+        if not inlined then
+         begin
+           { Align, gprof uses 16 byte granularity }
+           if (cs_profile in aktmoduleswitches) then
+            list.concat(Tai_align.Create_op(16,$90))
+           else
+            list.concat(Tai_align.Create(aktalignment.procalign));
+
+           if (cs_profile in aktmoduleswitches) or
+              (aktprocdef.owner.symtabletype=globalsymtable) or
+              (assigned(procinfo^._class) and (procinfo^._class.owner.symtabletype=globalsymtable)) then
+            make_global:=true;
+
+           if make_global or ((procinfo^.flags and pi_is_global) <> 0) then
+            aktprocsym.is_global := True;
+
+{$ifdef GDB}
+           if (cs_debuginfo in aktmoduleswitches) then
+            begin
+              aktprocdef.concatstabto(list);
+              aktprocsym.isstabwritten:=true;
+            end;
+{$endif GDB}
+
+           repeat
+             hs:=aktprocdef.aliasnames.getfirst;
+             if hs='' then
+              break;
+{$ifdef GDB}
+             if (cs_debuginfo in aktmoduleswitches) and
+                target_info.use_function_relative_addresses then
+              list.concat(Tai_stab_function_name.Create(strpnew(hs)));
+{$endif GDB}
+             if make_global then
+              list.concat(Tai_symbol.Createname_global(hs,0))
+             else
+              list.concat(Tai_symbol.Createname(hs,0));
+           until false;
+
+           { omit stack frame ? }
+           if (procinfo^.framepointer=STACK_POINTER_REG) then
+            begin
+              CGMessage(cg_d_stackframe_omited);
+              nostackframe:=true;
+              if (aktprocdef.proctypeoption in [potype_unitinit,potype_proginit,potype_unitfinalize]) then
+                parasize:=0
+              else
+                parasize:=aktprocdef.parast.datasize+procinfo^.para_offset-4;
+              if stackframe<>0 then
+                cg.a_op_const_reg(list,OP_SUB,stackframe,procinfo^.framepointer);
+            end
+           else
+            begin
+              nostackframe:=false;
+              if (aktprocdef.proctypeoption in [potype_unitinit,potype_proginit,potype_unitfinalize]) then
+                parasize:=0
+              else
+                parasize:=aktprocdef.parast.datasize+procinfo^.para_offset-target_info.first_parm_offset;
+
+              if (po_interrupt in aktprocdef.procoptions) then
+                cg.g_interrupt_stackframe_entry(list);
+
+              cg.g_stackframe_entry(list,stackframe);
+
+              if (cs_check_stack in aktlocalswitches) then
+                cg.g_stackcheck(list,stackframe);
+            end;
+
+           if (cs_profile in aktmoduleswitches) and
+              not(po_assembler in aktprocdef.procoptions) then
+            cg.g_profilecode(list);
+         end;
+
+        { for the save all registers we can simply use a pusha,popa which
+          push edi,esi,ebp,esp(ignored),ebx,edx,ecx,eax }
+        if (po_saveregisters in aktprocdef.procoptions) then
+         cg.g_save_all_registers(list)
+        else
+         { should we save edi,esi,ebx like C ? }
+         if (po_savestdregs in aktprocdef.procoptions) then
+          cg.g_save_standard_registers(list);
+
+        { a constructor needs a help procedure }
+        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
+             list.concat(Tairegalloc.Alloc(self_pointer_reg));
+             reference_reset_base(href,procinfo^.framepointer,procinfo^.selfpointer_offset);
+             cg.a_load_ref_reg(list,OS_ADDR,href,self_pointer_reg);
+          end;
+
+        { initialize return value }
+        if (not is_void(aktprocdef.rettype.def)) and
+           (aktprocdef.rettype.def.needs_inittable) then
+          begin
+             procinfo^.flags:=procinfo^.flags or pi_needs_implicit_finally;
+             reference_reset_base(href,procinfo^.framepointer,procinfo^.return_offset);
+             cg.g_initialize(list,aktprocdef.rettype.def,href,ret_in_param(aktprocdef.rettype.def));
+          end;
+
+        { initialisize local data like ansistrings }
+        case aktprocdef.proctypeoption of
+           potype_unitinit:
+             begin
+                { using current_module.globalsymtable is hopefully      }
+                { more robust than symtablestack and symtablestack.next }
+                tsymtable(current_module.globalsymtable).foreach_static({$ifndef TP}@{$endif}initialize_data,list);
+                tsymtable(current_module.localsymtable).foreach_static({$ifndef TP}@{$endif}initialize_data,list);
+             end;
+           { units have seperate code for initilization and finalization }
+           potype_unitfinalize: ;
+           else
+             aktprocdef.localst.foreach_static({$ifndef TP}@{$endif}initialize_data,list);
+        end;
+
+        { initialisizes temp. ansi/wide string data }
+        inittempvariables(list);
+
+        { generate copies of call by value parameters }
+        if not(po_assembler in aktprocdef.procoptions) and
+           not(aktprocdef.proccalloption in [pocall_cdecl,pocall_cppdecl,pocall_palmossyscall,pocall_system]) then
+          aktprocdef.parast.foreach_static({$ifndef TP}@{$endif}copyvalueparas,list);
+
+        if assigned( aktprocdef.parast) then
+          aktprocdef.parast.foreach_static({$ifndef TP}@{$endif}init_paras,list);
+
+        if (not inlined) then
+         begin
+           { call startup helpers from main program }
+           if (aktprocdef.proctypeoption=potype_proginit) then
+            begin
+              { initialize profiling for win32 }
+              if (target_info.target in [target_I386_WIN32,target_I386_wdosx]) and
+                 (cs_profile in aktmoduleswitches) then
+                cg.a_call_name(list,'__monstartup');
+
+              { add local threadvars in units (only if needed because not all platforms
+                have threadvar support) }
+              if have_local_threadvars then
+                cg.a_call_name(list,'FPC_INITIALIZELOCALTHREADVARS');
+
+              { add global threadvars }
+              p:=symtablestack;
+              while assigned(p) do
+               begin
+                 p.foreach_static({$ifndef TP}@{$endif}initialize_threadvar,list);
+                 p:=p.next;
+               end;
+
+              { initialize units }
+              cg.a_call_name(list,'FPC_INITIALIZEUNITS');
+            end;
+
+           { do we need an exception frame because of ansi/widestrings/interfaces ? }
+           if ((procinfo^.flags and pi_needs_implicit_finally)<>0) and
+              { but it's useless in init/final code of units }
+              not(aktprocdef.proctypeoption in [potype_unitfinalize,potype_unitinit]) then
+            begin
+              include(rg.usedinproc,accumulator);
+
+              { allocate exception frame buffer }
+              list.concat(Taicpu.op_const_reg(A_SUB,S_L,36,R_ESP));
+              list.concat(Taicpu.op_reg_reg(A_MOV,S_L,R_ESP,R_EDI));
+              reference_reset_base(tempbuf,R_EDI,0);
+
+              cg.g_push_exception(list,tempbuf,1,aktexitlabel);
+
+              { probably we've to reload self here }
+              cg.g_maybe_loadself(list);
+            end;
+
+{$ifdef GDB}
+           if (cs_debuginfo in aktmoduleswitches) then
+            list.concat(Tai_force_line.Create);
+{$endif GDB}
+         end;
+
+        if inlined then
+         load_regvars(list,nil);
+      end;
+
+
+   procedure genexitcode(list : TAAsmoutput;parasize:longint;nostackframe,inlined:boolean);
+      var
+{$ifdef GDB}
+        stabsendlabel : tasmlabel;
+        mangled_length : longint;
+        p : pchar;
+        st : string[2];
+{$endif GDB}
+        okexitlabel,
+        noreraiselabel,nodestroycall : tasmlabel;
+        tmpreg : tregister;
+        href : treference;
+        usesacc,
+        usesacchi,
+        usesself : boolean;
+        pd : tprocdef;
+      begin
+        if aktexit2label.is_used and
+           ((procinfo^.flags and (pi_needs_implicit_finally or pi_uses_exceptions)) <> 0) then
+          begin
+            cg.a_jmp_always(list,aktexitlabel);
+            cg.a_label(list,aktexit2label);
+            handle_fast_exit_return_value(list);
+          end;
+
+        if aktexitlabel.is_used then
+          list.concat(Tai_label.Create(aktexitlabel));
+
+        cleanup_regvars(list);
+
+        { call the destructor help procedure }
+        if (aktprocdef.proctypeoption=potype_destructor) and
+           assigned(procinfo^._class) then
+         cg.g_call_destructor_helper(list);
+
+        { finalize temporary data }
+        finalizetempvariables(list);
+
+        { finalize local data like ansistrings}
+        case aktprocdef.proctypeoption of
+           potype_unitfinalize:
+             begin
+                { using current_module.globalsymtable is hopefully      }
+                { more robust than symtablestack and symtablestack.next }
+                tsymtable(current_module.globalsymtable).foreach_static({$ifndef TP}@{$endif}finalize_data,list);
+                tsymtable(current_module.localsymtable).foreach_static({$ifndef TP}@{$endif}finalize_data,list);
+             end;
+           { units have seperate code for initialization and finalization }
+           potype_unitinit: ;
+           else
+             aktprocdef.localst.foreach_static({$ifndef TP}@{$endif}finalize_data,list);
+        end;
+
+        { finalize paras data }
+        if assigned(aktprocdef.parast) then
+          aktprocdef.parast.foreach_static({$ifndef TP}@{$endif}final_paras,list);
+
+        { do we need to handle exceptions because of ansi/widestrings ? }
+        if not inlined and
+           ((procinfo^.flags and pi_needs_implicit_finally)<>0) and
+           { but it's useless in init/final code of units }
+           not(aktprocdef.proctypeoption in [potype_unitfinalize,potype_unitinit]) then
+          begin
+             { the exception helper routines modify all registers }
+             aktprocdef.usedregisters:=all_registers;
+             getlabel(noreraiselabel);
+             cg.g_pop_exception(list,noreraiselabel);
+
+             if (aktprocdef.proctypeoption=potype_constructor) then
+               begin
+                  if assigned(procinfo^._class) then
+                    begin
+                       pd:=procinfo^._class.searchdestructor;
+                       if assigned(pd) then
+                         begin
+                            getlabel(nodestroycall);
+                            reference_reset_base(href,procinfo^.framepointer,procinfo^.selfpointer_offset);
+                            cg.a_cmp_const_ref_label(list,OS_ADDR,OC_EQ,0,href,nodestroycall);
+                            if is_class(procinfo^._class) then
+                             begin
+                               cg.a_param_const(list,OS_INT,1,2);
+                               cg.a_param_reg(list,OS_ADDR,self_pointer_reg,1);
+                             end
+                            else if is_object(procinfo^._class) then
+                             begin
+                               cg.a_param_reg(list,OS_ADDR,self_pointer_reg,2);
+                               reference_reset_symbol(href,newasmsymbol(procinfo^._class.vmt_mangledname),0);
+                               cg.a_paramaddr_ref(list,href,1);
+                             end
+                            else
+                             Internalerror(200006164);
+                            if (po_virtualmethod in pd.procoptions) then
+                             begin
+                               reference_reset_base(href,self_pointer_reg,0);
+                               tmpreg:=cg.get_scratch_reg(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_call_ref(list,href);
+                             end
+                            else
+                             cg.a_call_name(list,pd.mangledname);
+                            { not necessary because the result is never assigned in the
+                              case of an exception (FK) }
+                            cg.a_label(list,nodestroycall);
+                         end;
+                    end
+               end
+             else
+              begin
+                { no constructor }
+                { must be the return value finalized before reraising the exception? }
+                if (not is_void(aktprocdef.rettype.def)) and
+                   (aktprocdef.rettype.def.needs_inittable) and
+                   ((aktprocdef.rettype.def.deftype<>objectdef) or
+                    not is_class(aktprocdef.rettype.def)) then
+                  begin
+                     reference_reset_base(href,procinfo^.framepointer,procinfo^.return_offset);
+                     cg.g_finalize(list,aktprocdef.rettype.def,href,ret_in_param(aktprocdef.rettype.def));
+                  end;
+              end;
+
+             cg.a_call_name(list,'FPC_RERAISE');
+             cg.a_label(list,noreraiselabel);
+          end;
+
+        { call __EXIT for main program }
+        if (not DLLsource) and
+           (not inlined) and
+           (aktprocdef.proctypeoption=potype_proginit) then
+         cg.a_call_name(list,'FPC_DO_EXIT');
+
+        { handle return value, this is not done for assembler routines when
+          they didn't reference the result variable }
+        usesacc:=false;
+        usesacchi:=false;
+        usesself:=false;
+        if not(po_assembler in aktprocdef.procoptions) or
+           (assigned(aktprocdef.funcretsym) and
+            (tfuncretsym(aktprocdef.funcretsym).refcount>1)) then
+          begin
+            if (aktprocdef.proctypeoption<>potype_constructor) then
+              handle_return_value(list,inlined,usesacc,usesacchi)
+            else
+              begin
+                { successful constructor deletes the zero flag }
+                { and returns self in eax                   }
+                { eax must be set to zero if the allocation failed !!! }
+                getlabel(okexitlabel);
+                cg.a_jmp_always(list,okexitlabel);
+                cg.a_label(list,faillabel);
+                cg.g_call_fail_helper(list);
+                cg.a_label(list,okexitlabel);
+
+                { for classes this is done after the call to }
+                { AfterConstruction                          }
+                if is_object(procinfo^._class) then
+                  begin
+                    cg.a_reg_alloc(list,accumulator);
+                    cg.a_load_reg_reg(list,OS_ADDR,self_pointer_reg,accumulator);
+                    usesacc:=true;
+                  end;
+{$ifdef i386}
+                list.concat(taicpu.op_reg_reg(A_TEST,S_L,R_ESI,R_ESI));
+{$else}
+{$warning constructor returns in flags for i386}
+{$endif i386}
+                usesself:=true;
+              end;
+          end;
+
+        if aktexit2label.is_used and not aktexit2label.is_set then
+          cg.a_label(list,aktexit2label);
+
+{$ifdef GDB}
+        if ((cs_debuginfo in aktmoduleswitches) and not inlined) then
+          begin
+            getlabel(stabsendlabel);
+            cg.a_label(list,stabsendlabel);
+          end;
+{$endif GDB}
+
+        { for the save all registers we can simply use a pusha,popa which
+          push edi,esi,ebp,esp(ignored),ebx,edx,ecx,eax }
+        if (po_saveregisters in aktprocdef.procoptions) then
+          cg.g_restore_all_registers(list,usesself,usesacc,usesacchi)
+        else
+         { should we restore edi ? }
+         if (po_savestdregs in aktprocdef.procoptions) then
+           cg.g_restore_standard_registers(list);
+
+        { remove stackframe }
+        if not inlined then
+         begin
+           if (not nostackframe) then
+            cg.g_restore_frame_pointer(list)
+           else
+            if (tg.gettempsize<>0) then
+             cg.a_op_const_reg(list,OP_ADD,tg.gettempsize,R_ESP);
+         end;
+
+        { at last, the return is generated }
+        if not inlined then
+         begin
+           if (po_interrupt in aktprocdef.procoptions) then
+            cg.g_interrupt_stackframe_exit(list,usesself,usesacc,usesacchi)
+           else
+            cg.g_return_from_proc(list,parasize);
+         end;
+
+        if not inlined then
+          list.concat(Tai_symbol_end.Createname(aktprocdef.mangledname));
+
+{$ifdef GDB}
+        if (cs_debuginfo in aktmoduleswitches) and not inlined  then
+          begin
+            if assigned(procinfo^._class) then
+              if (not assigned(procinfo^.parent) or
+                 not assigned(procinfo^.parent^._class)) then
+                begin
+                  if (po_classmethod in aktprocdef.procoptions) or
+                     ((po_virtualmethod in aktprocdef.procoptions) and
+                      (potype_constructor=aktprocdef.proctypeoption)) or
+                     (po_staticmethod in aktprocdef.procoptions) then
+                    begin
+                      list.concat(Tai_stabs.Create(strpnew(
+                       '"pvmt:p'+tstoreddef(pvmttype.def).numberstring+'",'+
+                       tostr(N_tsym)+',0,0,'+tostr(procinfo^.selfpointer_offset))));
+                    end
+                  else
+                    begin
+                      if not(is_class(procinfo^._class)) then
+                        st:='v'
+                      else
+                        st:='p';
+                      list.concat(Tai_stabs.Create(strpnew(
+                       '"$t:'+st+procinfo^._class.numberstring+'",'+
+                       tostr(N_tsym)+',0,0,'+tostr(procinfo^.selfpointer_offset))));
+                    end;
+                end
+              else
+                begin
+                  if not is_class(procinfo^._class) then
+                    st:='*'
+                  else
+                    st:='';
+                  list.concat(Tai_stabs.Create(strpnew(
+                   '"$t:r'+st+procinfo^._class.numberstring+'",'+
+                   tostr(N_RSYM)+',0,0,'+tostr(GDB_i386index[R_ESI]))));
+                end;
+
+            { define calling EBP as pseudo local var PM }
+            { this enables test if the function is a local one !! }
+            if  assigned(procinfo^.parent) and (lexlevel>normal_function_level) then
+              list.concat(Tai_stabs.Create(strpnew(
+               '"parent_ebp:'+tstoreddef(voidpointertype.def).numberstring+'",'+
+               tostr(N_LSYM)+',0,0,'+tostr(procinfo^.framepointer_offset))));
+
+            if (not is_void(aktprocdef.rettype.def)) then
+              begin
+                if ret_in_param(aktprocdef.rettype.def) then
+                  list.concat(Tai_stabs.Create(strpnew(
+                   '"'+aktprocsym.name+':X*'+tstoreddef(aktprocdef.rettype.def).numberstring+'",'+
+                   tostr(N_tsym)+',0,0,'+tostr(procinfo^.return_offset))))
+                else
+                  list.concat(Tai_stabs.Create(strpnew(
+                   '"'+aktprocsym.name+':X'+tstoreddef(aktprocdef.rettype.def).numberstring+'",'+
+                   tostr(N_tsym)+',0,0,'+tostr(procinfo^.return_offset))));
+                if (m_result in aktmodeswitches) then
+                  if ret_in_param(aktprocdef.rettype.def) then
+                    list.concat(Tai_stabs.Create(strpnew(
+                     '"RESULT:X*'+tstoreddef(aktprocdef.rettype.def).numberstring+'",'+
+                     tostr(N_tsym)+',0,0,'+tostr(procinfo^.return_offset))))
+                  else
+                    list.concat(Tai_stabs.Create(strpnew(
+                     '"RESULT:X'+tstoreddef(aktprocdef.rettype.def).numberstring+'",'+
+                     tostr(N_tsym)+',0,0,'+tostr(procinfo^.return_offset))));
+              end;
+            mangled_length:=length(aktprocdef.mangledname);
+            getmem(p,2*mangled_length+50);
+            strpcopy(p,'192,0,0,');
+            strpcopy(strend(p),aktprocdef.mangledname);
+            if (target_info.use_function_relative_addresses) then
+              begin
+                strpcopy(strend(p),'-');
+                strpcopy(strend(p),aktprocdef.mangledname);
+              end;
+            list.concat(Tai_stabn.Create(strnew(p)));
+            {List.concat(Tai_stabn.Create(strpnew('192,0,0,'
+             +aktprocdef.mangledname))));
+            p[0]:='2';p[1]:='2';p[2]:='4';
+            strpcopy(strend(p),'_end');}
+            strpcopy(p,'224,0,0,'+stabsendlabel.name);
+            if (target_info.use_function_relative_addresses) then
+              begin
+                strpcopy(strend(p),'-');
+                strpcopy(strend(p),aktprocdef.mangledname);
+              end;
+            list.concatlist(withdebuglist);
+            list.concat(Tai_stabn.Create(strnew(p)));
+             { strpnew('224,0,0,'
+             +aktprocdef.mangledname+'_end'))));}
+            freemem(p,2*mangled_length+50);
+          end;
+{$endif GDB}
+
+        if inlined then
+         cleanup_regvars(list);
+      end;
+
+
+    procedure genimplicitunitinit(list : TAAsmoutput);
+      begin
+         { using current_module.globalsymtable is hopefully      }
+         { more robust than symtablestack and symtablestack.next }
+         tsymtable(current_module.globalsymtable).foreach_static({$ifdef FPCPROCVAR}@{$endif}finalize_data,list);
+         tsymtable(current_module.localsymtable).foreach_static({$ifdef FPCPROCVAR}@{$endif}finalize_data,list);
+         list.insert(Tai_symbol.Createname_global('INIT$$'+current_module.modulename^,0));
+         list.insert(Tai_symbol.Createname_global(target_info.cprefix+current_module.modulename^+'_init',0));
+{$ifdef GDB}
+         if (cs_debuginfo in aktmoduleswitches) and
+            target_info.use_function_relative_addresses then
+           list.insert(Tai_stab_function_name.Create(strpnew('INIT$$'+current_module.modulename^)));
+{$endif GDB}
+         cg.g_return_from_proc(list,0);
+      end;
+
+
+    procedure genimplicitunitfinal(list : TAAsmoutput);
+      begin
+         { using current_module.globalsymtable is hopefully      }
+         { more robust than symtablestack and symtablestack.next }
+         tsymtable(current_module.globalsymtable).foreach_static({$ifdef FPCPROCVAR}@{$endif}finalize_data,list);
+         tsymtable(current_module.localsymtable).foreach_static({$ifdef FPCPROCVAR}@{$endif}finalize_data,list);
+         list.insert(Tai_symbol.Createname_global('FINALIZE$$'+current_module.modulename^,0));
+         list.insert(Tai_symbol.Createname_global(target_info.cprefix+current_module.modulename^+'_finalize',0));
+{$ifdef GDB}
+         if (cs_debuginfo in aktmoduleswitches) and
+            target_info.use_function_relative_addresses then
+           list.insert(Tai_stab_function_name.Create(strpnew('FINALIZE$$'+current_module.modulename^)));
+{$endif GDB}
+         cg.g_return_from_proc(list,0);
+      end;
+
+
+
+end.
 {
   $Log$
-  Revision 1.10  2002-04-21 19:02:03  peter
+  Revision 1.11  2002-05-12 16:53:07  peter
+    * moved entry and exitcode to ncgutil and cgobj
+    * foreach gets extra argument for passing local data to the
+      iterator function
+    * -CR checks also class typecasts at runtime by changing them
+      into as
+    * fixed compiler to cycle with the -CR option
+    * fixed stabs with elf writer, finally the global variables can
+      be watched
+    * removed a lot of routines from cga unit and replaced them by
+      calls to cgobj
+    * u32bit-s32bit updates for and,or,xor nodes. When one element is
+      u32bit then the other is typecasted also to u32bit without giving
+      a rangecheck warning/error.
+    * fixed pascal calling method with reversing also the high tree in
+      the parast, detected by tcalcst3 test
+
+  Revision 1.10  2002/04/21 19:02:03  peter
     * removed newn and disposen nodes, the code is now directly
       inlined from pexpr
     * -an option that will write the secondpass nodes to the .s file, this

+ 122 - 88
compiler/ncnv.pas

@@ -110,7 +110,6 @@ interface
           constructor create(l,r : tnode);virtual;
           function pass_1 : tnode;override;
           function det_resulttype:tnode;override;
-          procedure pass_2;override;
        end;
        tasnodeclass = class of tasnode;
 
@@ -128,7 +127,9 @@ interface
        cisnode : tisnodeclass;
 
     procedure inserttypeconv(var p:tnode;const t:ttype);
-    procedure arrayconstructor_to_set(var p : tarrayconstructornode);
+    procedure inserttypeconv_explicit(var p:tnode;const t:ttype);
+    procedure arrayconstructor_to_set(var p : tnode);
+
 
 implementation
 
@@ -171,11 +172,36 @@ implementation
       end;
 
 
+    procedure inserttypeconv_explicit(var p:tnode;const t:ttype);
+
+      begin
+        if not assigned(p.resulttype.def) then
+         begin
+           resulttypepass(p);
+           if codegenerror then
+            exit;
+         end;
+
+        { don't insert obsolete type conversions }
+        if is_equal(p.resulttype.def,t.def) and
+           not ((p.resulttype.def.deftype=setdef) and
+                (tsetdef(p.resulttype.def).settype <>
+                 tsetdef(t.def).settype)) then
+         begin
+           p.resulttype:=t;
+         end
+        else
+         begin
+           p:=ctypeconvnode.create_explicit(p,t);
+           resulttypepass(p);
+         end;
+      end;
+
 {*****************************************************************************
                     Array constructor to Set Conversion
 *****************************************************************************}
 
-    procedure arrayconstructor_to_set(var p : tarrayconstructornode);
+    procedure arrayconstructor_to_set(var p : tnode);
 
       var
         constp      : tsetconstnode;
@@ -234,8 +260,10 @@ implementation
       var
         l : Longint;
         lr,hr : TConstExprInt;
-
+        hp : tarrayconstructornode;
       begin
+        if p.nodetype<>arrayconstructorn then
+         internalerror(200205105);
         new(constset);
         FillChar(constset^,sizeof(constset^),0);
         htype.reset;
@@ -244,23 +272,24 @@ implementation
         constp:=csetconstnode.create(nil,htype);
         constp.value_set:=constset;
         buildp:=constp;
-        if assigned(p.left) then
+        hp:=tarrayconstructornode(p);
+        if assigned(hp.left) then
          begin
-           while assigned(p) do
+           while assigned(hp) do
             begin
               p4:=nil; { will contain the tree to create the set }
             {split a range into p2 and p3 }
-              if p.left.nodetype=arrayconstructorrangen then
+              if hp.left.nodetype=arrayconstructorrangen then
                begin
-                 p2:=tarrayconstructorrangenode(p.left).left;
-                 p3:=tarrayconstructorrangenode(p.left).right;
-                 tarrayconstructorrangenode(p.left).left:=nil;
-                 tarrayconstructorrangenode(p.left).right:=nil;
+                 p2:=tarrayconstructorrangenode(hp.left).left;
+                 p3:=tarrayconstructorrangenode(hp.left).right;
+                 tarrayconstructorrangenode(hp.left).left:=nil;
+                 tarrayconstructorrangenode(hp.left).right:=nil;
                end
               else
                begin
-                 p2:=p.left;
-                 p.left:=nil;
+                 p2:=hp.left;
+                 hp.left:=nil;
                  p3:=nil;
                end;
               resulttypepass(p2);
@@ -368,12 +397,12 @@ implementation
                     else
                       CGMessage(type_e_ordinal_expr_expected);
               end;
-            { insert the set creation tree }
+              { insert the set creation tree }
               if assigned(p4) then
                buildp:=caddnode.create(addn,buildp,p4);
-            { load next and dispose current node }
-              p2:=p;
-              p:=tarrayconstructornode(tarrayconstructornode(p2).right);
+              { load next and dispose current node }
+              p2:=hp;
+              hp:=tarrayconstructornode(tarrayconstructornode(p2).right);
               tarrayconstructornode(p2).right:=nil;
               p2.free;
             end;
@@ -382,15 +411,15 @@ implementation
          end
         else
          begin
-         { empty set [], only remove node }
+           { empty set [], only remove node }
            p.free;
          end;
-      { set the initial set type }
+        { set the initial set type }
         constp.resulttype.setdef(tsetdef.create(htype,constsethi));
-      { determine the resulttype for the tree }
+        { determine the resulttype for the tree }
         resulttypepass(buildp);
-      { set the new tree }
-        p:=tarrayconstructornode(buildp);
+        { set the new tree }
+        p:=buildp;
       end;
 
 
@@ -727,11 +756,11 @@ implementation
         result:=nil;
         if left.nodetype<>arrayconstructorn then
          internalerror(5546);
-      { remove typeconv node }
+        { remove typeconv node }
         hp:=left;
         left:=nil;
-      { create a set constructor tree }
-        arrayconstructor_to_set(tarrayconstructornode(hp));
+        { create a set constructor tree }
+        arrayconstructor_to_set(hp);
         result:=hp;
       end;
 
@@ -993,13 +1022,38 @@ implementation
 
               { constant pointer to ordinal }
               else if is_ordinal(resulttype.def) and
-                (left.nodetype=pointerconstn) then
+                      (left.nodetype=pointerconstn) then
                 begin
                    hp:=cordconstnode.create(tpointerconstnode(left).value,resulttype);
                    result:=hp;
                    exit;
                 end
 
+              { class to class or object to object, with checkobject support }
+              else if (resulttype.def.deftype=objectdef) and
+                      (left.resulttype.def.deftype=objectdef) then
+                begin
+                  if (cs_check_object in aktlocalswitches) then
+                   begin
+                     if is_class_or_interface(resulttype.def) then
+                      begin
+                        { we can translate the typeconvnode to 'as' when
+                          typecasting to a class or interface }
+                        hp:=casnode.create(left,cloadvmtnode.create(ctypenode.create(resulttype)));
+                        left:=nil;
+                        result:=hp;
+                        exit;
+                      end;
+                   end
+                  else
+                   begin
+                     { check if the types are related }
+                     if (not(tobjectdef(left.resulttype.def).is_related(tobjectdef(resulttype.def)))) and
+                        (not(tobjectdef(resulttype.def).is_related(tobjectdef(left.resulttype.def)))) then
+                       CGMessage2(type_w_classes_not_related,left.resulttype.def.typename,resulttype.def.typename);
+                   end;
+                end
+
               {Are we typecasting an ordconst to a char?}
               else
                 if is_char(resulttype.def) and
@@ -1216,7 +1270,6 @@ implementation
     function ttypeconvnode.first_nothing : tnode;
       begin
          first_nothing:=nil;
-         location.loc:=LOC_CREFERENCE;
       end;
 
 
@@ -1475,9 +1528,9 @@ implementation
         { load the value_str from the left part }
         registers32:=left.registers32;
         registersfpu:=left.registersfpu;
- {$ifdef SUPPORT_MMX}
+{$ifdef SUPPORT_MMX}
         registersmmx:=left.registersmmx;
- {$endif}
+{$endif}
         location.loc:=left.location.loc;
 
         if nf_explizit in flags then
@@ -1488,25 +1541,7 @@ implementation
             make_not_regable(left);
          end;
 
-        if convtype=tc_equal then
-         begin
-           { remove typeconv node if left is a const. For other nodes we can't
-             remove it because the secondpass can still depend on the old type (PFV)
-             Conversions to float should also be left in the tree, because a float
-             is not possible in LOC_CONSTANT. The second_nothing routine will take
-             care of the conversion to LOC_REFERENCE }
-           if is_constnode(left) and
-              (resulttype.def.deftype<>floatdef) then
-            begin
-              left.resulttype:=resulttype;
-              result:=left;
-              left:=nil;
-            end;
-         end
-        else
-         begin
-           result:=first_call_helper(convtype);
-         end;
+        result:=first_call_helper(convtype);
       end;
 
 
@@ -1553,10 +1588,11 @@ implementation
                   tobjectdef(tclassrefdef(right.resulttype.def).pointertype.def)))) and
                   (not(tobjectdef(tclassrefdef(right.resulttype.def).pointertype.def).is_related(
                   tobjectdef(left.resulttype.def)))) then
-                 CGMessage(type_e_mismatch);
+                 CGMessage2(type_e_classes_not_related,left.resulttype.def.typename,
+                            tclassrefdef(right.resulttype.def).pointertype.def.typename);
              end
             else
-             CGMessage(type_e_mismatch);
+             CGMessage1(type_e_class_type_expected,left.resulttype.def.typename);
 
             { call fpc_do_is helper }
             paras := ccallparanode.create(
@@ -1575,7 +1611,7 @@ implementation
                { the operands must be related }
                if not(assigned(tobjectdef(left.resulttype.def).implementedinterfaces) and
                       (tobjectdef(left.resulttype.def).implementedinterfaces.searchintf(right.resulttype.def)<>-1)) then
-                 CGMessage(type_e_mismatch);
+                 CGMessage2(type_e_classes_not_related,left.resulttype.def.typename,right.resulttype.def.typename);
              end
             { left is an interface }
             else if is_interface(left.resulttype.def) then
@@ -1586,7 +1622,7 @@ implementation
                  CGMessage(type_e_mismatch);
              end
             else
-             CGMessage(type_e_mismatch);
+             CGMessage1(type_e_class_type_expected,left.resulttype.def.typename);
 
             { call fpc_do_is helper }
             paras := ccallparanode.create(
@@ -1598,7 +1634,7 @@ implementation
             right := nil;
           end
          else
-          CGMessage(type_e_mismatch);
+          CGMessage1(type_e_class_or_interface_type_expected,right.resulttype.def.typename);
 
          resulttype:=booltype;
       end;
@@ -1629,8 +1665,6 @@ implementation
 
 
     function tasnode.det_resulttype:tnode;
-      var
-        paras : tcallparanode;
       begin
          result:=nil;
          resulttypepass(right);
@@ -1652,19 +1686,12 @@ implementation
                   tobjectdef(tclassrefdef(right.resulttype.def).pointertype.def)))) and
                   (not(tobjectdef(tclassrefdef(right.resulttype.def).pointertype.def).is_related(
                   tobjectdef(left.resulttype.def)))) then
-                 CGMessage(type_e_mismatch);
+                 CGMessage2(type_e_classes_not_related,left.resulttype.def.typename,
+                            tclassrefdef(right.resulttype.def).pointertype.def.typename);
              end
             else
-             CGMessage(type_e_mismatch);
-
-            { call fpc_do_as helper }
-            paras := ccallparanode.create(
-                         left,
-                     ccallparanode.create(
-                         right,nil));
-            result := ccallnode.createinternres('fpc_do_as',paras,tclassrefdef(right.resulttype.def).pointertype);
-            left := nil;
-            right := nil;
+             CGMessage1(type_e_class_type_expected,left.resulttype.def.typename);
+            resulttype:=tclassrefdef(right.resulttype.def).pointertype;
           end
          else if is_interface(right.resulttype.def) then
           begin
@@ -1674,7 +1701,7 @@ implementation
                { the operands must be related }
                if not(assigned(tobjectdef(left.resulttype.def).implementedinterfaces) and
                       (tobjectdef(left.resulttype.def).implementedinterfaces.searchintf(right.resulttype.def)<>-1)) then
-                 CGMessage(type_e_mismatch);
+                 CGMessage2(type_e_classes_not_related,left.resulttype.def.typename,right.resulttype.def.typename);
              end
             { left is an interface }
             else if is_interface(left.resulttype.def) then
@@ -1682,39 +1709,29 @@ implementation
                { the operands must be related }
                if (not(tobjectdef(left.resulttype.def).is_related(tobjectdef(right.resulttype.def)))) and
                   (not(tobjectdef(right.resulttype.def).is_related(tobjectdef(left.resulttype.def)))) then
-                 CGMessage(type_e_mismatch);
+                 CGMessage2(type_e_classes_not_related,left.resulttype.def.typename,right.resulttype.def.typename);
              end
             else
-             CGMessage(type_e_mismatch);
-
-            { call fpc_do_as helper }
-            paras := ccallparanode.create(
-                         left,
-                     ccallparanode.create(
-                         right,nil));
-            result := ccallnode.createinternres('fpc_do_as',paras,right.resulttype);
-            left := nil;
-            right := nil;
+             CGMessage1(type_e_class_type_expected,left.resulttype.def.typename);
+            resulttype:=right.resulttype;
           end
          else
-          CGMessage(type_e_mismatch);
+          CGMessage1(type_e_class_or_interface_type_expected,right.resulttype.def.typename);
       end;
 
 
     function tasnode.pass_1 : tnode;
       begin
-        internalerror(200204252);
+        firstpass(left);
+        firstpass(right);
+        if codegenerror then
+         exit;
+        left_right_max;
+        location.loc:=left.location.loc;
         result:=nil;
       end;
 
 
-    { dummy pass_2, it will never be called, but we need one since }
-    { you can't instantiate an abstract class                      }
-    procedure tasnode.pass_2;
-      begin
-      end;
-
-
 begin
    ctypeconvnode:=ttypeconvnode;
    casnode:=tasnode;
@@ -1722,7 +1739,24 @@ begin
 end.
 {
   $Log$
-  Revision 1.54  2002-04-25 20:16:38  peter
+  Revision 1.55  2002-05-12 16:53:07  peter
+    * moved entry and exitcode to ncgutil and cgobj
+    * foreach gets extra argument for passing local data to the
+      iterator function
+    * -CR checks also class typecasts at runtime by changing them
+      into as
+    * fixed compiler to cycle with the -CR option
+    * fixed stabs with elf writer, finally the global variables can
+      be watched
+    * removed a lot of routines from cga unit and replaced them by
+      calls to cgobj
+    * u32bit-s32bit updates for and,or,xor nodes. When one element is
+      u32bit then the other is typecasted also to u32bit without giving
+      a rangecheck warning/error.
+    * fixed pascal calling method with reversing also the high tree in
+      the parast, detected by tcalcst3 test
+
+  Revision 1.54  2002/04/25 20:16:38  peter
     * moved more routines from cga/n386util
 
   Revision 1.53  2002/04/23 19:16:34  peter

+ 20 - 6
compiler/ncon.pas

@@ -297,11 +297,8 @@ implementation
             p1:=cpointerconstnode.create(p.valueordptr,p.consttype);
           constnil :
             p1:=cnilnode.create;
-          constresourcestring:
-            begin
-              p1:=cloadnode.create(tvarsym(p),tvarsym(p).owner);
-              p1.resulttype:=cansistringtype;
-            end;
+          else
+            internalerror(200205103);
         end;
         genconstsymtree:=p1;
       end;
@@ -724,7 +721,24 @@ begin
 end.
 {
   $Log$
-  Revision 1.28  2002-04-07 13:25:20  carl
+  Revision 1.29  2002-05-12 16:53:07  peter
+    * moved entry and exitcode to ncgutil and cgobj
+    * foreach gets extra argument for passing local data to the
+      iterator function
+    * -CR checks also class typecasts at runtime by changing them
+      into as
+    * fixed compiler to cycle with the -CR option
+    * fixed stabs with elf writer, finally the global variables can
+      be watched
+    * removed a lot of routines from cga unit and replaced them by
+      calls to cgobj
+    * u32bit-s32bit updates for and,or,xor nodes. When one element is
+      u32bit then the other is typecasted also to u32bit without giving
+      a rangecheck warning/error.
+    * fixed pascal calling method with reversing also the high tree in
+      the parast, detected by tcalcst3 test
+
+  Revision 1.28  2002/04/07 13:25:20  carl
   + change unit use
 
   Revision 1.27  2002/04/04 19:05:58  peter

+ 19 - 2
compiler/nflw.pas

@@ -498,7 +498,7 @@ implementation
          while (hp.nodetype=subscriptn) or
                ((hp.nodetype=vecn) and
                 is_constintnode(tvecnode(hp).right)) do
-          hp:=tsubscriptnode(hp).left;
+          hp:=tunarynode(hp).left;
          { we need a simple loadn, but the load must be in a global symtable or
            in the same lexlevel }
          if (hp.nodetype=funcretn) or
@@ -1113,7 +1113,24 @@ begin
 end.
 {
   $Log$
-  Revision 1.28  2002-03-31 20:26:34  jonas
+  Revision 1.29  2002-05-12 16:53:07  peter
+    * moved entry and exitcode to ncgutil and cgobj
+    * foreach gets extra argument for passing local data to the
+      iterator function
+    * -CR checks also class typecasts at runtime by changing them
+      into as
+    * fixed compiler to cycle with the -CR option
+    * fixed stabs with elf writer, finally the global variables can
+      be watched
+    * removed a lot of routines from cga unit and replaced them by
+      calls to cgobj
+    * u32bit-s32bit updates for and,or,xor nodes. When one element is
+      u32bit then the other is typecasted also to u32bit without giving
+      a rangecheck warning/error.
+    * fixed pascal calling method with reversing also the high tree in
+      the parast, detected by tcalcst3 test
+
+  Revision 1.28  2002/03/31 20:26:34  jonas
     + a_loadfpu_* and a_loadmm_* methods in tcg
     * register allocation is now handled by a class and is mostly processor
       independent (+rgobj.pas and i386/rgcpu.pas)

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 192 - 286
compiler/ninl.pas


+ 22 - 6
compiler/nld.pas

@@ -530,11 +530,10 @@ implementation
         { call helpers for interface }
         if is_interfacecom(left.resulttype.def) then
          begin
-           hp:=ccallparanode.create
-                   (right,
-               ccallparanode.create(caddrnode.create
-                   (left),nil));
-           hp:=ccallparanode.create(right,nil);
+           hp:=ccallparanode.create(ctypeconvnode.create_explicit
+                   (right,voidpointertype),
+               ccallparanode.create(ctypeconvnode.create_explicit
+                   (left,voidpointertype),nil));
            result:=ccallnode.createintern('fpc_intf_assign',hp);
            left:=nil;
            right:=nil;
@@ -956,7 +955,24 @@ begin
 end.
 {
   $Log$
-  Revision 1.38  2002-04-25 20:16:39  peter
+  Revision 1.39  2002-05-12 16:53:07  peter
+    * moved entry and exitcode to ncgutil and cgobj
+    * foreach gets extra argument for passing local data to the
+      iterator function
+    * -CR checks also class typecasts at runtime by changing them
+      into as
+    * fixed compiler to cycle with the -CR option
+    * fixed stabs with elf writer, finally the global variables can
+      be watched
+    * removed a lot of routines from cga unit and replaced them by
+      calls to cgobj
+    * u32bit-s32bit updates for and,or,xor nodes. When one element is
+      u32bit then the other is typecasted also to u32bit without giving
+      a rangecheck warning/error.
+    * fixed pascal calling method with reversing also the high tree in
+      the parast, detected by tcalcst3 test
+
+  Revision 1.38  2002/04/25 20:16:39  peter
     * moved more routines from cga/n386util
 
   Revision 1.37  2002/04/23 19:16:34  peter

+ 28 - 10
compiler/nmem.pas

@@ -94,8 +94,8 @@ interface
        tvecnodeclass = class of tvecnode;
 
        tselfnode = class(tnode)
-          classdef : tobjectdef;
-          constructor create(_class : tobjectdef);virtual;
+          classdef : tdef; { objectdef or classrefdef }
+          constructor create(_class : tdef);virtual;
           function pass_1 : tnode;override;
           function det_resulttype:tnode;override;
        end;
@@ -748,7 +748,7 @@ implementation
                                TSELFNODE
 *****************************************************************************}
 
-    constructor tselfnode.create(_class : tobjectdef);
+    constructor tselfnode.create(_class : tdef);
 
       begin
          inherited create(selfn);
@@ -789,6 +789,7 @@ implementation
 
     destructor twithnode.destroy;
       var
+        hsymt,
         symt : tsymtable;
         i    : longint;
       begin
@@ -797,10 +798,10 @@ implementation
          begin
            if assigned(symt) then
             begin
-              withsymtable:=twithsymtable(symt.next);
+              hsymt:=symt.next;
               symt.free;
+              symt:=hsymt;
             end;
-           symt:=withsymtable;
          end;
         inherited destroy;
       end;
@@ -821,7 +822,7 @@ implementation
 
     function twithnode.det_resulttype:tnode;
       var
-         symtable : twithsymtable;
+         symtable : tsymtable;
          i : longint;
       begin
          result:=nil;
@@ -839,9 +840,9 @@ implementation
              begin
                if (left.nodetype=loadn) and
                   (tloadnode(left).symtable=aktprocdef.localst) then
-                symtable.direct_with:=true;
-               symtable.withnode:=self;
-               symtable:=twithsymtable(symtable.next);
+                twithsymtable(symtable).direct_with:=true;
+               twithsymtable(symtable).withnode:=self;
+               symtable:=symtable.next;
              end;
 
             resulttypepass(right);
@@ -893,7 +894,24 @@ begin
 end.
 {
   $Log$
-  Revision 1.29  2002-04-21 19:02:04  peter
+  Revision 1.30  2002-05-12 16:53:07  peter
+    * moved entry and exitcode to ncgutil and cgobj
+    * foreach gets extra argument for passing local data to the
+      iterator function
+    * -CR checks also class typecasts at runtime by changing them
+      into as
+    * fixed compiler to cycle with the -CR option
+    * fixed stabs with elf writer, finally the global variables can
+      be watched
+    * removed a lot of routines from cga unit and replaced them by
+      calls to cgobj
+    * u32bit-s32bit updates for and,or,xor nodes. When one element is
+      u32bit then the other is typecasted also to u32bit without giving
+      a rangecheck warning/error.
+    * fixed pascal calling method with reversing also the high tree in
+      the parast, detected by tcalcst3 test
+
+  Revision 1.29  2002/04/21 19:02:04  peter
     * removed newn and disposen nodes, the code is now directly
       inlined from pexpr
     * -an option that will write the secondpass nodes to the .s file, this

+ 36 - 20
compiler/nobj.pas

@@ -61,8 +61,8 @@ interface
         { message tables }
         root : pprocdeftree;
         procedure disposeprocdeftree(p : pprocdeftree);
-        procedure insertmsgint(p : tnamedindexitem);
-        procedure insertmsgstr(p : tnamedindexitem);
+        procedure insertmsgint(p : tnamedindexitem;arg:pointer);
+        procedure insertmsgstr(p : tnamedindexitem;arg:pointer);
         procedure insertint(p : pprocdeftree;var at : pprocdeftree);
         procedure insertstr(p : pprocdeftree;var at : pprocdeftree);
         procedure writenames(p : pprocdeftree);
@@ -71,21 +71,21 @@ interface
 {$ifdef WITHDMT}
       private
         { dmt }
-        procedure insertdmtentry(p : tnamedindexitem);
+        procedure insertdmtentry(p : tnamedindexitem;arg:pointer);
         procedure writedmtindexentry(p : pprocdeftree);
         procedure writedmtaddressentry(p : pprocdeftree);
 {$endif}
       private
         { published methods }
-        procedure do_count(p : tnamedindexitem);
-        procedure genpubmethodtableentry(p : tnamedindexitem);
+        procedure do_count(p : tnamedindexitem;arg:pointer);
+        procedure genpubmethodtableentry(p : tnamedindexitem;arg:pointer);
       private
         { vmt }
         wurzel : psymcoll;
         nextvirtnumber : integer;
         has_constructor,
         has_virtual_method : boolean;
-        procedure eachsym(sym : tnamedindexitem);
+        procedure eachsym(sym : tnamedindexitem;arg:pointer);
         procedure disposevmttree;
         procedure writevirtualmethods(List:TAAsmoutput);
       private
@@ -136,11 +136,10 @@ implementation
 {$endif}
        globtype,globals,verbose,
        symtable,symconst,symtype,symsym,types,
-       fmodule,
 {$ifdef GDB}
        gdb,
 {$endif GDB}
-       cpuinfo,cpubase
+       cpuinfo
        ;
 
 
@@ -217,7 +216,7 @@ implementation
            end;
       end;
 
-    procedure tclassheader.insertmsgint(p : tnamedindexitem);
+    procedure tclassheader.insertmsgint(p : tnamedindexitem;arg:pointer);
 
       var
          hp : pprocdeflist;
@@ -241,7 +240,7 @@ implementation
            end;
       end;
 
-    procedure tclassheader.insertmsgstr(p : tnamedindexitem);
+    procedure tclassheader.insertmsgstr(p : tnamedindexitem;arg:pointer);
 
       var
          hp : pprocdeflist;
@@ -301,7 +300,7 @@ implementation
          root:=nil;
          count:=0;
          { insert all message handlers into a tree, sorted by name }
-         _class.symtable.foreach({$ifdef FPCPROCVAR}@{$endif}insertmsgstr);
+         _class.symtable.foreach({$ifdef FPCPROCVAR}@{$endif}insertmsgstr,nil);
 
          { write all names }
          if assigned(root) then
@@ -341,7 +340,7 @@ implementation
          root:=nil;
          count:=0;
          { insert all message handlers into a tree, sorted by name }
-         _class.symtable.foreach({$ifdef FPCPROCVAR}@{$endif}insertmsgint);
+         _class.symtable.foreach({$ifdef FPCPROCVAR}@{$endif}insertmsgint,nil);
 
          { now start writing of the message string table }
          getdatalabel(r);
@@ -361,7 +360,7 @@ implementation
               DMT
 **************************************}
 
-    procedure tclassheader.insertdmtentry(p : tnamedindexitem);
+    procedure tclassheader.insertdmtentry(p : tnamedindexitem;arg:pointer);
 
       var
          hp : tprocdef;
@@ -443,14 +442,14 @@ implementation
         Published Methods
 **************************************}
 
-    procedure tclassheader.do_count(p : tnamedindexitem);
+    procedure tclassheader.do_count(p : tnamedindexitem;arg:pointer);
 
       begin
          if (tsym(p).typ=procsym) and (sp_published in tsym(p).symoptions) then
            inc(count);
       end;
 
-    procedure tclassheader.genpubmethodtableentry(p : tnamedindexitem);
+    procedure tclassheader.genpubmethodtableentry(p : tnamedindexitem;arg:pointer);
 
       var
          hp : tprocdef;
@@ -480,13 +479,13 @@ implementation
 
       begin
          count:=0;
-         _class.symtable.foreach({$ifdef FPCPROCVAR}@{$endif}do_count);
+         _class.symtable.foreach({$ifdef FPCPROCVAR}@{$endif}do_count,nil);
          if count>0 then
            begin
               getdatalabel(l);
               dataSegment.concat(Tai_label.Create(l));
               dataSegment.concat(Tai_const.Create_32bit(count));
-              _class.symtable.foreach({$ifdef FPCPROCVAR}@{$endif}genpubmethodtableentry);
+              _class.symtable.foreach({$ifdef FPCPROCVAR}@{$endif}genpubmethodtableentry,nil);
               genpublishedmethodstable:=l;
            end
          else
@@ -498,7 +497,7 @@ implementation
                VMT
 **************************************}
 
-    procedure tclassheader.eachsym(sym : tnamedindexitem);
+    procedure tclassheader.eachsym(sym : tnamedindexitem;arg:pointer);
 
       var
          procdefcoll : pprocdefcoll;
@@ -746,7 +745,7 @@ implementation
              do_genvmt(p.childof);
 
            { walk through all public syms }
-           p.symtable.foreach({$ifdef FPCPROCVAR}@{$endif}eachsym);
+           p.symtable.foreach({$ifdef FPCPROCVAR}@{$endif}eachsym,nil);
         end;
 
       begin
@@ -1270,7 +1269,24 @@ initialization
 end.
 {
   $Log$
-  Revision 1.16  2002-04-20 21:32:24  carl
+  Revision 1.17  2002-05-12 16:53:08  peter
+    * moved entry and exitcode to ncgutil and cgobj
+    * foreach gets extra argument for passing local data to the
+      iterator function
+    * -CR checks also class typecasts at runtime by changing them
+      into as
+    * fixed compiler to cycle with the -CR option
+    * fixed stabs with elf writer, finally the global variables can
+      be watched
+    * removed a lot of routines from cga unit and replaced them by
+      calls to cgobj
+    * u32bit-s32bit updates for and,or,xor nodes. When one element is
+      u32bit then the other is typecasted also to u32bit without giving
+      a rangecheck warning/error.
+    * fixed pascal calling method with reversing also the high tree in
+      the parast, detected by tcalcst3 test
+
+  Revision 1.16  2002/04/20 21:32:24  carl
   + generic FPC_CHECKPOINTER
   + first parameter offset in stack now portable
   * rename some constants

+ 19 - 2
compiler/nset.pas

@@ -221,7 +221,7 @@ implementation
          { Convert array constructor first to set }
          if is_array_constructor(right.resulttype.def) then
           begin
-            arrayconstructor_to_set(tarrayconstructornode(right));
+            arrayconstructor_to_set(right);
             firstpass(right);
             if codegenerror then
              exit;
@@ -574,7 +574,24 @@ begin
 end.
 {
   $Log$
-  Revision 1.20  2002-04-07 13:27:50  carl
+  Revision 1.21  2002-05-12 16:53:08  peter
+    * moved entry and exitcode to ncgutil and cgobj
+    * foreach gets extra argument for passing local data to the
+      iterator function
+    * -CR checks also class typecasts at runtime by changing them
+      into as
+    * fixed compiler to cycle with the -CR option
+    * fixed stabs with elf writer, finally the global variables can
+      be watched
+    * removed a lot of routines from cga unit and replaced them by
+      calls to cgobj
+    * u32bit-s32bit updates for and,or,xor nodes. When one element is
+      u32bit then the other is typecasted also to u32bit without giving
+      a rangecheck warning/error.
+    * fixed pascal calling method with reversing also the high tree in
+      the parast, detected by tcalcst3 test
+
+  Revision 1.20  2002/04/07 13:27:50  carl
   + change unit use
 
   Revision 1.19  2002/04/02 17:11:29  peter

+ 22 - 17
compiler/ogelf.pas

@@ -425,17 +425,15 @@ implementation
     procedure telf32data.writestabs(section:tsection;offset:longint;p:pchar;nidx,nother,line:longint;reloc : boolean);
       var
         stab : telf32stab;
-        s : tsection;
       begin
-        s:=section;
         if reloc then
          begin
            if (offset=-1) then
             begin
-              if s=sec_none then
+              if section=sec_none then
                offset:=0
               else
-               offset:=sects[s].datasize;
+               offset:=sects[section].datasize;
             end;
          end;
         fillchar(stab,sizeof(telf32stab),0);
@@ -452,7 +450,7 @@ implementation
         { when the offset is not 0 then write a relocation, take also the
           hdrstab into account with the offset }
         if reloc then
-         sects[sec_stab].addsectionreloc(sects[sec_stab].datasize-4,s,relative_false);
+         sects[sec_stab].addsectionreloc(sects[sec_stab].datasize-4,section,relative_false);
       end;
 
 
@@ -461,16 +459,6 @@ implementation
       var
         stab : telf32stab;
       begin
-        if reloc then
-         begin
-           if (offset=-1) then
-            begin
-              if section=sec_none then
-               offset:=0
-              else
-               offset:=sects[section].datasize;
-            end;
-         end;
         fillchar(stab,sizeof(telf32stab),0);
         if assigned(p) and (p[0]<>#0) then
          begin
@@ -480,7 +468,7 @@ implementation
         stab.ntype:=nidx;
         stab.ndesc:=line;
         stab.nother:=nother;
-        stab.nvalue:=offset;
+        stab.nvalue:=0;
         sects[sec_stab].write(stab,sizeof(stab));
         { when the offset is not 0 then write a relocation, take also the
           hdrstab into account with the offset }
@@ -886,7 +874,24 @@ initialization
 end.
 {
   $Log$
-  Revision 1.11  2002-04-04 19:05:58  peter
+  Revision 1.12  2002-05-12 16:53:08  peter
+    * moved entry and exitcode to ncgutil and cgobj
+    * foreach gets extra argument for passing local data to the
+      iterator function
+    * -CR checks also class typecasts at runtime by changing them
+      into as
+    * fixed compiler to cycle with the -CR option
+    * fixed stabs with elf writer, finally the global variables can
+      be watched
+    * removed a lot of routines from cga unit and replaced them by
+      calls to cgobj
+    * u32bit-s32bit updates for and,or,xor nodes. When one element is
+      u32bit then the other is typecasted also to u32bit without giving
+      a rangecheck warning/error.
+    * fixed pascal calling method with reversing also the high tree in
+      the parast, detected by tcalcst3 test
+
+  Revision 1.11  2002/04/04 19:05:58  peter
     * removed unused units
     * use tlocation.size in cg.a_*loc*() routines
 

+ 26 - 3
compiler/options.pas

@@ -466,9 +466,15 @@ begin
                                 include(initlocalswitches,cs_check_range);
                             'R' :
                               If UnsetBool(More, j) then
-                                exclude(initlocalswitches,cs_check_object_ext)
+                                begin
+                                  exclude(initlocalswitches,cs_check_range);
+                                  exclude(initlocalswitches,cs_check_object);
+                                end
                               Else
-                                include(initlocalswitches,cs_check_object_ext);
+                                begin
+                                  include(initlocalswitches,cs_check_range);
+                                  include(initlocalswitches,cs_check_object);
+                                end;
                             's' :
                               begin
                                  val(copy(more,j+1,length(more)-j),stacksize,code);
@@ -1658,7 +1664,24 @@ finalization
 end.
 {
   $Log$
-  Revision 1.69  2002-04-21 19:02:04  peter
+  Revision 1.70  2002-05-12 16:53:08  peter
+    * moved entry and exitcode to ncgutil and cgobj
+    * foreach gets extra argument for passing local data to the
+      iterator function
+    * -CR checks also class typecasts at runtime by changing them
+      into as
+    * fixed compiler to cycle with the -CR option
+    * fixed stabs with elf writer, finally the global variables can
+      be watched
+    * removed a lot of routines from cga unit and replaced them by
+      calls to cgobj
+    * u32bit-s32bit updates for and,or,xor nodes. When one element is
+      u32bit then the other is typecasted also to u32bit without giving
+      a rangecheck warning/error.
+    * fixed pascal calling method with reversing also the high tree in
+      the parast, detected by tcalcst3 test
+
+  Revision 1.69  2002/04/21 19:02:04  peter
     * removed newn and disposen nodes, the code is now directly
       inlined from pexpr
     * -an option that will write the secondpass nodes to the .s file, this

+ 21 - 4
compiler/pass_2.pas

@@ -226,7 +226,7 @@ implementation
          do_secondpass:=codegenerror;
       end;
 
-    procedure clearrefs(p : tnamedindexitem);
+    procedure clearrefs(p : tnamedindexitem;arg:pointer);
 
       begin
          if (tsym(p).typ=varsym) then
@@ -247,8 +247,8 @@ implementation
          { clear register count }
          rg.clearregistercount;
          use_esp_stackframe:=false;
-         symtablestack.foreach_static({$ifdef FPCPROCVAR}@{$endif}clearrefs);
-         symtablestack.next.foreach_static({$ifdef FPCPROCVAR}@{$endif}clearrefs);
+         symtablestack.foreach_static({$ifdef FPCPROCVAR}@{$endif}clearrefs,nil);
+         symtablestack.next.foreach_static({$ifdef FPCPROCVAR}@{$endif}clearrefs,nil);
          { firstpass everything }
          do_firstpass(p);
          { only do secondpass if there are no errors }
@@ -321,7 +321,24 @@ implementation
 end.
 {
   $Log$
-  Revision 1.26  2002-04-21 19:02:04  peter
+  Revision 1.27  2002-05-12 16:53:08  peter
+    * moved entry and exitcode to ncgutil and cgobj
+    * foreach gets extra argument for passing local data to the
+      iterator function
+    * -CR checks also class typecasts at runtime by changing them
+      into as
+    * fixed compiler to cycle with the -CR option
+    * fixed stabs with elf writer, finally the global variables can
+      be watched
+    * removed a lot of routines from cga unit and replaced them by
+      calls to cgobj
+    * u32bit-s32bit updates for and,or,xor nodes. When one element is
+      u32bit then the other is typecasted also to u32bit without giving
+      a rangecheck warning/error.
+    * fixed pascal calling method with reversing also the high tree in
+      the parast, detected by tcalcst3 test
+
+  Revision 1.26  2002/04/21 19:02:04  peter
     * removed newn and disposen nodes, the code is now directly
       inlined from pexpr
     * -an option that will write the secondpass nodes to the .s file, this

+ 22 - 5
compiler/pdecl.pas

@@ -268,7 +268,7 @@ implementation
 
 
     { search in symtablestack used, but not defined type }
-    procedure resolve_type_forward(p : tnamedindexitem);
+    procedure resolve_type_forward(p : tnamedindexitem;arg:pointer);
       var
         hpd,pd : tdef;
         stpos  : tfileposinfo;
@@ -347,7 +347,7 @@ implementation
                   end;
                end;
              recorddef :
-               trecorddef(pd).symtable.foreach_static({$ifdef FPCPROCVAR}@{$endif}resolve_type_forward);
+               trecorddef(pd).symtable.foreach_static({$ifdef FPCPROCVAR}@{$endif}resolve_type_forward,nil);
              objectdef :
                begin
                  if not(m_fpc in aktmodeswitches) and
@@ -363,7 +363,7 @@ implementation
                       check objectdefs in objects/records, because these
                       can't exist (anonymous objects aren't allowed) }
                     if not(tsym(p).owner.symtabletype in [objectsymtable,recordsymtable]) then
-                     tobjectdef(pd).symtable.foreach_static({$ifdef FPCPROCVAR}@{$endif}resolve_type_forward);
+                     tobjectdef(pd).symtable.foreach_static({$ifdef FPCPROCVAR}@{$endif}resolve_type_forward,nil);
                   end;
                end;
           end;
@@ -524,7 +524,7 @@ implementation
             end;
          until token<>_ID;
          typecanbeforward:=false;
-         symtablestack.foreach_static({$ifdef FPCPROCVAR}@{$endif}resolve_type_forward);
+         symtablestack.foreach_static({$ifdef FPCPROCVAR}@{$endif}resolve_type_forward,nil);
          block_type:=old_block_type;
       end;
 
@@ -608,7 +608,24 @@ implementation
 end.
 {
   $Log$
-  Revision 1.42  2002-04-19 15:46:02  peter
+  Revision 1.43  2002-05-12 16:53:08  peter
+    * moved entry and exitcode to ncgutil and cgobj
+    * foreach gets extra argument for passing local data to the
+      iterator function
+    * -CR checks also class typecasts at runtime by changing them
+      into as
+    * fixed compiler to cycle with the -CR option
+    * fixed stabs with elf writer, finally the global variables can
+      be watched
+    * removed a lot of routines from cga unit and replaced them by
+      calls to cgobj
+    * u32bit-s32bit updates for and,or,xor nodes. When one element is
+      u32bit then the other is typecasted also to u32bit without giving
+      a rangecheck warning/error.
+    * fixed pascal calling method with reversing also the high tree in
+      the parast, detected by tcalcst3 test
+
+  Revision 1.42  2002/04/19 15:46:02  peter
     * mangledname rewrite, tprocdef.mangledname is now created dynamicly
       in most cases and not written to the ppu
     * add mangeledname_prefix() routine to generate the prefix of

+ 19 - 2
compiler/pdecobj.pas

@@ -516,7 +516,7 @@ implementation
                      if (p.proptype.def.deftype=setdef) and
                         (pt.nodetype=arrayconstructorn) then
                        begin
-                         arrayconstructor_to_set(tarrayconstructornode(pt));
+                         arrayconstructor_to_set(pt);
                          do_resulttypepass(pt);
                        end;
                      inserttypeconv(pt,p.proptype);
@@ -1111,7 +1111,24 @@ implementation
 end.
 {
   $Log$
-  Revision 1.41  2002-04-21 19:02:04  peter
+  Revision 1.42  2002-05-12 16:53:08  peter
+    * moved entry and exitcode to ncgutil and cgobj
+    * foreach gets extra argument for passing local data to the
+      iterator function
+    * -CR checks also class typecasts at runtime by changing them
+      into as
+    * fixed compiler to cycle with the -CR option
+    * fixed stabs with elf writer, finally the global variables can
+      be watched
+    * removed a lot of routines from cga unit and replaced them by
+      calls to cgobj
+    * u32bit-s32bit updates for and,or,xor nodes. When one element is
+      u32bit then the other is typecasted also to u32bit without giving
+      a rangecheck warning/error.
+    * fixed pascal calling method with reversing also the high tree in
+      the parast, detected by tcalcst3 test
+
+  Revision 1.41  2002/04/21 19:02:04  peter
     * removed newn and disposen nodes, the code is now directly
       inlined from pexpr
     * -an option that will write the secondpass nodes to the .s file, this

+ 50 - 14
compiler/pdecsub.pas

@@ -85,7 +85,7 @@ implementation
        ;
 
 
-    procedure resetvaluepara(p:tnamedindexitem);
+    procedure resetvaluepara(p:tnamedindexitem;arg:pointer);
       begin
         if tsym(p).typ=varsym then
          with tvarsym(p) do
@@ -1464,7 +1464,8 @@ const
     procedure handle_calling_convention(sym:tprocsym;def:tabstractprocdef);
       var
         st,parast : tsymtable;
-        lastps,ps : tsym;
+        lastps,
+        highps,ps : tsym;
       begin
       { set the default calling convention }
         if def.proccalloption=pocall_none then
@@ -1483,7 +1484,7 @@ const
                  if not assigned(tprocdef(def).parast) then
                   internalerror(200110234);
                  { do not copy on local !! }
-                 tprocdef(def).parast.foreach_static({$ifdef FPCPROCVAR}@{$endif}resetvaluepara);
+                 tprocdef(def).parast.foreach_static({$ifdef FPCPROCVAR}@{$endif}resetvaluepara,nil);
                  { Adjust positions of args for cdecl or stdcall }
                  tparasymtable(tprocdef(def).parast).set_alignment(std_param_align);
                end;
@@ -1503,7 +1504,7 @@ const
                  if not assigned(tprocdef(def).parast) then
                   internalerror(200110235);
                  { do not copy on local !! }
-                 tprocdef(def).parast.foreach_static({$ifdef FPCPROCVAR}@{$endif}resetvaluepara);
+                 tprocdef(def).parast.foreach_static({$ifdef FPCPROCVAR}@{$endif}resetvaluepara,nil);
                  { Adjust positions of args for cdecl or stdcall }
                  tparasymtable(tprocdef(def).parast).set_alignment(std_param_align);
                end;
@@ -1532,25 +1533,43 @@ const
           pocall_pascal :
             begin
               include(def.procoptions,po_leftright);
-              st:=tparasymtable.create;
               if def.deftype=procdef then
                begin
+                 st:=tparasymtable.create;
+                 st.symindex.noclear:=true;
                  parast:=tprocdef(def).parast;
+                 highps:=nil;
                  lastps:=nil;
                  while assigned(parast.symindex.first) and (lastps<>tsym(parast.symindex.first)) do
                   begin
                     ps:=tsym(parast.symindex.first);
                     while assigned(ps.indexnext) and (tsym(ps.indexnext)<>lastps) do
                       ps:=tsym(ps.indexnext);
-                    ps.owner:=st;
-                    { recalculate the corrected offset }
-                    { the really_insert_in_data procedure
-                      for parasymtable should only calculateoffset PM }
-                    tstoredsym(ps).insert_in_data;
-                    { reset the owner correctly }
-                    ps.owner:=parast;
+                    { Wait with inserting the high value, it needs to be inserted
+                      after the corresponding parameter }
+                    if Copy(ps.name,1,4)='high' then
+                     highps:=ps
+                    else
+                     begin
+                       { recalculate the corrected offset by inserting it into
+                         the new symtable and then reset the owner back }
+                       ps.owner:=st;
+                       tstoredsym(ps).insert_in_data;
+                       ps.owner:=parast;
+                       { add also the high tree if it was saved }
+                       if assigned(highps) then
+                        begin
+                          highps.owner:=st;
+                          tstoredsym(highps).insert_in_data;
+                          highps.owner:=parast;
+                          highps:=nil;
+                        end;
+                     end;
                     lastps:=ps;
                   end;
+                 st.free;
+                 if assigned(highps) then
+                  internalerror(200205111);
                end;
             end;
           pocall_register :
@@ -1581,7 +1600,7 @@ const
                  if not assigned(tprocdef(def).parast) then
                   internalerror(200110236);
                  { do not copy on local !! }
-                 tprocdef(def).parast.foreach_static({$ifdef FPCPROCVAR}@{$endif}resetvaluepara);
+                 tprocdef(def).parast.foreach_static({$ifdef FPCPROCVAR}@{$endif}resetvaluepara,nil);
                  { Adjust positions of args for cdecl or stdcall }
                  tparasymtable(tprocdef(def).parast).set_alignment(std_param_align);
                end;
@@ -1938,7 +1957,24 @@ const
 end.
 {
   $Log$
-  Revision 1.53  2002-04-21 19:02:04  peter
+  Revision 1.54  2002-05-12 16:53:08  peter
+    * moved entry and exitcode to ncgutil and cgobj
+    * foreach gets extra argument for passing local data to the
+      iterator function
+    * -CR checks also class typecasts at runtime by changing them
+      into as
+    * fixed compiler to cycle with the -CR option
+    * fixed stabs with elf writer, finally the global variables can
+      be watched
+    * removed a lot of routines from cga unit and replaced them by
+      calls to cgobj
+    * u32bit-s32bit updates for and,or,xor nodes. When one element is
+      u32bit then the other is typecasted also to u32bit without giving
+      a rangecheck warning/error.
+    * fixed pascal calling method with reversing also the high tree in
+      the parast, detected by tcalcst3 test
+
+  Revision 1.53  2002/04/21 19:02:04  peter
     * removed newn and disposen nodes, the code is now directly
       inlined from pexpr
     * -an option that will write the secondpass nodes to the .s file, this

+ 35 - 18
compiler/pexpr.pas

@@ -715,12 +715,12 @@ implementation
                      subscriptn. If no tree is found (with block), then
                      generate a loadn }
                    if assigned(p1) then
-                    p1:=csubscriptnode.create(tvarsym(plist^.sym),p1)
+                    p1:=csubscriptnode.create(plist^.sym,p1)
                    else
-                    p1:=cloadnode.create(tvarsym(plist^.sym),st);
+                    p1:=cloadnode.create(plist^.sym,st);
                  end;
                sl_subscript :
-                 p1:=csubscriptnode.create(tvarsym(plist^.sym),p1);
+                 p1:=csubscriptnode.create(plist^.sym,p1);
                sl_vec :
                  p1:=cvecnode.create(p1,cordconstnode.create(plist^.value,s32bittype));
                else
@@ -903,10 +903,10 @@ implementation
                            static_name:=lower(sym.owner.name^)+'_'+sym.name;
                            searchsym(static_name,sym,srsymtable);
                            p1.free;
-                           p1:=cloadnode.create(tvarsym(sym),srsymtable);
+                           p1:=cloadnode.create(sym,srsymtable);
                         end
                       else
-                        p1:=csubscriptnode.create(tvarsym(sym),p1);
+                        p1:=csubscriptnode.create(sym,p1);
                    end;
                  propertysym:
                    begin
@@ -948,17 +948,17 @@ implementation
                { is this an access to a function result? Accessing _RESULT is
                  always allowed and funcretn is generated }
                if assigned(p^.procdef.funcretsym) and
-                  ((tfuncretsym(sym)=p^.procdef.resultfuncretsym) or
-                   ((tfuncretsym(sym)=p^.procdef.funcretsym) or
-                    ((tvarsym(sym)=otsym) and ((p^.flags and pi_operator)<>0))) and
+                  ((sym=tsym(p^.procdef.resultfuncretsym)) or
+                   ((sym=tsym(p^.procdef.funcretsym)) or
+                    ((sym=tsym(otsym)) and ((p^.flags and pi_operator)<>0))) and
                    (not is_void(p^.procdef.rettype.def)) and
                    (token<>_LKLAMMER) and
                    (not (not(m_fpc in aktmodeswitches) and (afterassignment or in_args)))
                   ) then
                  begin
-                    if ((tvarsym(sym)=otsym) and
+                    if ((sym=tsym(otsym)) and
                        ((p^.flags and pi_operator)<>0)) then
-                       inc(otsym.refs);
+                      inc(otsym.refs);
                     p1:=cfuncretnode.create(p^.procdef.funcretsym);
                     is_func_ret:=true;
                     if tfuncretsym(p^.procdef.funcretsym).funcretstate=vs_declared then
@@ -1016,7 +1016,7 @@ implementation
               case srsym.typ of
                 absolutesym :
                   begin
-                    p1:=cloadnode.create(tvarsym(srsym),srsymtable);
+                    p1:=cloadnode.create(srsym,srsymtable);
                   end;
 
                 varsym :
@@ -1031,7 +1031,7 @@ implementation
                        static_name:=lower(srsym.owner.name^)+'_'+srsym.name;
                        searchsym(static_name,srsym,srsymtable);
                      end;
-                    p1:=cloadnode.create(tvarsym(srsym),srsymtable);
+                    p1:=cloadnode.create(srsym,srsymtable);
                     if tvarsym(srsym).varstate=vs_declared then
                      begin
                        include(p1.flags,nf_first);
@@ -1097,7 +1097,7 @@ implementation
                               p1:=ctypenode.create(htype);
                               { TP allows also @TMenu.Load if Load is only }
                               { defined in an anchestor class              }
-                              srsym:=tvarsym(search_class_member(tobjectdef(htype.def),pattern));
+                              srsym:=search_class_member(tobjectdef(htype.def),pattern);
                               if not assigned(srsym) then
                                Message1(sym_e_id_no_member,pattern)
                               else if not(getaddr) and not(sp_static in srsym.symoptions) then
@@ -1122,7 +1122,7 @@ implementation
                                 p1:=ctypenode.create(htype);
                                 { TP allows also @TMenu.Load if Load is only }
                                 { defined in an anchestor class              }
-                                srsym:=tvarsym(search_class_member(tobjectdef(htype.def),pattern));
+                                srsym:=search_class_member(tobjectdef(htype.def),pattern);
                                 if not assigned(srsym) then
                                  Message1(sym_e_id_no_member,pattern)
                                 else
@@ -1193,7 +1193,7 @@ implementation
                         p1:=cnilnode.create;
                       constresourcestring:
                         begin
-                          p1:=cloadnode.create(tvarsym(srsym),srsymtable);
+                          p1:=cloadnode.create(srsym,srsymtable);
                           do_resulttypepass(p1);
                           p1.resulttype:=cansistringtype;
                         end;
@@ -1499,7 +1499,7 @@ implementation
                             hsym:=tsym(trecorddef(p1.resulttype.def).symtable.search(pattern));
                             if assigned(hsym) and
                                (hsym.typ=varsym) then
-                              p1:=csubscriptnode.create(tvarsym(hsym),p1)
+                              p1:=csubscriptnode.create(hsym,p1)
                             else
                               begin
                                 Message1(sym_e_illegal_field,pattern);
@@ -1687,7 +1687,7 @@ implementation
                    begin
                      { self in class methods is a class reference type }
                      htype.setdef(procinfo^._class);
-                     p1:=cselfnode.create(tobjectdef(tclassrefdef.create(htype)));
+                     p1:=cselfnode.create(tclassrefdef.create(htype));
                    end
                   else
                    p1:=cselfnode.create(procinfo^._class);
@@ -2224,7 +2224,24 @@ implementation
 end.
 {
   $Log$
-  Revision 1.64  2002-04-23 19:16:34  peter
+  Revision 1.65  2002-05-12 16:53:09  peter
+    * moved entry and exitcode to ncgutil and cgobj
+    * foreach gets extra argument for passing local data to the
+      iterator function
+    * -CR checks also class typecasts at runtime by changing them
+      into as
+    * fixed compiler to cycle with the -CR option
+    * fixed stabs with elf writer, finally the global variables can
+      be watched
+    * removed a lot of routines from cga unit and replaced them by
+      calls to cgobj
+    * u32bit-s32bit updates for and,or,xor nodes. When one element is
+      u32bit then the other is typecasted also to u32bit without giving
+      a rangecheck warning/error.
+    * fixed pascal calling method with reversing also the high tree in
+      the parast, detected by tcalcst3 test
+
+  Revision 1.64  2002/04/23 19:16:34  peter
     * add pinline unit that inserts compiler supported functions using
       one or more statements
     * moved finalize and setlength from ninl to pinline

+ 11 - 162
compiler/pinline.pas

@@ -1,6 +1,6 @@
 {
     $Id$
-    Copyright (c) 1998-2002 by Florian Klaempfl
+    Copyright (c) 1998-2001 by Florian Klaempfl
 
     Generates nodes for routines that need compiler support
 
@@ -22,7 +22,7 @@
 }
 unit pinline;
 
-{$i fpcdefs.inc}
+{$i defines.inc}
 
 interface
 
@@ -37,7 +37,6 @@ interface
 
     function inline_setlength : tnode;
     function inline_finalize : tnode;
-    function inline_copy : tnode;
 
 
 implementation
@@ -52,7 +51,7 @@ implementation
        globtype,tokens,verbose,
        systems,
        { symtable }
-       symconst,symdef,symsym,symtable,defutil,
+       symconst,symdef,symsym,symtable,types,
        { pass 1 }
        pass_1,htypechk,
        nmat,nadd,ncal,nmem,nset,ncnv,ninl,ncon,nld,nflw,nbas,
@@ -170,15 +169,6 @@ implementation
                 { we need the real called method }
                 { rg.cleartempgen;}
                 do_resulttypepass(p2);
-
-                if p2.nodetype<>calln then
-                  begin
-                    if is_new then
-                      CGMessage(parser_e_expr_have_to_be_constructor_call)
-                    else
-                      CGMessage(parser_e_expr_have_to_be_destructor_call);
-                  end;
-
                 if not codegenerror then
                  begin
                    if is_new then
@@ -221,7 +211,7 @@ implementation
 
                   { create statements with call to getmem+initialize or
                     finalize+freemem }
-                  new_dispose_statement:=internalstatements(newstatement,true);
+                  new_dispose_statement:=internalstatements(newstatement);
 
                   if is_new then
                    begin
@@ -231,7 +221,7 @@ implementation
 
                      { create call to fpc_getmem }
                      para := ccallparanode.create(cordconstnode.create
-                         (tpointerdef(p.resulttype.def).pointertype.def.size,s32bittype,true),nil);
+                         (tpointerdef(p.resulttype.def).pointertype.def.size,s32bittype),nil);
                      addstatement(newstatement,cassignmentnode.create(
                          ctemprefnode.create(temp),
                          ccallnode.createintern('fpc_getmem',para)));
@@ -307,7 +297,7 @@ implementation
               Message(parser_w_use_extended_syntax_for_objects);
 
             { create statements with call to getmem+initialize }
-            newblock:=internalstatements(newstatement,true);
+            newblock:=internalstatements(newstatement);
 
             { create temp for result }
             temp := ctempcreatenode.create(p1.resulttype,p1.resulttype.def.size,true);
@@ -315,7 +305,7 @@ implementation
 
             { create call to fpc_getmem }
             para := ccallparanode.create(cordconstnode.create
-                (tpointerdef(p1.resulttype.def).pointertype.def.size,s32bittype,true),nil);
+                (tpointerdef(p1.resulttype.def).pointertype.def.size,s32bittype),nil);
             addstatement(newstatement,cassignmentnode.create(
                 ctemprefnode.create(temp),
                 ccallnode.createintern('fpc_getmem',para)));
@@ -465,7 +455,7 @@ implementation
          begin
             { create statements with call initialize the arguments and
               call fpc_dynarr_setlength }
-            newblock:=internalstatements(newstatement,true);
+            newblock:=internalstatements(newstatement);
 
             { get temp for array of lengths }
             temp := ctempcreatenode.create(s32bittype,counter*s32bittype.def.size,true);
@@ -490,7 +480,7 @@ implementation
             npara:=ccallparanode.create(caddrnode.create
                       (ctemprefnode.create(temp)),
                    ccallparanode.create(cordconstnode.create
-                      (counter,s32bittype,true),
+                      (counter,s32bittype),
                    ccallparanode.create(caddrnode.create
                       (crttinode.create(tstoreddef(destppn.resulttype.def),initrtti)),
                    ccallparanode.create(ctypeconvnode.create_explicit(destppn,voidpointertype),nil))));
@@ -546,7 +536,7 @@ implementation
             end;
            { create call to fpc_finalize_array }
            npara:=ccallparanode.create(cordconstnode.create
-                     (destppn.left.resulttype.def.size,s32bittype,true),
+                     (destppn.left.resulttype.def.size,s32bittype),
                   ccallparanode.create(ctypeconvnode.create
                      (ppn.left,s32bittype),
                   ccallparanode.create(caddrnode.create
@@ -572,151 +562,10 @@ implementation
         result:=newblock;
       end;
 
-
-    function inline_copy : tnode;
-      var
-        copynode,
-        lowppn,
-        highppn,
-        npara,
-        paras   : tnode;
-        temp    : ttempcreatenode;
-        ppn     : tcallparanode;
-        paradef : tdef;
-        counter : integer;
-        newstatement : tstatementnode;
-      begin
-        { for easy exiting if something goes wrong }
-        result := cerrornode.create;
-
-        consume(_LKLAMMER);
-        paras:=parse_paras(false,false);
-        consume(_RKLAMMER);
-        if not assigned(paras) then
-         begin
-           CGMessage(parser_e_wrong_parameter_size);
-           exit;
-         end;
-
-        { determine copy function to use based on the first argument,
-          also count the number of arguments in this loop }
-        counter:=1;
-        ppn:=tcallparanode(paras);
-        while assigned(ppn.right) do
-         begin
-           inc(counter);
-           ppn:=tcallparanode(ppn.right);
-         end;
-        paradef:=ppn.left.resulttype.def;
-        if is_ansistring(paradef) then
-          copynode:=ccallnode.createintern('fpc_ansistr_copy',paras)
-        else
-         if is_widestring(paradef) then
-           copynode:=ccallnode.createintern('fpc_widestr_copy',paras)
-        else
-         if is_char(paradef) then
-           copynode:=ccallnode.createintern('fpc_char_copy',paras)
-        else
-         if is_dynamic_array(paradef) then
-          begin
-            { Only allow 1 or 3 arguments }
-            if (counter<>1) and (counter<>3) then
-             begin
-               CGMessage(parser_e_wrong_parameter_size);
-               exit;
-             end;
-
-            { create statements with call }
-            copynode:=internalstatements(newstatement,true);
-
-            if (counter=3) then
-             begin
-               highppn:=tcallparanode(paras).left.getcopy;
-               lowppn:=tcallparanode(tcallparanode(paras).right).left.getcopy;
-             end
-            else
-             begin
-               { use special -1,-1 argument to copy the whole array }
-               highppn:=cordconstnode.create(-1,s32bittype,false);
-               lowppn:=cordconstnode.create(-1,s32bittype,false);
-             end;
-
-            { create temp for result, we've to use a temp because a dynarray
-              type is handled differently from a pointer so we can't
-              use createinternres() and a function }
-            temp := ctempcreatenode.create(voidpointertype,voidpointertype.def.size,true);
-            addstatement(newstatement,temp);
-
-            { create call to fpc_dynarray_copy }
-            npara:=ccallparanode.create(highppn,
-                   ccallparanode.create(lowppn,
-                   ccallparanode.create(caddrnode.create
-                      (crttinode.create(tstoreddef(ppn.left.resulttype.def),initrtti)),
-                   ccallparanode.create
-                      (ctypeconvnode.create_explicit(ppn.left,voidpointertype),
-                   ccallparanode.create
-                      (ctemprefnode.create(temp),nil)))));
-            addstatement(newstatement,ccallnode.createintern('fpc_dynarray_copy',npara));
-
-            { convert the temp to normal and return the reference to the
-              created temp, and convert the type of the temp to the dynarray type }
-            addstatement(newstatement,ctempdeletenode.create_normal_temp(temp));
-            addstatement(newstatement,ctypeconvnode.create_explicit(ctemprefnode.create(temp),ppn.left.resulttype));
-
-            ppn.left:=nil;
-            paras.free;
-          end
-        else
-         begin
-           { generic fallback that will give an error if a wrong
-             type is passed }
-           copynode:=ccallnode.createintern('fpc_shortstr_copy',paras)
-         end;
-
-        result.free;
-        result:=copynode;
-      end;
-
 end.
 {
   $Log$
-  Revision 1.12  2002-04-25 20:15:40  florian
-    * block nodes within expressions shouldn't release the used registers,
-      fixed using a flag till the new rg is ready
-
-  Revision 1.11  2002/11/26 22:59:09  peter
-    * fix Copy(array,x,y)
-
-  Revision 1.10  2002/11/25 17:43:22  peter
-    * splitted defbase in defutil,symutil,defcmp
-    * merged isconvertable and is_equal into compare_defs(_ext)
-    * made operator search faster by walking the list only once
-
-  Revision 1.9  2002/10/29 10:01:22  pierre
-   * fix crash report as webbug 2174
-
-  Revision 1.8  2002/10/02 18:20:52  peter
-    * Copy() is now internal syssym that calls compilerprocs
-
-  Revision 1.7  2002/09/07 12:16:03  carl
-    * second part bug report 1996 fix, testrange in cordconstnode
-      only called if option is set (also make parsing a tiny faster)
-
-  Revision 1.6  2002/07/20 11:57:56  florian
-    * types.pas renamed to defbase.pas because D6 contains a types
-      unit so this would conflicts if D6 programms are compiled
-    + Willamette/SSE2 instructions to assembler added
-
-  Revision 1.5  2002/05/18 13:34:12  peter
-    * readded missing revisions
-
-  Revision 1.4  2002/05/16 19:46:43  carl
-  + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
-  + try to fix temp allocation (still in ifdef)
-  + generic constructor calls
-  + start of tassembler / tmodulebase class cleanup
-
-  Revision 1.2  2002/05/12 16:53:09  peter
+  Revision 1.2  2002-05-12 16:53:09  peter
     * moved entry and exitcode to ncgutil and cgobj
     * foreach gets extra argument for passing local data to the
       iterator function

+ 45 - 37
compiler/pmodules.pas

@@ -38,9 +38,9 @@ implementation
        globtype,version,systems,tokens,
        cutils,cclasses,comphook,
        globals,verbose,fmodule,finput,fppu,
-       symconst,symbase,symdef,symsym,symtable,aasm,
+       symconst,symbase,symtype,symdef,symsym,symtable,aasm,
        cgbase,
-       cga,
+       ncgutil,
        link,assemble,import,export,gendef,ppu,comprsrc,
        cresstr,cpubase,cpuasm,
 {$ifdef GDB}
@@ -682,29 +682,18 @@ implementation
       end;
 
 
-
-    var ltvTable : taasmoutput;
-
-    procedure addToLocalThreadvarTab(p:tnamedindexitem);
+    procedure addToLocalThreadvarTab(p:tnamedindexitem;arg:pointer);
       var
-        asym : tasmsymbol;
+        ltvTable : taasmoutput;
       begin
-        with tvarsym(p) do
+        ltvTable:=taasmoutput(arg);
+        if (tsym(p).typ=varsym) and
+           (vo_is_thread_var in tvarsym(p).varoptions) then
          begin
-           if (typ=varsym) and (vo_is_thread_var IN varoptions) then
-           begin
-             if ltvTable = nil then
-             begin   { first threadvar }
-               ltvTable := TAAsmOutput.Create;
-               ltvTable.insert(tai_symbol.createdataname_global(current_module.modulename^+'_$LOCALTHREADVARLIST',0));
-             end;
-                 asym := getasmsymbol(mangledname);
-             if asym <> nil then
-             begin
-               ltvTable.concat(tai_const_symbol.create(asym));    { address of threadvar }
-               ltvTable.concat(tai_const.create_32bit(getsize));  { size of threadvar }
-             end;
-           end;
+           { address of threadvar }
+           ltvTable.concat(tai_const_symbol.create(newasmsymbol(tvarsym(p).mangledname)));
+           { size of threadvar }
+           ltvTable.concat(tai_const.create_32bit(tvarsym(p).getsize));
          end;
       end;
 
@@ -735,7 +724,7 @@ implementation
          store_crc,store_interface_crc : cardinal;
          s2  : ^string; {Saves stack space}
          force_init_final : boolean;
-
+         ltvTable : taasmoutput;
       begin
          consume(_UNIT);
          if compile_level=1 then
@@ -980,18 +969,20 @@ implementation
            end;
 
          { generate a list of local threadvars }
-         ltvTable := nil;
-         st.foreach_static (@addToLocalThreadvarTab);
-         if ltvTable <> nil then
-         begin
-           ltvTable.concat(tai_const.create_32bit(0));  { end of list marker }
-           ltvTable.concat(tai_symbol_end.createname(current_module.modulename^+'_$LOCALTHREADVARLIST'));
-           if (cs_create_smart in aktmoduleswitches) then
-            dataSegment.concat(Tai_cut.Create);
-           dataSegment.concatlist(ltvTable);
-           ltvTable.Free;
-           current_module.flags:=current_module.flags or uf_local_threadvars;
-         end;
+         ltvTable:=TAAsmoutput.create;
+         st.foreach_static({$ifdef FPCPROCVAR}@{$endif}addToLocalThreadvarTab,ltvTable);
+         if ltvTable.first<>nil then
+          begin
+            { add begin and end of the list }
+            ltvTable.insert(tai_symbol.createdataname_global(current_module.modulename^+'_$LOCALTHREADVARLIST',0));
+            ltvTable.concat(tai_const.create_32bit(0));  { end of list marker }
+            ltvTable.concat(tai_symbol_end.createname(current_module.modulename^+'_$LOCALTHREADVARLIST'));
+            if (cs_create_smart in aktmoduleswitches) then
+             dataSegment.concat(Tai_cut.Create);
+            dataSegment.concatlist(ltvTable);
+            current_module.flags:=current_module.flags or uf_local_threadvars;
+          end;
+         ltvTable.Free;
 
          { the last char should always be a point }
          consume(_POINT);
@@ -1236,7 +1227,7 @@ implementation
 
          {Insert the name of the main program into the symbol table.}
          if current_module.realmodulename^<>'' then
-           st.insert(tunitsym.create(current_module.realmodulename^,tglobalsymtable(st)));
+           st.insert(tunitsym.create(current_module.realmodulename^,st));
 
          { ...is also constsymtable, this is the symtable where }
          { the elements of enumeration types are inserted       }
@@ -1392,7 +1383,24 @@ implementation
 end.
 {
   $Log$
-  Revision 1.63  2002-05-06 19:54:50  carl
+  Revision 1.64  2002-05-12 16:53:09  peter
+    * moved entry and exitcode to ncgutil and cgobj
+    * foreach gets extra argument for passing local data to the
+      iterator function
+    * -CR checks also class typecasts at runtime by changing them
+      into as
+    * fixed compiler to cycle with the -CR option
+    * fixed stabs with elf writer, finally the global variables can
+      be watched
+    * removed a lot of routines from cga unit and replaced them by
+      calls to cgobj
+    * u32bit-s32bit updates for and,or,xor nodes. When one element is
+      u32bit then the other is typecasted also to u32bit without giving
+      a rangecheck warning/error.
+    * fixed pascal calling method with reversing also the high tree in
+      the parast, detected by tcalcst3 test
+
+  Revision 1.63  2002/05/06 19:54:50  carl
   + added more patches from Mazen for SPARC port
 
   Revision 1.62  2002/04/20 21:32:24  carl

+ 29 - 18
compiler/psub.pas

@@ -54,17 +54,17 @@ implementation
        { pass 1 }
        node,
        nbas,
+       pass_1,
        { pass 2 }
 {$ifndef NOPASS2}
-       pass_1,pass_2,
+       pass_2,
 {$endif}
        { parser }
        scanner,
        pbase,pstatmnt,pdecl,pdecsub,pexports,
        { codegen }
-       tgobj,cgbase,rgobj,
-       rgcpu,
-       cga
+       tgobj,cgbase,rgobj,rgcpu,
+       ncgutil
        {$ifndef NOOPT}
          {$ifdef i386}
            ,aopt386
@@ -328,11 +328,7 @@ implementation
                 { first generate entry code with the correct position and switches }
                 aktfilepos:=entrypos;
                 aktlocalswitches:=entryswitches;
-{$ifdef newcg}
-                cg^.g_entrycode(procinfo^.aktentrycode,proc_names,make_global,stackframe,parasize,nostackframe,false);
-{$else newcg}
                 genentrycode(procinfo^.aktentrycode,make_global,stackframe,parasize,nostackframe,false);
-{$endif newcg}
 
                 { FPC_POPADDRSTACK destroys all registers (JM) }
                 if (procinfo^.flags and (pi_needs_implicit_finally or pi_uses_exceptions)) <> 0 then
@@ -343,11 +339,7 @@ implementation
                 { now generate exit code with the correct position and switches }
                 aktfilepos:=exitpos;
                 aktlocalswitches:=exitswitches;
-{$ifdef newcg}
-                cg^.g_exitcode(procinfo^.aktexitcode,parasize,nostackframe,false);
-{$else newcg}
                 genexitcode(procinfo^.aktexitcode,parasize,nostackframe,false);
-{$endif newcg}
 
                 { now all the registers used are known }
                 aktprocdef.usedregisters:=rg.usedinproc;
@@ -462,11 +454,13 @@ implementation
                         PROCEDURE/FUNCTION PARSING
 ****************************************************************************}
 
-    procedure checkvaluepara(p:tnamedindexitem);
+    procedure checkvaluepara(p:tnamedindexitem;arg:pointer);
       var
         vs : tvarsym;
         s  : string;
       begin
+        if tsym(p).typ<>varsym then
+         exit;
         with tvarsym(p) do
          begin
            if copy(name,1,3)='val' then
@@ -648,7 +642,7 @@ implementation
            the parameter and insert a copy in the localst. This is not done
            for assembler procedures }
          if (not parse_only) and (not aktprocdef.forwarddef) then
-           aktprocdef.parast.foreach_static({$ifdef FPCPROCVAR}@{$endif}checkvaluepara);
+           aktprocdef.parast.foreach_static({$ifdef FPCPROCVAR}@{$endif}checkvaluepara,nil);
 
          { restore file pos }
          aktfilepos:=oldfilepos;
@@ -700,7 +694,7 @@ implementation
 ****************************************************************************}
 
     { search in symtablestack for not complete classes }
-    procedure check_forward_class(p : tnamedindexitem);
+    procedure check_forward_class(p : tnamedindexitem;arg:pointer);
       begin
         if (tsym(p).typ=typesym) and
            (ttypesym(p).restype.def.deftype=objectdef) and
@@ -772,7 +766,7 @@ implementation
          { check for incomplete class definitions, this is only required
            for fpc modes }
          if (m_fpc in aktmodeswitches) then
-          symtablestack.foreach_static({$ifdef FPCPROCVAR}@{$endif}check_forward_class);
+          symtablestack.foreach_static({$ifdef FPCPROCVAR}@{$endif}check_forward_class,nil);
       end;
 
 
@@ -805,13 +799,30 @@ implementation
          { check for incomplete class definitions, this is only required
            for fpc modes }
          if (m_fpc in aktmodeswitches) then
-          symtablestack.foreach_static({$ifdef FPCPROCVAR}@{$endif}check_forward_class);
+          symtablestack.foreach_static({$ifdef FPCPROCVAR}@{$endif}check_forward_class,nil);
       end;
 
 end.
 {
   $Log$
-  Revision 1.49  2002-04-20 21:32:24  carl
+  Revision 1.50  2002-05-12 16:53:09  peter
+    * moved entry and exitcode to ncgutil and cgobj
+    * foreach gets extra argument for passing local data to the
+      iterator function
+    * -CR checks also class typecasts at runtime by changing them
+      into as
+    * fixed compiler to cycle with the -CR option
+    * fixed stabs with elf writer, finally the global variables can
+      be watched
+    * removed a lot of routines from cga unit and replaced them by
+      calls to cgobj
+    * u32bit-s32bit updates for and,or,xor nodes. When one element is
+      u32bit then the other is typecasted also to u32bit without giving
+      a rangecheck warning/error.
+    * fixed pascal calling method with reversing also the high tree in
+      the parast, detected by tcalcst3 test
+
+  Revision 1.49  2002/04/20 21:32:24  carl
   + generic FPC_CHECKPOINTER
   + first parameter offset in stack now portable
   * rename some constants

+ 19 - 3
compiler/psystem.pas

@@ -40,8 +40,7 @@ implementation
 uses
   globals,
   symconst,symtype,symsym,symdef,symtable,
-  ninl,
-  cpuinfo;
+  ninl;
 
 procedure insertinternsyms(p : tsymtable);
 {
@@ -277,7 +276,24 @@ end;
 end.
 {
   $Log$
-  Revision 1.22  2002-01-24 12:33:53  jonas
+  Revision 1.23  2002-05-12 16:53:09  peter
+    * moved entry and exitcode to ncgutil and cgobj
+    * foreach gets extra argument for passing local data to the
+      iterator function
+    * -CR checks also class typecasts at runtime by changing them
+      into as
+    * fixed compiler to cycle with the -CR option
+    * fixed stabs with elf writer, finally the global variables can
+      be watched
+    * removed a lot of routines from cga unit and replaced them by
+      calls to cgobj
+    * u32bit-s32bit updates for and,or,xor nodes. When one element is
+      u32bit then the other is typecasted also to u32bit without giving
+      a rangecheck warning/error.
+    * fixed pascal calling method with reversing also the high tree in
+      the parast, detected by tcalcst3 test
+
+  Revision 1.22  2002/01/24 12:33:53  jonas
     * adapted ranges of native types to int64 (e.g. high cardinal is no
       longer longint($ffffffff), but just $fffffff in psystem)
     * small additional fix in 64bit rangecheck code generation for 32 bit

+ 20 - 3
compiler/ptconst.pas

@@ -43,7 +43,7 @@ implementation
 {$endif Delphi}
        globtype,systems,tokens,
        cutils,globals,widestr,scanner,
-       symconst,symbase,symdef,aasm,cpuasm,types,verbose,cpubase,
+       symconst,symbase,symdef,aasm,cpuasm,types,verbose,
        { pass 1 }
        node,
        nmat,nadd,ncal,nmem,nset,ncnv,ninl,ncon,nld,nflw,
@@ -347,7 +347,7 @@ implementation
                      hpstart:=taddrnode(p).left;
                     hp:=hpstart;
                     while assigned(hp) and (hp.nodetype in [subscriptn,vecn]) do
-                      hp:=tbinarynode(hp).left;
+                      hp:=tunarynode(hp).left;
                     if (hp.nodetype=loadn) then
                       begin
                         hp:=hpstart;
@@ -971,7 +971,24 @@ implementation
 end.
 {
   $Log$
-  Revision 1.45  2002-04-23 19:16:35  peter
+  Revision 1.46  2002-05-12 16:53:09  peter
+    * moved entry and exitcode to ncgutil and cgobj
+    * foreach gets extra argument for passing local data to the
+      iterator function
+    * -CR checks also class typecasts at runtime by changing them
+      into as
+    * fixed compiler to cycle with the -CR option
+    * fixed stabs with elf writer, finally the global variables can
+      be watched
+    * removed a lot of routines from cga unit and replaced them by
+      calls to cgobj
+    * u32bit-s32bit updates for and,or,xor nodes. When one element is
+      u32bit then the other is typecasted also to u32bit without giving
+      a rangecheck warning/error.
+    * fixed pascal calling method with reversing also the high tree in
+      the parast, detected by tcalcst3 test
+
+  Revision 1.45  2002/04/23 19:16:35  peter
     * add pinline unit that inserts compiler supported functions using
       one or more statements
     * moved finalize and setlength from ninl to pinline

+ 19 - 2
compiler/ptype.pas

@@ -55,7 +55,7 @@ implementation
 
     uses
        { common }
-       cutils,cpuinfo,
+       cutils,
        { global }
        globals,tokens,verbose,
        systems,
@@ -631,7 +631,24 @@ implementation
 end.
 {
   $Log$
-  Revision 1.37  2002-04-19 15:46:03  peter
+  Revision 1.38  2002-05-12 16:53:10  peter
+    * moved entry and exitcode to ncgutil and cgobj
+    * foreach gets extra argument for passing local data to the
+      iterator function
+    * -CR checks also class typecasts at runtime by changing them
+      into as
+    * fixed compiler to cycle with the -CR option
+    * fixed stabs with elf writer, finally the global variables can
+      be watched
+    * removed a lot of routines from cga unit and replaced them by
+      calls to cgobj
+    * u32bit-s32bit updates for and,or,xor nodes. When one element is
+      u32bit then the other is typecasted also to u32bit without giving
+      a rangecheck warning/error.
+    * fixed pascal calling method with reversing also the high tree in
+      the parast, detected by tcalcst3 test
+
+  Revision 1.37  2002/04/19 15:46:03  peter
     * mangledname rewrite, tprocdef.mangledname is now created dynamicly
       in most cases and not written to the ppu
     * add mangeledname_prefix() routine to generate the prefix of

+ 20 - 3
compiler/rautils.pas

@@ -1134,7 +1134,7 @@ end;
                              TLocalLabelList
 ***************************************************************************}
 
-procedure LocalLabelEmitted(p:tnamedindexitem);
+procedure LocalLabelEmitted(p:tnamedindexitem;arg:pointer);
 begin
   if not TLocalLabel(p).emitted  then
    Message1(asmr_e_unknown_label_identifier,p.name);
@@ -1142,7 +1142,7 @@ end;
 
 procedure TLocalLabelList.CheckEmitted;
 begin
-  ForEach_Static({$ifdef FPCPROCVAR}@{$endif}LocalLabelEmitted)
+  ForEach_Static({$ifdef FPCPROCVAR}@{$endif}LocalLabelEmitted,nil)
 end;
 
 
@@ -1585,7 +1585,24 @@ end;
 end.
 {
   $Log$
-  Revision 1.30  2002-04-20 21:32:24  carl
+  Revision 1.31  2002-05-12 16:53:10  peter
+    * moved entry and exitcode to ncgutil and cgobj
+    * foreach gets extra argument for passing local data to the
+      iterator function
+    * -CR checks also class typecasts at runtime by changing them
+      into as
+    * fixed compiler to cycle with the -CR option
+    * fixed stabs with elf writer, finally the global variables can
+      be watched
+    * removed a lot of routines from cga unit and replaced them by
+      calls to cgobj
+    * u32bit-s32bit updates for and,or,xor nodes. When one element is
+      u32bit then the other is typecasted also to u32bit without giving
+      a rangecheck warning/error.
+    * fixed pascal calling method with reversing also the high tree in
+      the parast, detected by tcalcst3 test
+
+  Revision 1.30  2002/04/20 21:32:24  carl
   + generic FPC_CHECKPOINTER
   + first parameter offset in stack now portable
   * rename some constants

+ 29 - 10
compiler/regvars.pas

@@ -49,16 +49,15 @@ implementation
       globtype,systems,comphook,
       cutils,cclasses,verbose,globals,
       symconst,symbase,symtype,symdef,types,
-      tainst,cgbase,cpuasm,cgobj, cgcpu,cga,rgcpu;
+      tainst,cgbase,cpuasm,cgobj,cgcpu,rgcpu;
 
-    var
-      parasym : boolean;
 
-
-    procedure searchregvars(p : tnamedindexitem);
+    procedure searchregvars(p : tnamedindexitem;arg:pointer);
       var
          i,j,k : longint;
+         parasym : boolean;
       begin
+         parasym:=pboolean(arg)^;
          if (tsym(p).typ=varsym) and (vo_regable in tvarsym(p).varoptions) then
            begin
               j:=tvarsym(p).refs;
@@ -94,10 +93,12 @@ implementation
       end;
 
 
-    procedure searchfpuregvars(p : tnamedindexitem);
+    procedure searchfpuregvars(p : tnamedindexitem;arg:pointer);
       var
          i,j,k : longint;
+         parasym : boolean;
       begin
+         parasym:=pboolean(arg)^;
          if (tsym(p).typ=varsym) and (vo_fpuregable in tvarsym(p).varoptions) then
            begin
               j:=tvarsym(p).refs;
@@ -137,6 +138,7 @@ implementation
     var
       regvarinfo: pregvarinfo;
       i: longint;
+      parasym : boolean;
     begin
       { max. optimizations     }
       { only if no asm is used }
@@ -150,10 +152,10 @@ implementation
           if (p.registers32<4) then
             begin
               parasym:=false;
-              symtablestack.foreach_static({$ifdef FPCPROCVAR}@{$endif}searchregvars);
+              symtablestack.foreach_static({$ifdef FPCPROCVAR}@{$endif}searchregvars,@parasym);
               { copy parameter into a register ? }
               parasym:=true;
-              symtablestack.next.foreach_static({$ifdef FPCPROCVAR}@{$endif}searchregvars);
+              symtablestack.next.foreach_static({$ifdef FPCPROCVAR}@{$endif}searchregvars,@parasym);
               { hold needed registers free }
               for i:=maxvarregs downto maxvarregs-p.registers32+1 do
                 begin
@@ -209,7 +211,7 @@ implementation
             if ((p.registersfpu+1)<maxfpuvarregs) then
               begin
                 parasym:=false;
-                symtablestack.foreach_static({$ifdef FPCPROCVAR}@{$endif}searchfpuregvars);
+                symtablestack.foreach_static({$ifdef FPCPROCVAR}@{$endif}searchfpuregvars,@parasym);
 {$ifdef dummy}
                 { copy parameter into a register ? }
                 parasym:=true;
@@ -462,7 +464,24 @@ end.
 
 {
   $Log$
-  Revision 1.29  2002-04-21 15:23:34  carl
+  Revision 1.30  2002-05-12 16:53:10  peter
+    * moved entry and exitcode to ncgutil and cgobj
+    * foreach gets extra argument for passing local data to the
+      iterator function
+    * -CR checks also class typecasts at runtime by changing them
+      into as
+    * fixed compiler to cycle with the -CR option
+    * fixed stabs with elf writer, finally the global variables can
+      be watched
+    * removed a lot of routines from cga unit and replaced them by
+      calls to cgobj
+    * u32bit-s32bit updates for and,or,xor nodes. When one element is
+      u32bit then the other is typecasted also to u32bit without giving
+      a rangecheck warning/error.
+    * fixed pascal calling method with reversing also the high tree in
+      the parast, detected by tcalcst3 test
+
+  Revision 1.29  2002/04/21 15:23:34  carl
   + changeregsize -> makeregsize
 
   Revision 1.28  2002/04/19 15:46:03  peter

+ 24 - 7
compiler/symbase.pas

@@ -113,8 +113,8 @@ interface
           destructor  destroy;override;
           procedure clear;virtual;
           function  rename(const olds,news : stringid):tsymentry;
-          procedure foreach(proc2call : tnamedindexcallback);
-          procedure foreach_static(proc2call : tnamedindexstaticcallback);
+          procedure foreach(proc2call : tnamedindexcallback;arg:pointer);
+          procedure foreach_static(proc2call : tnamedindexstaticcallback;arg:pointer);
           procedure insert(sym : tsymentry);virtual;
           function  search(const s : stringid) : tsymentry;
           function  speedsearch(const s : stringid;speedvalue : cardinal) : tsymentry;virtual;
@@ -208,15 +208,15 @@ implementation
       end;
 
 
-    procedure tsymtable.foreach(proc2call : tnamedindexcallback);
+    procedure tsymtable.foreach(proc2call : tnamedindexcallback;arg:pointer);
       begin
-        symindex.foreach(proc2call);
+        symindex.foreach(proc2call,arg);
       end;
 
 
-    procedure tsymtable.foreach_static(proc2call : tnamedindexstaticcallback);
+    procedure tsymtable.foreach_static(proc2call : tnamedindexstaticcallback;arg:pointer);
       begin
-        symindex.foreach_static(proc2call);
+        symindex.foreach_static(proc2call,arg);
       end;
 
 
@@ -311,7 +311,24 @@ implementation
 end.
 {
   $Log$
-  Revision 1.2  2001-04-13 01:22:15  peter
+  Revision 1.3  2002-05-12 16:53:10  peter
+    * moved entry and exitcode to ncgutil and cgobj
+    * foreach gets extra argument for passing local data to the
+      iterator function
+    * -CR checks also class typecasts at runtime by changing them
+      into as
+    * fixed compiler to cycle with the -CR option
+    * fixed stabs with elf writer, finally the global variables can
+      be watched
+    * removed a lot of routines from cga unit and replaced them by
+      calls to cgobj
+    * u32bit-s32bit updates for and,or,xor nodes. When one element is
+      u32bit then the other is typecasted also to u32bit without giving
+      a rangecheck warning/error.
+    * fixed pascal calling method with reversing also the high tree in
+      the parast, detected by tcalcst3 test
+
+  Revision 1.2  2001/04/13 01:22:15  peter
     * symtable change to classes
     * range check generation and errors fixed, make cycle DEBUG=1 works
     * memory leaks fixed

+ 22 - 1
compiler/symconst.pas

@@ -269,6 +269,10 @@ type
     vs_set_but_first_not_passed,vs_assigned,vs_used
   );
 
+  tvarspez = (vs_value,vs_const,vs_var,vs_out);
+
+  targconvtyp = (act_convertable,act_equal,act_exact);
+
   absolutetyp = (tovar,toasm,toaddr);
 
   tconsttyp = (constnone,
@@ -326,7 +330,24 @@ implementation
 end.
 {
   $Log$
-  Revision 1.28  2002-01-06 12:08:15  peter
+  Revision 1.29  2002-05-12 16:53:10  peter
+    * moved entry and exitcode to ncgutil and cgobj
+    * foreach gets extra argument for passing local data to the
+      iterator function
+    * -CR checks also class typecasts at runtime by changing them
+      into as
+    * fixed compiler to cycle with the -CR option
+    * fixed stabs with elf writer, finally the global variables can
+      be watched
+    * removed a lot of routines from cga unit and replaced them by
+      calls to cgobj
+    * u32bit-s32bit updates for and,or,xor nodes. When one element is
+      u32bit then the other is typecasted also to u32bit without giving
+      a rangecheck warning/error.
+    * fixed pascal calling method with reversing also the high tree in
+      the parast, detected by tcalcst3 test
+
+  Revision 1.28  2002/01/06 12:08:15  peter
     * removed uauto from orddef, use new range_to_basetype generating
       the correct ordinal type for a range
 

+ 75 - 61
compiler/symdef.pas

@@ -93,10 +93,6 @@ interface
           savesize  : longint;
        end;
 
-       targconvtyp = (act_convertable,act_equal,act_exact);
-
-       tvarspez = (vs_value,vs_const,vs_var,vs_out);
-
        tparaitem = class(tlinkedlistitem)
           paratype     : ttype;
           parasym      : tsym;
@@ -199,11 +195,11 @@ interface
           StabRecString : pchar;
           StabRecSize   : Integer;
           RecOffset     : Integer;
-          procedure addname(p : tnamedindexitem);
+          procedure addname(p : tnamedindexitem;arg:pointer);
 {$endif}
-          procedure count_field_rtti(sym : tnamedindexitem);
-          procedure write_field_rtti(sym : tnamedindexitem);
-          procedure generate_field_rtti(sym : tnamedindexitem);
+          procedure count_field_rtti(sym : tnamedindexitem;arg:pointer);
+          procedure write_field_rtti(sym : tnamedindexitem;arg:pointer);
+          procedure generate_field_rtti(sym : tnamedindexitem;arg:pointer);
        public
           symtable : tsymtable;
           function  getsymtable(t:tgetsymtable):tsymtable;override;
@@ -237,15 +233,15 @@ interface
        tobjectdef = class(tabstractrecorddef)
        private
           sd : tprocdef;
-          procedure _searchdestructor(sym : tnamedindexitem);
+          procedure _searchdestructor(sym : tnamedindexitem;arg:pointer);
 {$ifdef GDB}
-          procedure addprocname(p :tnamedindexitem);
+          procedure addprocname(p :tnamedindexitem;arg:pointer);
 {$endif GDB}
-          procedure count_published_properties(sym:tnamedindexitem);
-          procedure write_property_info(sym : tnamedindexitem);
-          procedure generate_published_child_rtti(sym : tnamedindexitem);
-          procedure count_published_fields(sym:tnamedindexitem);
-          procedure writefields(sym:tnamedindexitem);
+          procedure count_published_properties(sym:tnamedindexitem;arg:pointer);
+          procedure write_property_info(sym : tnamedindexitem;arg:pointer);
+          procedure generate_published_child_rtti(sym : tnamedindexitem;arg:pointer);
+          procedure count_published_fields(sym:tnamedindexitem;arg:pointer);
+          procedure writefields(sym:tnamedindexitem;arg:pointer);
        public
           childof  : tobjectdef;
           objname,
@@ -307,7 +303,8 @@ interface
           procedure addintf(def: tdef);
 
           procedure deref;
-          procedure addintfref(def: tdef);
+          { add interface reference loaded from ppu }
+          procedure addintfref(def: pointer);
 
           procedure clearmappings;
           procedure addmappings(intfindex: longint; const name, newname: string);
@@ -848,7 +845,7 @@ implementation
          fillchar(localrttilab,sizeof(localrttilab),0);
       { load }
          indexnr:=ppufile.getword;
-         typesym:=ttypesym(ppufile.getderef);
+         typesym:=ttypesym(pointer(ppufile.getderef));
          ppufile.getsmallset(defoptions);
          if df_has_rttitable in defoptions then
           rttitablesym:=tsym(ppufile.getderef);
@@ -911,9 +908,9 @@ implementation
 
     procedure tstoreddef.deref;
       begin
-        resolvesym(typesym);
-        resolvesym(rttitablesym);
-        resolvesym(inittablesym);
+        resolvesym(pointer(typesym));
+        resolvesym(pointer(rttitablesym));
+        resolvesym(pointer(inittablesym));
       end;
 
 
@@ -1323,8 +1320,8 @@ implementation
              end;
            st_widestring:
              begin
-               { an ansi string looks like a pchar easy !! }
-               stabstring:=strpnew('*'+typeglobalnumber('char'));
+               { an ansi string looks like a pwidechar easy !! }
+               stabstring:=strpnew('*'+typeglobalnumber('widechar'));
              end;
       end;
     end;
@@ -1481,7 +1478,7 @@ implementation
     procedure tenumdef.deref;
       begin
         inherited deref;
-        resolvedef(tdef(basedef));
+        resolvedef(pointer(basedef));
       end;
 
 
@@ -2810,7 +2807,7 @@ implementation
 
 
 {$ifdef GDB}
-    procedure tabstractrecorddef.addname(p : tnamedindexitem);
+    procedure tabstractrecorddef.addname(p : tnamedindexitem;arg:pointer);
       var
         news, newrec : pchar;
         spec : string[3];
@@ -2857,7 +2854,7 @@ implementation
 {$endif GDB}
 
 
-    procedure tabstractrecorddef.count_field_rtti(sym : tnamedindexitem);
+    procedure tabstractrecorddef.count_field_rtti(sym : tnamedindexitem;arg:pointer);
       begin
          if (FRTTIType=fullrtti) or
             ((tsym(sym).typ=varsym) and
@@ -2866,7 +2863,7 @@ implementation
       end;
 
 
-    procedure tabstractrecorddef.generate_field_rtti(sym:tnamedindexitem);
+    procedure tabstractrecorddef.generate_field_rtti(sym:tnamedindexitem;arg:pointer);
       begin
          if (FRTTIType=fullrtti) or
             ((tsym(sym).typ=varsym) and
@@ -2875,7 +2872,7 @@ implementation
       end;
 
 
-    procedure tabstractrecorddef.write_field_rtti(sym : tnamedindexitem);
+    procedure tabstractrecorddef.write_field_rtti(sym : tnamedindexitem;arg:pointer);
       begin
          if (FRTTIType=fullrtti) or
             ((tsym(sym).typ=varsym) and
@@ -3017,7 +3014,7 @@ implementation
         stabrecsize:=memsizeinc;
         strpcopy(stabRecString,'s'+tostr(size));
         RecOffset := 0;
-        symtable.foreach({$ifdef FPCPROCVAR}@{$endif}addname);
+        symtable.foreach({$ifdef FPCPROCVAR}@{$endif}addname,nil);
         strpcopy(strend(StabRecString),';');
         stabstring := strnew(StabRecString);
         Freemem(stabrecstring,stabrecsize);
@@ -3036,7 +3033,7 @@ implementation
     procedure trecorddef.write_child_rtti_data(rt:trttitype);
       begin
          FRTTIType:=rt;
-         symtable.foreach({$ifdef FPCPROCVAR}@{$endif}generate_field_rtti);
+         symtable.foreach({$ifdef FPCPROCVAR}@{$endif}generate_field_rtti,nil);
       end;
 
 
@@ -3047,9 +3044,9 @@ implementation
          rttiList.concat(Tai_const.Create_32bit(size));
          Count:=0;
          FRTTIType:=rt;
-         symtable.foreach({$ifdef FPCPROCVAR}@{$endif}count_field_rtti);
+         symtable.foreach({$ifdef FPCPROCVAR}@{$endif}count_field_rtti,nil);
          rttiList.concat(Tai_const.Create_32bit(Count));
-         symtable.foreach({$ifdef FPCPROCVAR}@{$endif}write_field_rtti);
+         symtable.foreach({$ifdef FPCPROCVAR}@{$endif}write_field_rtti,nil);
       end;
 
 
@@ -3128,8 +3125,8 @@ implementation
          while assigned(hp) do
           begin
             hp.paratype.resolve;
-            resolvesym(tsym(hp.defaultvalue));
-            resolvesym(tsym(hp.parasym));
+            resolvesym(pointer(hp.defaultvalue));
+            resolvesym(pointer(hp.parasym));
             hp:=TParaItem(hp.next);
           end;
       end;
@@ -3747,7 +3744,7 @@ implementation
         oldlocalsymtable : tsymtable;
       begin
          inherited deref;
-         resolvedef(tdef(_class));
+         resolvedef(pointer(_class));
          { parast }
          oldlocalsymtable:=aktlocalsymtable;
          aktlocalsymtable:=parast;
@@ -3755,7 +3752,7 @@ implementation
          aktlocalsymtable:=oldlocalsymtable;
          { procsym that originaly defined this definition, should be in the
            same symtable }
-         resolvesym(procsym);
+         resolvesym(pointer(procsym));
       end;
 
 
@@ -3774,7 +3771,7 @@ implementation
             tlocalsymtable(localst).derefimpl;
             aktlocalsymtable:=oldlocalsymtable;
             { funcretsym, this is always located in the localst }
-            resolvesym(funcretsym);
+            resolvesym(pointer(funcretsym));
           end
          else
           begin
@@ -4143,7 +4140,7 @@ implementation
              implintfcount:=ppufile.getlongint;
              for i:=1 to implintfcount do
                begin
-                  implementedinterfaces.addintfref(tdef(ppufile.getderef));
+                  implementedinterfaces.addintfref(ppufile.getderef);
                   implementedinterfaces.ioffsets(i)^:=ppufile.getlongint;
                end;
            end
@@ -4234,7 +4231,7 @@ implementation
          oldrecsyms : tsymtable;
       begin
          inherited deref;
-         resolvedef(tdef(childof));
+         resolvedef(pointer(childof));
          oldrecsyms:=aktrecordsymtable;
          aktrecordsymtable:=symtable;
          tstoredsymtable(symtable).deref;
@@ -4327,7 +4324,7 @@ implementation
      end;
 
 
-   procedure tobjectdef._searchdestructor(sym : tnamedindexitem);
+   procedure tobjectdef._searchdestructor(sym : tnamedindexitem;arg:pointer);
 
      var
         p : pprocdeflist;
@@ -4362,7 +4359,7 @@ implementation
         sd:=nil;
         while assigned(o) do
           begin
-             symtable.foreach({$ifdef FPCPROCVAR}@{$endif}_searchdestructor);
+             symtable.foreach({$ifdef FPCPROCVAR}@{$endif}_searchdestructor,nil);
              if assigned(sd) then
                begin
                   searchdestructor:=sd;
@@ -4420,7 +4417,7 @@ implementation
 
 
 {$ifdef GDB}
-    procedure tobjectdef.addprocname(p :tnamedindexitem);
+    procedure tobjectdef.addprocname(p :tnamedindexitem;arg:pointer);
       var virtualind,argnames : string;
           news, newrec : pchar;
           pd,ipd : tprocdef;
@@ -4538,7 +4535,7 @@ implementation
             {virtual table to implement yet}
             OldRecOffset:=RecOffset;
             RecOffset := 0;
-            symtable.foreach({$ifdef FPCPROCVAR}@{$endif}addname);
+            symtable.foreach({$ifdef FPCPROCVAR}@{$endif}addname,nil);
             RecOffset:=OldRecOffset;
             if (oo_has_vmt in objectoptions) then
               if not assigned(childof) or not(oo_has_vmt in childof.objectoptions) then
@@ -4546,7 +4543,7 @@ implementation
                     strpcopy(strend(stabrecstring),'$vf'+classnumberstring+':'+typeglobalnumber('vtblarray')
                       +','+tostr(vmt_offset*8)+';');
                  end;
-            symtable.foreach({$ifdef FPCPROCVAR}@{$endif}addprocname);
+            symtable.foreach({$ifdef FPCPROCVAR}@{$endif}addprocname,nil);
             if (oo_has_vmt in objectoptions) then
               begin
                  anc := self;
@@ -4680,7 +4677,7 @@ implementation
       end;
 
 
-    procedure tobjectdef.count_published_properties(sym:tnamedindexitem);
+    procedure tobjectdef.count_published_properties(sym:tnamedindexitem;arg:pointer);
       begin
          if needs_prop_entry(tsym(sym)) and
           (tsym(sym).typ<>varsym) then
@@ -4688,7 +4685,7 @@ implementation
       end;
 
 
-    procedure tobjectdef.write_property_info(sym : tnamedindexitem);
+    procedure tobjectdef.write_property_info(sym : tnamedindexitem;arg:pointer);
       var
          proctypesinfo : byte;
 
@@ -4792,7 +4789,7 @@ implementation
       end;
 
 
-    procedure tobjectdef.generate_published_child_rtti(sym : tnamedindexitem);
+    procedure tobjectdef.generate_published_child_rtti(sym : tnamedindexitem;arg:pointer);
       begin
          if needs_prop_entry(tsym(sym)) then
           begin
@@ -4813,9 +4810,9 @@ implementation
          FRTTIType:=rt;
          case rt of
            initrtti :
-             symtable.foreach({$ifdef FPCPROCVAR}@{$endif}generate_field_rtti);
+             symtable.foreach({$ifdef FPCPROCVAR}@{$endif}generate_field_rtti,nil);
            fullrtti :
-             symtable.foreach({$ifdef FPCPROCVAR}@{$endif}generate_published_child_rtti);
+             symtable.foreach({$ifdef FPCPROCVAR}@{$endif}generate_published_child_rtti,nil);
            else
              internalerror(200108301);
          end;
@@ -4851,7 +4848,7 @@ implementation
       end;
 
 
-    procedure tobjectdef.count_published_fields(sym:tnamedindexitem);
+    procedure tobjectdef.count_published_fields(sym:tnamedindexitem;arg:pointer);
       var
          hp : tclasslistitem;
       begin
@@ -4874,7 +4871,7 @@ implementation
       end;
 
 
-    procedure tobjectdef.writefields(sym:tnamedindexitem);
+    procedure tobjectdef.writefields(sym:tnamedindexitem;arg:pointer);
       var
          hp : tclasslistitem;
       begin
@@ -4904,13 +4901,13 @@ implementation
          getdatalabel(classtable);
          count:=0;
          tablecount:=0;
-         symtable.foreach({$ifdef FPC}@{$endif}count_published_fields);
+         symtable.foreach({$ifdef FPC}@{$endif}count_published_fields,nil);
          if (cs_create_smart in aktmoduleswitches) then
           rttiList.concat(Tai_cut.Create);
          rttiList.concat(Tai_label.Create(fieldtable));
          rttiList.concat(Tai_const.Create_16bit(count));
          rttiList.concat(Tai_const_symbol.Create(classtable));
-         symtable.foreach({$ifdef FPC}@{$endif}writefields);
+         symtable.foreach({$ifdef FPC}@{$endif}writefields,nil);
 
          { generate the class table }
          rttiList.concat(Tai_label.Create(classtable));
@@ -4936,7 +4933,7 @@ implementation
          else
            i:=0;
          count:=0;
-         symtable.foreach({$ifdef FPCPROCVAR}@{$endif}count_published_properties);
+         symtable.foreach({$ifdef FPCPROCVAR}@{$endif}count_published_properties,nil);
          next_free_name_index:=i+count;
       end;
 
@@ -4968,9 +4965,9 @@ implementation
                 begin
                   count:=0;
                   FRTTIType:=rt;
-                  symtable.foreach({$ifdef FPCPROCVAR}@{$endif}count_field_rtti);
+                  symtable.foreach({$ifdef FPCPROCVAR}@{$endif}count_field_rtti,nil);
                   rttiList.concat(Tai_const.Create_32bit(count));
-                  symtable.foreach({$ifdef FPCPROCVAR}@{$endif}write_field_rtti);
+                  symtable.foreach({$ifdef FPCPROCVAR}@{$endif}write_field_rtti,nil);
                 end;
              end;
            fullrtti :
@@ -4993,7 +4990,7 @@ implementation
                  count:=0;
 
                { write it }
-               symtable.foreach({$ifdef FPCPROCVAR}@{$endif}count_published_properties);
+               symtable.foreach({$ifdef FPCPROCVAR}@{$endif}count_published_properties,nil);
                rttiList.concat(Tai_const.Create_16bit(count));
 
                { write unit name }
@@ -5002,7 +4999,7 @@ implementation
 
                { write published properties count }
                count:=0;
-               symtable.foreach({$ifdef FPCPROCVAR}@{$endif}count_published_properties);
+               symtable.foreach({$ifdef FPCPROCVAR}@{$endif}count_published_properties,nil);
                rttiList.concat(Tai_const.Create_16bit(count));
 
                { count is used to write nameindex   }
@@ -5014,7 +5011,7 @@ implementation
                else
                  count:=0;
 
-               symtable.foreach({$ifdef FPCPROCVAR}@{$endif}write_property_info);
+               symtable.foreach({$ifdef FPCPROCVAR}@{$endif}write_property_info,nil);
              end;
          end;
       end;
@@ -5142,10 +5139,10 @@ implementation
       begin
         for i:=1 to count do
           with timplintfentry(finterfaces.search(i)) do
-            resolvedef(tdef(intf));
+            resolvedef(pointer(intf));
       end;
 
-    procedure timplementedinterfaces.addintfref(def: tdef);
+    procedure timplementedinterfaces.addintfref(def: pointer);
       begin
         finterfaces.insert(timplintfentry.create(tobjectdef(def)));
       end;
@@ -5479,7 +5476,24 @@ implementation
 end.
 {
   $Log$
-  Revision 1.75  2002-04-25 20:16:39  peter
+  Revision 1.76  2002-05-12 16:53:10  peter
+    * moved entry and exitcode to ncgutil and cgobj
+    * foreach gets extra argument for passing local data to the
+      iterator function
+    * -CR checks also class typecasts at runtime by changing them
+      into as
+    * fixed compiler to cycle with the -CR option
+    * fixed stabs with elf writer, finally the global variables can
+      be watched
+    * removed a lot of routines from cga unit and replaced them by
+      calls to cgobj
+    * u32bit-s32bit updates for and,or,xor nodes. When one element is
+      u32bit then the other is typecasted also to u32bit without giving
+      a rangecheck warning/error.
+    * fixed pascal calling method with reversing also the high tree in
+      the parast, detected by tcalcst3 test
+
+  Revision 1.75  2002/04/25 20:16:39  peter
     * moved more routines from cga/n386util
 
   Revision 1.74  2002/04/23 19:16:35  peter

+ 21 - 4
compiler/symppu.pas

@@ -35,7 +35,7 @@ interface
          procedure checkerror;
          procedure getguid(var g: tguid);
          procedure getposinfo(var p:tfileposinfo);
-         function  getderef : tsymtableentry;
+         function  getderef : pointer;
          function  getsymlist:tsymlist;
          procedure gettype(var t:ttype);
          procedure putguid(const g: tguid);
@@ -101,7 +101,7 @@ implementation
       end;
 
 
-    function tcompilerppufile.getderef : tsymtableentry;
+    function tcompilerppufile.getderef : pointer;
       var
         hp,p : tderef;
         b : tdereftype;
@@ -132,7 +132,7 @@ implementation
               end;
           end;
         until false;
-        getderef:=tsymtableentry(p);
+        getderef:=p;
       end;
 
 
@@ -388,7 +388,24 @@ implementation
 end.
 {
   $Log$
-  Revision 1.8  2002-04-19 15:40:40  peter
+  Revision 1.9  2002-05-12 16:53:15  peter
+    * moved entry and exitcode to ncgutil and cgobj
+    * foreach gets extra argument for passing local data to the
+      iterator function
+    * -CR checks also class typecasts at runtime by changing them
+      into as
+    * fixed compiler to cycle with the -CR option
+    * fixed stabs with elf writer, finally the global variables can
+      be watched
+    * removed a lot of routines from cga unit and replaced them by
+      calls to cgobj
+    * u32bit-s32bit updates for and,or,xor nodes. When one element is
+      u32bit then the other is typecasted also to u32bit without giving
+      a rangecheck warning/error.
+    * fixed pascal calling method with reversing also the high tree in
+      the parast, detected by tcalcst3 test
+
+  Revision 1.8  2002/04/19 15:40:40  peter
     * optimize tfileposinfo writing, this reduces the ppu size with 20%
 
   Revision 1.7  2001/10/21 12:33:07  peter

+ 32 - 11
compiler/symsym.pas

@@ -325,9 +325,9 @@ interface
                                      currently be parsed procedure }
        aktprocdef : tprocdef;
 
-       aktcallprocdef : tprocdef;  { pointer to the definition of the
-                                     currently called procedure,
-                                     only set/unset in ncal }
+       aktcallprocdef : tabstractprocdef;  { pointer to the definition of the
+                                             currently called procedure,
+                                             only set/unset in ncal }
 
        aktvarsym : tvarsym;     { pointer to the symbol for the
                                      currently read var, only used
@@ -686,9 +686,12 @@ implementation
          make_ref:=old_make_ref;
          typ:=unitsym;
          unitsymtable:=ref;
-         prevsym:=tglobalsymtable(ref).unitsym;
-         tglobalsymtable(ref).unitsym:=self;
-         refs:=0;
+         if assigned(ref) and
+            (ref.symtabletype=globalsymtable) then
+          begin
+            prevsym:=tglobalsymtable(ref).unitsym;
+            tglobalsymtable(ref).unitsym:=self;
+          end;
       end;
 
     constructor tunitsym.load(ppufile:tcompilerppufile);
@@ -706,7 +709,8 @@ implementation
     procedure tunitsym.restoreunitsym;
       var pus,ppus : tunitsym;
       begin
-         if assigned(unitsymtable) then
+         if assigned(unitsymtable) and
+            (unitsymtable.symtabletype=globalsymtable) then
            begin
              ppus:=nil;
              pus:=tglobalsymtable(unitsymtable).unitsym;
@@ -840,7 +844,7 @@ implementation
          p:=defs;
          while assigned(p) do
            begin
-             resolvedef(tdef(p^.def));
+             resolvedef(pointer(p^.def));
              p:=p^.next;
            end;
       end;
@@ -1018,7 +1022,7 @@ implementation
       begin
         if (ppo_is_override in propoptions) then
          begin
-           resolvesym(tsym(propoverriden));
+           resolvesym(pointer(propoverriden));
            dooverride(propoverriden);
          end
         else
@@ -2181,7 +2185,7 @@ implementation
 
     procedure tenumsym.deref;
       begin
-         resolvedef(tdef(definition));
+         resolvedef(pointer(definition));
          order;
       end;
 
@@ -2513,7 +2517,24 @@ implementation
 end.
 {
   $Log$
-  Revision 1.35  2002-04-19 15:46:03  peter
+  Revision 1.36  2002-05-12 16:53:15  peter
+    * moved entry and exitcode to ncgutil and cgobj
+    * foreach gets extra argument for passing local data to the
+      iterator function
+    * -CR checks also class typecasts at runtime by changing them
+      into as
+    * fixed compiler to cycle with the -CR option
+    * fixed stabs with elf writer, finally the global variables can
+      be watched
+    * removed a lot of routines from cga unit and replaced them by
+      calls to cgobj
+    * u32bit-s32bit updates for and,or,xor nodes. When one element is
+      u32bit then the other is typecasted also to u32bit without giving
+      a rangecheck warning/error.
+    * fixed pascal calling method with reversing also the high tree in
+      the parast, detected by tcalcst3 test
+
+  Revision 1.35  2002/04/19 15:46:03  peter
     * mangledname rewrite, tprocdef.mangledname is now created dynamicly
       in most cases and not written to the ppu
     * add mangeledname_prefix() routine to generate the prefix of

+ 61 - 47
compiler/symtable.pas

@@ -47,21 +47,20 @@ interface
        tstoredsymtable = class(tsymtable)
        private
           b_needs_init_final : boolean;
-          procedure _needs_init_final(p : tnamedindexitem);
-          procedure check_forward(sym : TNamedIndexItem);
-          procedure labeldefined(p : TNamedIndexItem);
-          procedure unitsymbolused(p : TNamedIndexItem);
-          procedure varsymbolused(p : TNamedIndexItem);
-          procedure TestPrivate(p : TNamedIndexItem);
-          procedure objectprivatesymbolused(p : TNamedIndexItem);
+          procedure _needs_init_final(p : tnamedindexitem;arg:pointer);
+          procedure check_forward(sym : TNamedIndexItem;arg:pointer);
+          procedure labeldefined(p : TNamedIndexItem;arg:pointer);
+          procedure unitsymbolused(p : TNamedIndexItem;arg:pointer);
+          procedure varsymbolused(p : TNamedIndexItem;arg:pointer);
+          procedure TestPrivate(p : TNamedIndexItem;arg:pointer);
+          procedure objectprivatesymbolused(p : TNamedIndexItem;arg:pointer);
 {$ifdef GDB}
        private
-          asmoutput : taasmoutput;
-          procedure concatstab(p : TNamedIndexItem);
-          procedure resetstab(p : TNamedIndexItem);
-          procedure concattypestab(p : TNamedIndexItem);
+          procedure concatstab(p : TNamedIndexItem;arg:pointer);
+          procedure resetstab(p : TNamedIndexItem;arg:pointer);
+          procedure concattypestab(p : TNamedIndexItem;arg:pointer);
 {$endif}
-          procedure unchain_overloads(p : TNamedIndexItem);
+          procedure unchain_overloads(p : TNamedIndexItem;arg:pointer);
           procedure loaddefs(ppufile:tcompilerppufile);
           procedure loadsyms(ppufile:tcompilerppufile);
           procedure writedefs(ppufile:tcompilerppufile);
@@ -88,7 +87,7 @@ interface
           procedure concatstabto(asmlist : taasmoutput);virtual;
           function  getnewtypecount : word; override;
 {$endif GDB}
-          procedure testfordefaultproperty(p : TNamedIndexItem);
+          procedure testfordefaultproperty(p : TNamedIndexItem;arg:pointer);
        end;
 
        tabstractrecordsymtable = class(tstoredsymtable)
@@ -451,14 +450,14 @@ implementation
              ibsymref :
                begin
                  sym:=tstoredsym(ppufile.getderef);
-                 resolvesym(tsym(sym));
+                 resolvesym(pointer(sym));
                  if assigned(sym) then
                    sym.load_references(ppufile,locals);
                end;
              ibdefref :
                begin
                  prdef:=tstoreddef(ppufile.getderef);
-                 resolvedef(tdef(prdef));
+                 resolvedef(pointer(prdef));
                  if assigned(prdef) then
                    begin
                      if prdef.deftype<>procdef then
@@ -669,7 +668,7 @@ implementation
              Callbacks
 **************************************}
 
-    procedure TStoredSymtable.check_forward(sym : TNamedIndexItem);
+    procedure TStoredSymtable.check_forward(sym : TNamedIndexItem;arg:pointer);
       begin
          if tsym(sym).typ=procsym then
            tprocsym(sym).check_forward
@@ -684,7 +683,7 @@ implementation
       end;
 
 
-    procedure TStoredSymtable.labeldefined(p : TNamedIndexItem);
+    procedure TStoredSymtable.labeldefined(p : TNamedIndexItem;arg:pointer);
       begin
         if (tsym(p).typ=labelsym) and
            not(tlabelsym(p).defined) then
@@ -697,18 +696,18 @@ implementation
       end;
 
 
-    procedure TStoredSymtable.unitsymbolused(p : TNamedIndexItem);
+    procedure TStoredSymtable.unitsymbolused(p : TNamedIndexItem;arg:pointer);
       begin
          if (tsym(p).typ=unitsym) and
             (tunitsym(p).refs=0) and
             { do not claim for unit name itself !! }
+            assigned(tunitsym(p).unitsymtable) and
             (tunitsym(p).unitsymtable.symtabletype=globalsymtable) then
-           MessagePos2(tsym(p).fileinfo,sym_n_unit_not_used,
-             p.name,current_module.modulename^);
+           MessagePos2(tsym(p).fileinfo,sym_n_unit_not_used,p.name,current_module.modulename^);
       end;
 
 
-    procedure TStoredSymtable.varsymbolused(p : TNamedIndexItem);
+    procedure TStoredSymtable.varsymbolused(p : TNamedIndexItem;arg:pointer);
       begin
          if (tsym(p).typ=varsym) and
             ((tsym(p).owner.symtabletype in
@@ -773,14 +772,14 @@ implementation
       end;
 
 
-    procedure TStoredSymtable.TestPrivate(p : TNamedIndexItem);
+    procedure TStoredSymtable.TestPrivate(p : TNamedIndexItem;arg:pointer);
       begin
         if sp_private in tsym(p).symoptions then
-          varsymbolused(p);
+          varsymbolused(p,arg);
       end;
 
 
-    procedure TStoredSymtable.objectprivatesymbolused(p : TNamedIndexItem);
+    procedure TStoredSymtable.objectprivatesymbolused(p : TNamedIndexItem;arg:pointer);
       begin
          {
            Don't test simple object aliases PM
@@ -788,11 +787,11 @@ implementation
          if (tsym(p).typ=typesym) and
             (ttypesym(p).restype.def.deftype=objectdef) and
             (ttypesym(p).restype.def.typesym=tsym(p)) then
-           tobjectdef(ttypesym(p).restype.def).symtable.foreach({$ifdef FPCPROCVAR}@{$endif}TestPrivate);
+           tobjectdef(ttypesym(p).restype.def).symtable.foreach({$ifdef FPCPROCVAR}@{$endif}TestPrivate,nil);
       end;
 
 
-    procedure tstoredsymtable.unchain_overloads(p : TNamedIndexItem);
+    procedure tstoredsymtable.unchain_overloads(p : TNamedIndexItem;arg:pointer);
       begin
          if tsym(p).typ=procsym then
            tprocsym(p).unchain_overload;
@@ -800,24 +799,24 @@ implementation
 
 {$ifdef GDB}
 
-    procedure TStoredSymtable.concatstab(p : TNamedIndexItem);
+    procedure TStoredSymtable.concatstab(p : TNamedIndexItem;arg:pointer);
       begin
         if tsym(p).typ <> procsym then
-          tstoredsym(p).concatstabto(asmoutput);
+          tstoredsym(p).concatstabto(TAAsmOutput(arg));
       end;
 
-    procedure TStoredSymtable.resetstab(p : TNamedIndexItem);
+    procedure TStoredSymtable.resetstab(p : TNamedIndexItem;arg:pointer);
       begin
         if tsym(p).typ <> procsym then
           tstoredsym(p).isstabwritten:=false;
       end;
 
-    procedure TStoredSymtable.concattypestab(p : TNamedIndexItem);
+    procedure TStoredSymtable.concattypestab(p : TNamedIndexItem;arg:pointer);
       begin
         if tsym(p).typ = typesym then
          begin
            tstoredsym(p).isstabwritten:=false;
-           tstoredsym(p).concatstabto(asmoutput);
+           tstoredsym(p).concatstabto(TAAsmOutput(arg));
          end;
       end;
 
@@ -894,48 +893,47 @@ implementation
     { checks, if all procsyms and methods are defined }
     procedure tstoredsymtable.check_forwards;
       begin
-         foreach({$ifdef FPCPROCVAR}@{$endif}check_forward);
+         foreach({$ifdef FPCPROCVAR}@{$endif}check_forward,nil);
       end;
 
 
     procedure tstoredsymtable.checklabels;
       begin
-         foreach({$ifdef FPCPROCVAR}@{$endif}labeldefined);
+         foreach({$ifdef FPCPROCVAR}@{$endif}labeldefined,nil);
       end;
 
 
     procedure tstoredsymtable.allunitsused;
       begin
-         foreach({$ifdef FPCPROCVAR}@{$endif}unitsymbolused);
+         foreach({$ifdef FPCPROCVAR}@{$endif}unitsymbolused,nil);
       end;
 
 
     procedure tstoredsymtable.allsymbolsused;
       begin
-         foreach({$ifdef FPCPROCVAR}@{$endif}varsymbolused);
+         foreach({$ifdef FPCPROCVAR}@{$endif}varsymbolused,nil);
       end;
 
 
     procedure tstoredsymtable.allprivatesused;
       begin
-         foreach({$ifdef FPCPROCVAR}@{$endif}objectprivatesymbolused);
+         foreach({$ifdef FPCPROCVAR}@{$endif}objectprivatesymbolused,nil);
       end;
 
 
     procedure tstoredsymtable.unchain_overloaded;
       begin
-         foreach({$ifdef FPCPROCVAR}@{$endif}unchain_overloads);
+         foreach({$ifdef FPCPROCVAR}@{$endif}unchain_overloads,nil);
       end;
 
 
 {$ifdef GDB}
     procedure tstoredsymtable.concatstabto(asmlist : taasmoutput);
       begin
-        asmoutput:=asmlist;
         if symtabletype in [inlineparasymtable,inlinelocalsymtable] then
-          foreach({$ifdef FPCPROCVAR}@{$endif}resetstab);
+          foreach({$ifdef FPCPROCVAR}@{$endif}resetstab,nil);
 
-        foreach({$ifdef FPCPROCVAR}@{$endif}concatstab);
+        foreach({$ifdef FPCPROCVAR}@{$endif}concatstab,asmlist);
       end;
 {$endif}
 
@@ -944,7 +942,7 @@ implementation
     function tstoredsymtable.needs_init_final : boolean;
       begin
          b_needs_init_final:=false;
-         foreach({$ifdef FPCPROCVAR}@{$endif}_needs_init_final);
+         foreach({$ifdef FPCPROCVAR}@{$endif}_needs_init_final,nil);
          needs_init_final:=b_needs_init_final;
       end;
 
@@ -1009,7 +1007,7 @@ implementation
       end;
 
 
-    procedure TStoredSymtable._needs_init_final(p : tnamedindexitem);
+    procedure TStoredSymtable._needs_init_final(p : tnamedindexitem;arg:pointer);
       begin
          if (not b_needs_init_final) and
             (tsym(p).typ=varsym) and
@@ -1363,8 +1361,7 @@ implementation
                     do_count_dbx:=assigned(dbx_counter);
                   end;
              end;
-           asmoutput:=asmlist;
-           foreach({$ifdef FPCPROCVAR}@{$endif}concattypestab);
+           foreach({$ifdef FPCPROCVAR}@{$endif}concattypestab,asmlist);
            if cs_gdb_dbx in aktglobalswitches then
              begin
                 if (current_module.globalsymtable<>self) then
@@ -1886,7 +1883,7 @@ implementation
    var
       _defaultprop : tpropertysym;
 
-   procedure tstoredsymtable.testfordefaultproperty(p : TNamedIndexItem);
+   procedure tstoredsymtable.testfordefaultproperty(p : TNamedIndexItem;arg:pointer);
      begin
         if (tsym(p).typ=propertysym) and
            (ppo_defaultproperty in tpropertysym(p).propoptions) then
@@ -1900,7 +1897,7 @@ implementation
         _defaultprop:=nil;
         while assigned(pd) do
           begin
-             pd.symtable.foreach({$ifdef FPCPROCVAR}@{$endif}tstoredsymtable(pd.symtable).testfordefaultproperty);
+             pd.symtable.foreach({$ifdef FPCPROCVAR}@{$endif}tstoredsymtable(pd.symtable).testfordefaultproperty,nil);
              if assigned(_defaultprop) then
                break;
              pd:=pd.childof;
@@ -2063,7 +2060,24 @@ implementation
 end.
 {
   $Log$
-  Revision 1.57  2002-04-04 19:06:05  peter
+  Revision 1.58  2002-05-12 16:53:15  peter
+    * moved entry and exitcode to ncgutil and cgobj
+    * foreach gets extra argument for passing local data to the
+      iterator function
+    * -CR checks also class typecasts at runtime by changing them
+      into as
+    * fixed compiler to cycle with the -CR option
+    * fixed stabs with elf writer, finally the global variables can
+      be watched
+    * removed a lot of routines from cga unit and replaced them by
+      calls to cgobj
+    * u32bit-s32bit updates for and,or,xor nodes. When one element is
+      u32bit then the other is typecasted also to u32bit without giving
+      a rangecheck warning/error.
+    * fixed pascal calling method with reversing also the high tree in
+      the parast, detected by tcalcst3 test
+
+  Revision 1.57  2002/04/04 19:06:05  peter
     * removed unused units
     * use tlocation.size in cg.a_*loc*() routines
 

+ 28 - 11
compiler/symtype.pas

@@ -137,8 +137,8 @@ interface
 
 
     { resolving }
-    procedure resolvesym(var sym:tsym);
-    procedure resolvedef(var def:tdef);
+    procedure resolvesym(var sym:pointer);
+    procedure resolvedef(var def:pointer);
 
 
 implementation
@@ -299,11 +299,11 @@ implementation
       begin
         if assigned(sym) then
          begin
-           resolvesym(sym);
+           resolvesym(pointer(sym));
            setsym(sym);
          end
         else
-         resolvedef(def);
+         resolvedef(pointer(def));
       end;
 
 {****************************************************************************
@@ -417,12 +417,12 @@ implementation
       var
         hp : psymlistitem;
       begin
-        resolvedef(def);
+        resolvedef(pointer(def));
         hp:=firstsym;
         while assigned(hp) do
          begin
            if assigned(hp^.sym) then
-            resolvesym(hp^.sym);
+            resolvesym(pointer(hp^.sym));
            hp:=hp^.next;
          end;
       end;
@@ -500,12 +500,12 @@ implementation
       end;
 
 
-    procedure resolvedef(var def:tdef);
+    procedure resolvedef(var def:pointer);
       var
         st   : tsymtable;
         idx  : word;
       begin
-        resolvederef(tderef(def),st,idx);
+        resolvederef(tderef(pointer(def)),st,idx);
         if assigned(st) then
          def:=tdef(st.getdefnr(idx))
         else
@@ -513,12 +513,12 @@ implementation
       end;
 
 
-    procedure resolvesym(var sym:tsym);
+    procedure resolvesym(var sym:pointer);
       var
         st   : tsymtable;
         idx  : word;
       begin
-        resolvederef(tderef(sym),st,idx);
+        resolvederef(tderef(pointer(sym)),st,idx);
         if assigned(st) then
          sym:=tsym(st.getsymnr(idx))
         else
@@ -528,7 +528,24 @@ implementation
 end.
 {
   $Log$
-  Revision 1.14  2002-04-19 15:46:04  peter
+  Revision 1.15  2002-05-12 16:53:15  peter
+    * moved entry and exitcode to ncgutil and cgobj
+    * foreach gets extra argument for passing local data to the
+      iterator function
+    * -CR checks also class typecasts at runtime by changing them
+      into as
+    * fixed compiler to cycle with the -CR option
+    * fixed stabs with elf writer, finally the global variables can
+      be watched
+    * removed a lot of routines from cga unit and replaced them by
+      calls to cgobj
+    * u32bit-s32bit updates for and,or,xor nodes. When one element is
+      u32bit then the other is typecasted also to u32bit without giving
+      a rangecheck warning/error.
+    * fixed pascal calling method with reversing also the high tree in
+      the parast, detected by tcalcst3 test
+
+  Revision 1.14  2002/04/19 15:46:04  peter
     * mangledname rewrite, tprocdef.mangledname is now created dynamicly
       in most cases and not written to the ppu
     * add mangeledname_prefix() routine to generate the prefix of

+ 21 - 15
compiler/targets/t_wdosx.pas

@@ -30,19 +30,8 @@ interface
 implementation
 
     uses
-{$ifdef Delphi}
-       dmisc,
-{$else Delphi}
-       dos,
-{$endif Delphi}
-       cutils,cclasses,
-       aasm,fmodule,globtype,globals,systems,verbose,
-       symconst,symsym,
-       script,gendef,
-       cpubase,cpuasm,
-{$ifdef GDB}
-       gdb,
-{$endif}
+       cutils,
+       fmodule,globals,systems,
        import,export,link,t_win32;
 
   type
@@ -176,7 +165,24 @@ end.
 
 {
   $Log$
-  Revision 1.4  2002-04-22 18:19:22  carl
+  Revision 1.5  2002-05-12 16:53:18  peter
+    * moved entry and exitcode to ncgutil and cgobj
+    * foreach gets extra argument for passing local data to the
+      iterator function
+    * -CR checks also class typecasts at runtime by changing them
+      into as
+    * fixed compiler to cycle with the -CR option
+    * fixed stabs with elf writer, finally the global variables can
+      be watched
+    * removed a lot of routines from cga unit and replaced them by
+      calls to cgobj
+    * u32bit-s32bit updates for and,or,xor nodes. When one element is
+      u32bit then the other is typecasted also to u32bit without giving
+      a rangecheck warning/error.
+    * fixed pascal calling method with reversing also the high tree in
+      the parast, detected by tcalcst3 test
+
+  Revision 1.4  2002/04/22 18:19:22  carl
   - remove use_bound_instruction field
 
   Revision 1.3  2002/04/20 21:43:18  carl
@@ -190,4 +196,4 @@ end.
   Revision 1.1  2002/04/04 18:09:49  carl
   + added wdosx patch from Pavel
 
-}
+}

+ 19 - 2
compiler/types.pas

@@ -271,7 +271,7 @@ interface
 implementation
 
     uses
-       globtype,cpubase,tokens,verbose,
+       globtype,tokens,verbose,
        symtable;
 
 
@@ -1970,7 +1970,24 @@ implementation
 end.
 {
   $Log$
-  Revision 1.69  2002-04-25 20:16:39  peter
+  Revision 1.70  2002-05-12 16:53:16  peter
+    * moved entry and exitcode to ncgutil and cgobj
+    * foreach gets extra argument for passing local data to the
+      iterator function
+    * -CR checks also class typecasts at runtime by changing them
+      into as
+    * fixed compiler to cycle with the -CR option
+    * fixed stabs with elf writer, finally the global variables can
+      be watched
+    * removed a lot of routines from cga unit and replaced them by
+      calls to cgobj
+    * u32bit-s32bit updates for and,or,xor nodes. When one element is
+      u32bit then the other is typecasted also to u32bit without giving
+      a rangecheck warning/error.
+    * fixed pascal calling method with reversing also the high tree in
+      the parast, detected by tcalcst3 test
+
+  Revision 1.69  2002/04/25 20:16:39  peter
     * moved more routines from cga/n386util
 
   Revision 1.68  2002/04/15 19:08:22  carl

+ 19 - 2
compiler/utils/ppudump.pp

@@ -234,7 +234,7 @@ var
 begin
   l1:=ppufile.getlongint;
   l2:=ppufile.getlongint;
-  getint64:=(int64(l2) shl 32) or l1;
+  getint64:=(int64(l2) shl 32) or qword(l1);
 end;
 
 Procedure ReadLinkContainer(const prefix:string);
@@ -1774,7 +1774,24 @@ begin
 end.
 {
   $Log$
-  Revision 1.21  2002-04-23 13:12:58  peter
+  Revision 1.22  2002-05-12 16:53:18  peter
+    * moved entry and exitcode to ncgutil and cgobj
+    * foreach gets extra argument for passing local data to the
+      iterator function
+    * -CR checks also class typecasts at runtime by changing them
+      into as
+    * fixed compiler to cycle with the -CR option
+    * fixed stabs with elf writer, finally the global variables can
+      be watched
+    * removed a lot of routines from cga unit and replaced them by
+      calls to cgobj
+    * u32bit-s32bit updates for and,or,xor nodes. When one element is
+      u32bit then the other is typecasted also to u32bit without giving
+      a rangecheck warning/error.
+    * fixed pascal calling method with reversing also the high tree in
+      the parast, detected by tcalcst3 test
+
+  Revision 1.21  2002/04/23 13:12:58  peter
     * updated for posinfo change
     * updated for mangledname change
     * include i386 registers, removed reference to cpubase unit that would

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно