Browse Source

* paraloc branch merged

peter 21 years ago
parent
commit
33a834821f

+ 101 - 37
compiler/cg64f32.pas

@@ -33,8 +33,8 @@ unit cg64f32;
 
 
     uses
     uses
        aasmbase,aasmtai,aasmcpu,
        aasmbase,aasmtai,aasmcpu,
-       cpuinfo, cpubase,cpupara,
-       cgbase, cgobj,
+       cpuinfo,cpubase,cpupara,
+       cgbase,cgobj,parabase,
        node,symtype
        node,symtype
 {$ifdef delphi}
 {$ifdef delphi}
        ,dmisc
        ,dmisc
@@ -46,8 +46,6 @@ unit cg64f32;
          to handle 64-bit integers.
          to handle 64-bit integers.
       }
       }
       tcg64f32 = class(tcg64)
       tcg64f32 = class(tcg64)
-        procedure a_reg_alloc(list : taasmoutput;r : tregister64);override;
-        procedure a_reg_dealloc(list : taasmoutput;r : tregister64);override;
         procedure a_load64_const_ref(list : taasmoutput;value : int64;const ref : treference);override;
         procedure a_load64_const_ref(list : taasmoutput;value : int64;const ref : treference);override;
         procedure a_load64_reg_ref(list : taasmoutput;reg : tregister64;const ref : treference);override;
         procedure a_load64_reg_ref(list : taasmoutput;reg : tregister64;const ref : treference);override;
         procedure a_load64_ref_reg(list : taasmoutput;const ref : treference;reg : tregister64);override;
         procedure a_load64_ref_reg(list : taasmoutput;const ref : treference;reg : tregister64);override;
@@ -72,10 +70,10 @@ unit cg64f32;
         procedure a_op64_loc_reg(list : taasmoutput;op:TOpCG;const l : tlocation;reg : tregister64);override;
         procedure a_op64_loc_reg(list : taasmoutput;op:TOpCG;const l : tlocation;reg : tregister64);override;
         procedure a_op64_const_ref(list : taasmoutput;op:TOpCG;value : int64;const ref : treference);override;
         procedure a_op64_const_ref(list : taasmoutput;op:TOpCG;value : int64;const ref : treference);override;
 
 
-        procedure a_param64_reg(list : taasmoutput;reg : tregister64;const locpara : tparalocation);override;
-        procedure a_param64_const(list : taasmoutput;value : int64;const locpara : tparalocation);override;
-        procedure a_param64_ref(list : taasmoutput;const r : treference;const locpara : tparalocation);override;
-        procedure a_param64_loc(list : taasmoutput;const l : tlocation;const locpara : tparalocation);override;
+        procedure a_param64_reg(list : taasmoutput;reg : tregister64;const paraloc : tcgpara);override;
+        procedure a_param64_const(list : taasmoutput;value : int64;const paraloc : tcgpara);override;
+        procedure a_param64_ref(list : taasmoutput;const r : treference;const paraloc : tcgpara);override;
+        procedure a_param64_loc(list : taasmoutput;const l : tlocation;const paraloc : tcgpara);override;
 
 
         {# This routine tries to optimize the a_op64_const_reg operation, by
         {# This routine tries to optimize the a_op64_const_reg operation, by
            removing superfluous opcodes. Returns TRUE if normal processing
            removing superfluous opcodes. Returns TRUE if normal processing
@@ -93,9 +91,9 @@ unit cg64f32;
   implementation
   implementation
 
 
     uses
     uses
-       globtype,globals,systems,
+       globtype,systems,
        verbose,
        verbose,
-       symbase,symconst,symdef,defutil,tgobj,paramgr;
+       symbase,symconst,symdef,defutil,paramgr;
 
 
 {****************************************************************************
 {****************************************************************************
                                      Helpers
                                      Helpers
@@ -114,23 +112,67 @@ unit cg64f32;
       end;
       end;
 
 
 
 
-{****************************************************************************
-                                   TCG64F32
-****************************************************************************}
-
-    procedure tcg64f32.a_reg_alloc(list : taasmoutput;r : tregister64);
+    procedure splitparaloc64(const cgpara:tcgpara;var cgparalo,cgparahi:tcgpara);
+      var
+        paraloclo,
+        paralochi : pcgparalocation;
       begin
       begin
-         list.concat(tai_regalloc.alloc(r.reglo));
-         list.concat(tai_regalloc.alloc(r.reghi));
+        if not(cgpara.size in [OS_64,OS_S64]) then
+          internalerror(200408231);
+        if not assigned(cgpara.location) then
+          internalerror(200408201);
+        { init lo/hi para }
+        cgparahi.reset;
+        if cgpara.size=OS_S64 then
+          cgparahi.size:=OS_S32
+        else
+          cgparahi.size:=OS_32;
+        cgparahi.alignment:=cgpara.alignment;
+        paralochi:=cgparahi.add_location;
+        cgparalo.reset;
+        cgparalo.size:=OS_32;
+        cgparalo.alignment:=cgpara.alignment;
+        paraloclo:=cgparalo.add_location;
+        { 2 parameter fields? }
+        if assigned(cgpara.location^.next) then
+          begin
+            if target_info.endian = endian_big then
+              begin
+                { low is in second location }
+                move(cgpara.location^.next^,paraloclo^,sizeof(paraloclo^));
+                move(cgpara.location^,paralochi^,sizeof(paralochi^));
+              end
+            else
+              begin
+                { low is in first location }
+                move(cgpara.location^,paraloclo^,sizeof(paraloclo^));
+                move(cgpara.location^.next^,paralochi^,sizeof(paralochi^));
+              end;
+          end
+        else
+          begin
+            { single parameter, this can only be in memory }
+            if cgpara.location^.loc<>LOC_REFERENCE then
+              internalerror(200408282);
+            move(cgpara.location^,paraloclo^,sizeof(paraloclo^));
+            move(cgpara.location^,paralochi^,sizeof(paralochi^));
+            { for big endian low is at +4, for little endian high }
+            if target_info.endian = endian_big then
+              inc(cgparalo.location^.reference.offset,tcgsize2size[cgparahi.size])
+            else
+              inc(cgparahi.location^.reference.offset,tcgsize2size[cgparalo.size]);
+          end;
+        { fix size }
+        paraloclo^.size:=cgparalo.size;
+        paraloclo^.next:=nil;
+        paralochi^.size:=cgparahi.size;
+        paralochi^.next:=nil;
       end;
       end;
 
 
 
 
-    procedure tcg64f32.a_reg_dealloc(list : taasmoutput;r : tregister64);
-      begin
-         list.concat(tai_regalloc.dealloc(r.reglo));
-         list.concat(tai_regalloc.dealloc(r.reghi));
-      end;
-
+{****************************************************************************
+                                   TCG64F32
+****************************************************************************}
 
 
     procedure tcg64f32.a_load64_reg_ref(list : taasmoutput;reg : tregister64;const ref : treference);
     procedure tcg64f32.a_load64_reg_ref(list : taasmoutput;reg : tregister64;const ref : treference);
       var
       var
@@ -450,32 +492,42 @@ unit cg64f32;
       end;
       end;
 
 
 
 
-    procedure tcg64f32.a_param64_reg(list : taasmoutput;reg : tregister64;const locpara : tparalocation);
+    procedure tcg64f32.a_param64_reg(list : taasmoutput;reg : tregister64;const paraloc : tcgpara);
       var
       var
-        tmplochi,tmploclo: tparalocation;
+        tmplochi,tmploclo: tcgpara;
       begin
       begin
-        paramanager.splitparaloc64(locpara,tmploclo,tmplochi);
+        tmploclo.init;
+        tmplochi.init;
+        splitparaloc64(paraloc,tmploclo,tmplochi);
         cg.a_param_reg(list,OS_32,reg.reghi,tmplochi);
         cg.a_param_reg(list,OS_32,reg.reghi,tmplochi);
         cg.a_param_reg(list,OS_32,reg.reglo,tmploclo);
         cg.a_param_reg(list,OS_32,reg.reglo,tmploclo);
+        tmploclo.done;
+        tmplochi.done;
       end;
       end;
 
 
 
 
-    procedure tcg64f32.a_param64_const(list : taasmoutput;value : int64;const locpara : tparalocation);
+    procedure tcg64f32.a_param64_const(list : taasmoutput;value : int64;const paraloc : tcgpara);
       var
       var
-        tmplochi,tmploclo: tparalocation;
+        tmplochi,tmploclo: tcgpara;
       begin
       begin
-        paramanager.splitparaloc64(locpara,tmploclo,tmplochi);
+        tmploclo.init;
+        tmplochi.init;
+        splitparaloc64(paraloc,tmploclo,tmplochi);
         cg.a_param_const(list,OS_32,aint(hi(value)),tmplochi);
         cg.a_param_const(list,OS_32,aint(hi(value)),tmplochi);
         cg.a_param_const(list,OS_32,aint(lo(value)),tmploclo);
         cg.a_param_const(list,OS_32,aint(lo(value)),tmploclo);
+        tmploclo.done;
+        tmplochi.done;
       end;
       end;
 
 
 
 
-    procedure tcg64f32.a_param64_ref(list : taasmoutput;const r : treference;const locpara : tparalocation);
+    procedure tcg64f32.a_param64_ref(list : taasmoutput;const r : treference;const paraloc : tcgpara);
       var
       var
         tmprefhi,tmpreflo : treference;
         tmprefhi,tmpreflo : treference;
-        tmploclo,tmplochi : tparalocation;
+        tmploclo,tmplochi : tcgpara;
       begin
       begin
-        paramanager.splitparaloc64(locpara,tmploclo,tmplochi);
+        tmploclo.init;
+        tmplochi.init;
+        splitparaloc64(paraloc,tmploclo,tmplochi);
         tmprefhi:=r;
         tmprefhi:=r;
         tmpreflo:=r;
         tmpreflo:=r;
         if target_info.endian=endian_big then
         if target_info.endian=endian_big then
@@ -484,20 +536,22 @@ unit cg64f32;
           inc(tmprefhi.offset,4);
           inc(tmprefhi.offset,4);
         cg.a_param_ref(list,OS_32,tmprefhi,tmplochi);
         cg.a_param_ref(list,OS_32,tmprefhi,tmplochi);
         cg.a_param_ref(list,OS_32,tmpreflo,tmploclo);
         cg.a_param_ref(list,OS_32,tmpreflo,tmploclo);
+        tmploclo.done;
+        tmplochi.done;
       end;
       end;
 
 
 
 
-    procedure tcg64f32.a_param64_loc(list : taasmoutput;const l:tlocation;const locpara : tparalocation);
+    procedure tcg64f32.a_param64_loc(list : taasmoutput;const l:tlocation;const paraloc : tcgpara);
       begin
       begin
         case l.loc of
         case l.loc of
           LOC_REGISTER,
           LOC_REGISTER,
           LOC_CREGISTER :
           LOC_CREGISTER :
-            a_param64_reg(list,l.register64,locpara);
+            a_param64_reg(list,l.register64,paraloc);
           LOC_CONSTANT :
           LOC_CONSTANT :
-            a_param64_const(list,l.value64,locpara);
+            a_param64_const(list,l.value64,paraloc);
           LOC_CREFERENCE,
           LOC_CREFERENCE,
           LOC_REFERENCE :
           LOC_REFERENCE :
-            a_param64_ref(list,l.reference,locpara);
+            a_param64_ref(list,l.reference,paraloc);
           else
           else
             internalerror(200203287);
             internalerror(200203287);
         end;
         end;
@@ -753,7 +807,17 @@ unit cg64f32;
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.61  2004-06-20 08:55:28  florian
+  Revision 1.62  2004-09-21 17:25:12  peter
+    * paraloc branch merged
+
+  Revision 1.61.4.2  2004/09/20 20:46:34  peter
+    * register allocation optimized for 64bit loading of parameters
+      and return values
+
+  Revision 1.61.4.1  2004/08/31 20:43:06  peter
+    * paraloc patch
+
+  Revision 1.61  2004/06/20 08:55:28  florian
     * logs truncated
     * logs truncated
 
 
   Revision 1.60  2004/06/18 15:16:46  peter
   Revision 1.60  2004/06/18 15:16:46  peter

+ 302 - 214
compiler/cgobj.pas

@@ -41,7 +41,7 @@ unit cgobj;
        dmisc,
        dmisc,
 {$endif}
 {$endif}
        cclasses,globtype,
        cclasses,globtype,
-       cpubase,cpuinfo,cgbase,
+       cpubase,cpuinfo,cgbase,parabase,
        aasmbase,aasmtai,aasmcpu,
        aasmbase,aasmtai,aasmcpu,
        symconst,symbase,symtype,symdef,symtable,rgobj
        symconst,symbase,symtype,symdef,symtable,rgobj
        ;
        ;
@@ -121,9 +121,9 @@ unit cgobj;
 
 
              @param(size size of the operand in the register)
              @param(size size of the operand in the register)
              @param(r register source of the operand)
              @param(r register source of the operand)
-             @param(locpara where the parameter will be stored)
+             @param(paraloc where the parameter will be stored)
           }
           }
-          procedure a_param_reg(list : taasmoutput;size : tcgsize;r : tregister;const locpara : tparalocation);virtual;
+          procedure a_param_reg(list : taasmoutput;size : tcgsize;r : tregister;const paraloc : TCGPara);virtual;
           {# Pass a parameter, which is a constant, to a routine.
           {# Pass a parameter, which is a constant, to a routine.
 
 
              A generic version is provided. This routine should
              A generic version is provided. This routine should
@@ -132,9 +132,9 @@ unit cgobj;
 
 
              @param(size size of the operand in constant)
              @param(size size of the operand in constant)
              @param(a value of constant to send)
              @param(a value of constant to send)
-             @param(locpara where the parameter will be stored)
+             @param(paraloc where the parameter will be stored)
           }
           }
-          procedure a_param_const(list : taasmoutput;size : tcgsize;a : aint;const locpara : tparalocation);virtual;
+          procedure a_param_const(list : taasmoutput;size : tcgsize;a : aint;const paraloc : TCGPara);virtual;
           {# Pass the value of a parameter, which is located in memory, to a routine.
           {# Pass the value of a parameter, which is located in memory, to a routine.
 
 
              A generic version is provided. This routine should
              A generic version is provided. This routine should
@@ -143,9 +143,9 @@ unit cgobj;
 
 
              @param(size size of the operand in constant)
              @param(size size of the operand in constant)
              @param(r Memory reference of value to send)
              @param(r Memory reference of value to send)
-             @param(locpara where the parameter will be stored)
+             @param(paraloc where the parameter will be stored)
           }
           }
-          procedure a_param_ref(list : taasmoutput;size : tcgsize;const r : treference;const locpara : tparalocation);virtual;
+          procedure a_param_ref(list : taasmoutput;size : tcgsize;const r : treference;const paraloc : TCGPara);virtual;
           {# Pass the value of a parameter, which can be located either in a register or memory location,
           {# Pass the value of a parameter, which can be located either in a register or memory location,
              to a routine.
              to a routine.
 
 
@@ -153,9 +153,9 @@ unit cgobj;
 
 
              @param(l location of the operand to send)
              @param(l location of the operand to send)
              @param(nr parameter number (starting from one) of routine (from left to right))
              @param(nr parameter number (starting from one) of routine (from left to right))
-             @param(locpara where the parameter will be stored)
+             @param(paraloc where the parameter will be stored)
           }
           }
-          procedure a_param_loc(list : taasmoutput;const l : tlocation;const locpara : tparalocation);
+          procedure a_param_loc(list : taasmoutput;const l : tlocation;const paraloc : TCGPara);
           {# Pass the address of a reference to a routine. This routine
           {# Pass the address of a reference to a routine. This routine
              will calculate the address of the reference, and pass this
              will calculate the address of the reference, and pass this
              calculated address as a parameter.
              calculated address as a parameter.
@@ -167,10 +167,10 @@ unit cgobj;
              @param(r reference to get address from)
              @param(r reference to get address from)
              @param(nr parameter number (starting from one) of routine (from left to right))
              @param(nr parameter number (starting from one) of routine (from left to right))
           }
           }
-          procedure a_paramaddr_ref(list : taasmoutput;const r : treference;const locpara : tparalocation);virtual;
+          procedure a_paramaddr_ref(list : taasmoutput;const r : treference;const paraloc : TCGPara);virtual;
 
 
-          { Copies a whole memory block to the stack, the locpara must be a memory location }
-          procedure a_param_copy_ref(list : taasmoutput;size : aint;const r : treference;const locpara : tparalocation);
+          { Copies a whole memory block to the stack, the paraloc must be a memory location }
+          procedure a_param_copy_ref(list : taasmoutput;size : aint;const r : treference;const paraloc : TCGPara);
           { Remarks:
           { Remarks:
             * If a method specifies a size you have only to take care
             * If a method specifies a size you have only to take care
               of that number of bits, i.e. load_const_reg with OP_8 must
               of that number of bits, i.e. load_const_reg with OP_8 must
@@ -189,9 +189,9 @@ unit cgobj;
           }
           }
 
 
           { Copy a parameter to a (temporary) reference }
           { Copy a parameter to a (temporary) reference }
-          procedure a_loadany_param_ref(list : taasmoutput;const locpara : tparalocation;const ref:treference;shuffle : pmmshuffle);virtual;
+          procedure a_loadany_param_ref(list : taasmoutput;const paraloc : TCGPara;const ref:treference;shuffle : pmmshuffle);virtual;
           { Copy a parameter to a register }
           { Copy a parameter to a register }
-          procedure a_loadany_param_reg(list : taasmoutput;const locpara : tparalocation;const reg:tregister;shuffle : pmmshuffle);virtual;
+          procedure a_loadany_param_reg(list : taasmoutput;const paraloc : TCGPara;const reg:tregister;shuffle : pmmshuffle);virtual;
 
 
           {# Emits instruction to call the method specified by symbol name.
           {# Emits instruction to call the method specified by symbol name.
              This routine must be overriden for each new target cpu.
              This routine must be overriden for each new target cpu.
@@ -222,8 +222,8 @@ unit cgobj;
           procedure a_loadfpu_reg_ref(list: taasmoutput; size: tcgsize; reg: tregister; const ref: treference); virtual; abstract;
           procedure a_loadfpu_reg_ref(list: taasmoutput; size: tcgsize; reg: tregister; const ref: treference); virtual; abstract;
           procedure a_loadfpu_loc_reg(list: taasmoutput; const loc: tlocation; const reg: tregister);
           procedure a_loadfpu_loc_reg(list: taasmoutput; const loc: tlocation; const reg: tregister);
           procedure a_loadfpu_reg_loc(list: taasmoutput; size: tcgsize; const reg: tregister; const loc: tlocation);
           procedure a_loadfpu_reg_loc(list: taasmoutput; size: tcgsize; const reg: tregister; const loc: tlocation);
-          procedure a_paramfpu_reg(list : taasmoutput;size : tcgsize;const r : tregister;const locpara : tparalocation);virtual;
-          procedure a_paramfpu_ref(list : taasmoutput;size : tcgsize;const ref : treference;const locpara : tparalocation);virtual;
+          procedure a_paramfpu_reg(list : taasmoutput;size : tcgsize;const r : tregister;const paraloc : TCGPara);virtual;
+          procedure a_paramfpu_ref(list : taasmoutput;size : tcgsize;const ref : treference;const paraloc : TCGPara);virtual;
 
 
           { vector register move instructions }
           { vector register move instructions }
           procedure a_loadmm_reg_reg(list: taasmoutput; fromsize, tosize : tcgsize;reg1, reg2: tregister;shuffle : pmmshuffle); virtual; abstract;
           procedure a_loadmm_reg_reg(list: taasmoutput; fromsize, tosize : tcgsize;reg1, reg2: tregister;shuffle : pmmshuffle); virtual; abstract;
@@ -231,9 +231,9 @@ unit cgobj;
           procedure a_loadmm_reg_ref(list: taasmoutput; fromsize, tosize : tcgsize;reg: tregister; const ref: treference;shuffle : pmmshuffle); virtual; abstract;
           procedure a_loadmm_reg_ref(list: taasmoutput; fromsize, tosize : tcgsize;reg: tregister; const ref: treference;shuffle : pmmshuffle); virtual; abstract;
           procedure a_loadmm_loc_reg(list: taasmoutput; size: tcgsize; const loc: tlocation; const reg: tregister;shuffle : pmmshuffle);
           procedure a_loadmm_loc_reg(list: taasmoutput; size: tcgsize; const loc: tlocation; const reg: tregister;shuffle : pmmshuffle);
           procedure a_loadmm_reg_loc(list: taasmoutput; size: tcgsize; const reg: tregister; const loc: tlocation;shuffle : pmmshuffle);
           procedure a_loadmm_reg_loc(list: taasmoutput; size: tcgsize; const reg: tregister; const loc: tlocation;shuffle : pmmshuffle);
-          procedure a_parammm_reg(list: taasmoutput; size: tcgsize; reg: tregister;const locpara : tparalocation;shuffle : pmmshuffle); virtual;
-          procedure a_parammm_ref(list: taasmoutput; size: tcgsize; const ref: treference;const locpara : tparalocation;shuffle : pmmshuffle); virtual;
-          procedure a_parammm_loc(list: taasmoutput; const loc: tlocation; const locpara : tparalocation;shuffle : pmmshuffle); virtual;
+          procedure a_parammm_reg(list: taasmoutput; size: tcgsize; reg: tregister;const paraloc : TCGPara;shuffle : pmmshuffle); virtual;
+          procedure a_parammm_ref(list: taasmoutput; size: tcgsize; const ref: treference;const paraloc : TCGPara;shuffle : pmmshuffle); virtual;
+          procedure a_parammm_loc(list: taasmoutput; const loc: tlocation; const paraloc : TCGPara;shuffle : pmmshuffle); virtual;
           procedure a_opmm_reg_reg(list: taasmoutput; Op: TOpCG; size : tcgsize;src,dst: tregister;shuffle : pmmshuffle); virtual;abstract;
           procedure a_opmm_reg_reg(list: taasmoutput; Op: TOpCG; size : tcgsize;src,dst: tregister;shuffle : pmmshuffle); virtual;abstract;
           procedure a_opmm_ref_reg(list: taasmoutput; Op: TOpCG; size : tcgsize;const ref: treference; reg: tregister;shuffle : pmmshuffle); virtual;
           procedure a_opmm_ref_reg(list: taasmoutput; Op: TOpCG; size : tcgsize;const ref: treference; reg: tregister;shuffle : pmmshuffle); virtual;
           procedure a_opmm_loc_reg(list: taasmoutput; Op: TOpCG; size : tcgsize;const loc: tlocation; reg: tregister;shuffle : pmmshuffle); virtual;
           procedure a_opmm_loc_reg(list: taasmoutput; Op: TOpCG; size : tcgsize;const loc: tlocation; reg: tregister;shuffle : pmmshuffle); virtual;
@@ -344,6 +344,20 @@ unit cgobj;
 
 
           }
           }
           procedure g_concatcopy(list : taasmoutput;const source,dest : treference;len : aint;delsource,loadref : boolean);virtual; abstract;
           procedure g_concatcopy(list : taasmoutput;const source,dest : treference;len : aint;delsource,loadref : boolean);virtual; abstract;
+          {# This should emit the opcode to copy len bytes from the an unaligned source
+             to destination, if loadref is true, it assumes that it first must load
+             the source address from the memory location where
+             source points to.
+
+             It must be overriden for each new target processor.
+
+             @param(source Source reference of copy)
+             @param(dest Destination reference of copy)
+             @param(delsource Indicates if the source reference's resources should be freed)
+             @param(loadref Is the source reference a pointer to the actual source (TRUE), is it the actual source address (FALSE))
+
+          }
+          procedure g_concatcopy_unaligned(list : taasmoutput;const source,dest : treference;len : aint;delsource,loadref : boolean);virtual;
           {# This should emit the opcode to a shortrstring from the source
           {# This should emit the opcode to a shortrstring from the source
              to destination, if loadref is true, it assumes that it first must load
              to destination, if loadref is true, it assumes that it first must load
              the source address from the memory location where
              the source address from the memory location where
@@ -420,7 +434,7 @@ unit cgobj;
           }
           }
           procedure g_restore_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_save_all_registers(list : taasmoutput);virtual;abstract;
-          procedure g_restore_all_registers(list : taasmoutput;const funcretparaloc:tparalocation);virtual;abstract;
+          procedure g_restore_all_registers(list : taasmoutput;const funcretparaloc:TCGPara);virtual;abstract;
        end;
        end;
 
 
 {$ifndef cpu64bit}
 {$ifndef cpu64bit}
@@ -429,10 +443,6 @@ unit cgobj;
        for 64 Bit operations.
        for 64 Bit operations.
     }
     }
     tcg64 = class
     tcg64 = class
-        { Allocates 64 Bit register r by inserting a pai_realloc record }
-        procedure a_reg_alloc(list : taasmoutput;r : tregister64);virtual;abstract;
-        { Deallocates 64 Bit register r by inserting a pa_regdealloc record}
-        procedure a_reg_dealloc(list : taasmoutput;r : tregister64);virtual;abstract;
         procedure a_load64_const_ref(list : taasmoutput;value : int64;const ref : treference);virtual;abstract;
         procedure a_load64_const_ref(list : taasmoutput;value : int64;const ref : treference);virtual;abstract;
         procedure a_load64_reg_ref(list : taasmoutput;reg : tregister64;const ref : treference);virtual;abstract;
         procedure a_load64_reg_ref(list : taasmoutput;reg : tregister64;const ref : treference);virtual;abstract;
         procedure a_load64_ref_reg(list : taasmoutput;const ref : treference;reg : tregister64);virtual;abstract;
         procedure a_load64_ref_reg(list : taasmoutput;const ref : treference;reg : tregister64);virtual;abstract;
@@ -461,10 +471,10 @@ unit cgobj;
         procedure a_op64_const_reg_reg(list: taasmoutput;op:TOpCG;value : int64;regsrc,regdst : tregister64);virtual;
         procedure a_op64_const_reg_reg(list: taasmoutput;op:TOpCG;value : int64;regsrc,regdst : tregister64);virtual;
         procedure a_op64_reg_reg_reg(list: taasmoutput;op:TOpCG;regsrc1,regsrc2,regdst : tregister64);virtual;
         procedure a_op64_reg_reg_reg(list: taasmoutput;op:TOpCG;regsrc1,regsrc2,regdst : tregister64);virtual;
 
 
-        procedure a_param64_reg(list : taasmoutput;reg64 : tregister64;const loc : tparalocation);virtual;abstract;
-        procedure a_param64_const(list : taasmoutput;value : int64;const loc : tparalocation);virtual;abstract;
-        procedure a_param64_ref(list : taasmoutput;const r : treference;const loc : tparalocation);virtual;abstract;
-        procedure a_param64_loc(list : taasmoutput;const l : tlocation;const loc : tparalocation);virtual;abstract;
+        procedure a_param64_reg(list : taasmoutput;reg64 : tregister64;const loc : TCGPara);virtual;abstract;
+        procedure a_param64_const(list : taasmoutput;value : int64;const loc : TCGPara);virtual;abstract;
+        procedure a_param64_ref(list : taasmoutput;const r : treference;const loc : TCGPara);virtual;abstract;
+        procedure a_param64_loc(list : taasmoutput;const l : tlocation;const loc : TCGPara);virtual;abstract;
 
 
         {
         {
              This routine tries to optimize the const_reg opcode, and should be
              This routine tries to optimize the const_reg opcode, and should be
@@ -729,19 +739,18 @@ implementation
           for better code generation these methods should be overridden
           for better code generation these methods should be overridden
 ******************************************************************************}
 ******************************************************************************}
 
 
-    procedure tcg.a_param_reg(list : taasmoutput;size : tcgsize;r : tregister;const locpara : tparalocation);
+    procedure tcg.a_param_reg(list : taasmoutput;size : tcgsize;r : tregister;const paraloc : TCGPara);
       var
       var
          ref : treference;
          ref : treference;
       begin
       begin
-         case locpara.loc of
+         paraloc.check_simple_location;
+         case paraloc.location^.loc of
             LOC_REGISTER,LOC_CREGISTER:
             LOC_REGISTER,LOC_CREGISTER:
-              a_load_reg_reg(list,size,locpara.size,r,locpara.register);
+              a_load_reg_reg(list,size,paraloc.location^.size,r,paraloc.location^.register);
             LOC_REFERENCE,LOC_CREFERENCE:
             LOC_REFERENCE,LOC_CREFERENCE:
               begin
               begin
-                 reference_reset(ref);
-                 ref.base:=locpara.reference.index;
-                 ref.offset:=locpara.reference.offset;
-                 a_load_reg_ref(list,size,locpara.size,r,ref);
+                 reference_reset_base(ref,paraloc.location^.reference.index,paraloc.location^.reference.offset);
+                 a_load_reg_ref(list,size,paraloc.location^.size,r,ref);
               end
               end
             else
             else
               internalerror(2002071004);
               internalerror(2002071004);
@@ -749,19 +758,18 @@ implementation
       end;
       end;
 
 
 
 
-    procedure tcg.a_param_const(list : taasmoutput;size : tcgsize;a : aint;const locpara : tparalocation);
+    procedure tcg.a_param_const(list : taasmoutput;size : tcgsize;a : aint;const paraloc : TCGPara);
       var
       var
          ref : treference;
          ref : treference;
       begin
       begin
-         case locpara.loc of
+         paraloc.check_simple_location;
+         case paraloc.location^.loc of
             LOC_REGISTER,LOC_CREGISTER:
             LOC_REGISTER,LOC_CREGISTER:
-              a_load_const_reg(list,locpara.size,a,locpara.register);
+              a_load_const_reg(list,paraloc.location^.size,a,paraloc.location^.register);
             LOC_REFERENCE,LOC_CREFERENCE:
             LOC_REFERENCE,LOC_CREFERENCE:
               begin
               begin
-                 reference_reset(ref);
-                 ref.base:=locpara.reference.index;
-                 ref.offset:=locpara.reference.offset;
-                 a_load_const_ref(list,locpara.size,a,ref);
+                 reference_reset_base(ref,paraloc.location^.reference.index,paraloc.location^.reference.offset);
+                 a_load_const_ref(list,paraloc.location^.size,a,ref);
               end
               end
             else
             else
               internalerror(2002071004);
               internalerror(2002071004);
@@ -769,18 +777,19 @@ implementation
       end;
       end;
 
 
 
 
-    procedure tcg.a_param_ref(list : taasmoutput;size : tcgsize;const r : treference;const locpara : tparalocation);
+    procedure tcg.a_param_ref(list : taasmoutput;size : tcgsize;const r : treference;const paraloc : TCGPara);
       var
       var
          ref : treference;
          ref : treference;
       begin
       begin
-         case locpara.loc of
+         paraloc.check_simple_location;
+         case paraloc.location^.loc of
             LOC_REGISTER,LOC_CREGISTER:
             LOC_REGISTER,LOC_CREGISTER:
-              a_load_ref_reg(list,size,locpara.size,r,locpara.register);
+              a_load_ref_reg(list,size,paraloc.location^.size,r,paraloc.location^.register);
             LOC_REFERENCE,LOC_CREFERENCE:
             LOC_REFERENCE,LOC_CREFERENCE:
               begin
               begin
                  reference_reset(ref);
                  reference_reset(ref);
-                 ref.base:=locpara.reference.index;
-                 ref.offset:=locpara.reference.offset;
+                 ref.base:=paraloc.location^.reference.index;
+                 ref.offset:=paraloc.location^.reference.offset;
                  { use concatcopy, because it can also be a float which fails when
                  { use concatcopy, because it can also be a float which fails when
                    load_ref_ref is used }
                    load_ref_ref is used }
                  g_concatcopy(list,r,ref,tcgsize2size[size],false,false);
                  g_concatcopy(list,r,ref,tcgsize2size[size],false,false);
@@ -791,162 +800,149 @@ implementation
       end;
       end;
 
 
 
 
-    procedure tcg.a_param_loc(list : taasmoutput;const l:tlocation;const locpara : tparalocation);
+    procedure tcg.a_param_loc(list : taasmoutput;const l:tlocation;const paraloc : TCGPara);
       begin
       begin
         case l.loc of
         case l.loc of
           LOC_REGISTER,
           LOC_REGISTER,
           LOC_CREGISTER :
           LOC_CREGISTER :
-            a_param_reg(list,l.size,l.register,locpara);
+            a_param_reg(list,l.size,l.register,paraloc);
           LOC_CONSTANT :
           LOC_CONSTANT :
-            a_param_const(list,l.size,l.value,locpara);
+            a_param_const(list,l.size,l.value,paraloc);
           LOC_CREFERENCE,
           LOC_CREFERENCE,
           LOC_REFERENCE :
           LOC_REFERENCE :
-            a_param_ref(list,l.size,l.reference,locpara);
-        else
-          internalerror(2002032211);
+            a_param_ref(list,l.size,l.reference,paraloc);
+          else
+            internalerror(2002032211);
         end;
         end;
       end;
       end;
 
 
 
 
-    procedure tcg.a_paramaddr_ref(list : taasmoutput;const r : treference;const locpara : tparalocation);
+    procedure tcg.a_paramaddr_ref(list : taasmoutput;const r : treference;const paraloc : TCGPara);
       var
       var
          hr : tregister;
          hr : tregister;
       begin
       begin
          hr:=getaddressregister(list);
          hr:=getaddressregister(list);
          a_loadaddr_ref_reg(list,r,hr);
          a_loadaddr_ref_reg(list,r,hr);
          ungetregister(list,hr);
          ungetregister(list,hr);
-         a_param_reg(list,OS_ADDR,hr,locpara);
+         a_param_reg(list,OS_ADDR,hr,paraloc);
       end;
       end;
 
 
 
 
-    procedure tcg.a_param_copy_ref(list : taasmoutput;size : aint;const r : treference;const locpara : tparalocation);
+    procedure tcg.a_param_copy_ref(list : taasmoutput;size : aint;const r : treference;const paraloc : TCGPara);
       var
       var
         ref : treference;
         ref : treference;
       begin
       begin
-         if not(locpara.loc in [LOC_REFERENCE,LOC_CREFERENCE]) then
+         paraloc.check_simple_location;
+         if not(paraloc.location^.loc in [LOC_REFERENCE,LOC_CREFERENCE]) then
            internalerror(2003010901);
            internalerror(2003010901);
-         reference_reset_base(ref,locpara.reference.index,locpara.reference.offset);
+         reference_reset_base(ref,paraloc.location^.reference.index,paraloc.location^.reference.offset);
          g_concatcopy(list,r,ref,size,false,false);
          g_concatcopy(list,r,ref,size,false,false);
       end;
       end;
 
 
 
 
-    procedure tcg.a_loadany_param_ref(list : taasmoutput;const locpara : tparalocation;const ref:treference;shuffle : pmmshuffle);
-      begin
-        case locpara.loc of
-          LOC_CREGISTER,
-          LOC_REGISTER:
-            begin
-{$ifndef cpu64bit}
-              if (locpara.size in [OS_S64,OS_64]) then
+    procedure tcg.a_loadany_param_ref(list : taasmoutput;const paraloc : TCGPara;const ref:treference;shuffle : pmmshuffle);
+
+       procedure gen_load(paraloc:TCGParaLocation;const ref:treference);
+         var
+           href : treference;
+         begin
+            case paraloc.loc of
+              LOC_CREGISTER,
+              LOC_REGISTER:
                 begin
                 begin
-                  if getsupreg(locpara.registerlow)<first_int_imreg then
+                  if getsupreg(paraloc.register)<first_int_imreg then
                     begin
                     begin
-                      getexplicitregister(list,locpara.registerlow);
-                      getexplicitregister(list,locpara.registerhigh);
-                      ungetregister(list,locpara.registerlow);
-                      ungetregister(list,locpara.registerhigh);
+                      getexplicitregister(list,paraloc.register);
+                      ungetregister(list,paraloc.register);
                     end;
                     end;
-                  cg64.a_load64_reg_ref(list,locpara.register64,ref)
-                end
-              else
-{$endif cpu64bit}
+                  a_load_reg_ref(list,paraloc.size,paraloc.size,paraloc.register,ref);
+                end;
+              LOC_MMREGISTER,
+              LOC_CMMREGISTER:
                 begin
                 begin
-                  if getsupreg(locpara.register)<first_int_imreg then
+                  if getsupreg(paraloc.register)<first_mm_imreg then
                     begin
                     begin
-                      getexplicitregister(list,locpara.register);
-                      ungetregister(list,locpara.register);
+                      getexplicitregister(list,paraloc.register);
+                      ungetregister(list,paraloc.register);
                     end;
                     end;
-                  a_load_reg_ref(list,locpara.size,locpara.size,locpara.register,ref);
+                  a_loadmm_reg_ref(list,paraloc.size,paraloc.size,paraloc.register,ref,shuffle);
                 end;
                 end;
-            end;
-          LOC_MMREGISTER,
-          LOC_CMMREGISTER:
-            begin
-              if getsupreg(locpara.register)<first_mm_imreg then
+              LOC_FPUREGISTER,
+              LOC_CFPUREGISTER:
                 begin
                 begin
-                  getexplicitregister(list,locpara.register);
-                  ungetregister(list,locpara.register);
+                  if getsupreg(paraloc.register)<first_fpu_imreg then
+                    begin
+                      getexplicitregister(list,paraloc.register);
+                      ungetregister(list,paraloc.register);
+                    end;
+                  a_loadfpu_reg_ref(list,paraloc.size,paraloc.register,ref);
                 end;
                 end;
-              a_loadmm_reg_ref(list,locpara.size,locpara.size,locpara.register,ref,shuffle);
-            end;
-          LOC_FPUREGISTER,
-          LOC_CFPUREGISTER:
-            begin
-              if getsupreg(locpara.register)<first_fpu_imreg then
+              LOC_REFERENCE:
                 begin
                 begin
-                  getexplicitregister(list,locpara.register);
-                  ungetregister(list,locpara.register);
+                  reference_reset_base(href,paraloc.reference.index,paraloc.reference.offset);
+                  { use concatcopy, because it can also be a float which fails when
+                    load_ref_ref is used }
+                  g_concatcopy(list,href,ref,tcgsize2size[paraloc.size],false,false);
                 end;
                 end;
-              a_loadfpu_reg_ref(list,locpara.size,locpara.register,ref);
+              else
+                internalerror(2002081302);
             end;
             end;
-          else
-            internalerror(2002081302);
         end;
         end;
+
+      var
+        href : treference;
+      begin
+        href:=ref;
+        gen_load(paraloc.location^,href);
+        if assigned(paraloc.location^.next) then
+          begin
+            inc(href.offset,TCGSize2Size[paraloc.location^.size]);
+            gen_load(paraloc.location^.next^,href);
+          end;
       end;
       end;
 
 
 
 
-    procedure tcg.a_loadany_param_reg(list : taasmoutput;const locpara : tparalocation;const reg:tregister;shuffle : pmmshuffle);
+    procedure tcg.a_loadany_param_reg(list : taasmoutput;const paraloc : TCGPara;const reg:tregister;shuffle : pmmshuffle);
       var
       var
         href : treference;
         href : treference;
       begin
       begin
-        case locpara.loc of
+        paraloc.check_simple_location;
+        case paraloc.location^.loc of
           LOC_CREGISTER,
           LOC_CREGISTER,
           LOC_REGISTER:
           LOC_REGISTER:
             begin
             begin
-              if not(locpara.size in [OS_S64,OS_64]) then
+              if getsupreg(paraloc.location^.register)<first_int_imreg then
                 begin
                 begin
-                  if getsupreg(locpara.register)<first_int_imreg then
-                    begin
-                      getexplicitregister(list,locpara.register);
-                      ungetregister(list,locpara.register);
-                    end;
-{
-                  This is now a normal imaginary register, allocated the usual way (JM)
-                  getexplicitregister(list,reg);
-}
-                  a_load_reg_reg(list,locpara.size,locpara.size,locpara.register,reg)
-                end
-              else
-                internalerror(2003053011);
+                  getexplicitregister(list,paraloc.location^.register);
+                  ungetregister(list,paraloc.location^.register);
+                end;
+              a_load_reg_reg(list,paraloc.location^.size,paraloc.location^.size,paraloc.location^.register,reg)
             end;
             end;
           LOC_CFPUREGISTER,
           LOC_CFPUREGISTER,
           LOC_FPUREGISTER:
           LOC_FPUREGISTER:
             begin
             begin
-
-              if getsupreg(locpara.register)<first_fpu_imreg then
+              if getsupreg(paraloc.location^.register)<first_fpu_imreg then
                 begin
                 begin
-                  getexplicitregister(list,locpara.register);
-                  ungetregister(list,locpara.register);
+                  getexplicitregister(list,paraloc.location^.register);
+                  ungetregister(list,paraloc.location^.register);
                 end;
                 end;
-{
-              This is now a normal imaginary register, allocated the usual way (JM)
-              getexplicitregister(list,reg);
-}
-              a_loadfpu_reg_reg(list,locpara.size,locpara.register,reg);
+              a_loadfpu_reg_reg(list,paraloc.location^.size,paraloc.location^.register,reg);
             end;
             end;
           LOC_MMREGISTER,
           LOC_MMREGISTER,
           LOC_CMMREGISTER:
           LOC_CMMREGISTER:
             begin
             begin
-              if getsupreg(locpara.register)<first_mm_imreg then
+              if getsupreg(paraloc.location^.register)<first_mm_imreg then
                 begin
                 begin
-                  getexplicitregister(list,locpara.register);
-                  ungetregister(list,locpara.register);
+                  getexplicitregister(list,paraloc.location^.register);
+                  ungetregister(list,paraloc.location^.register);
                 end;
                 end;
-{
-              This is now a normal imaginary register, allocated the usual way (JM)
-              getexplicitregister(list,reg);
-}
-              a_loadmm_reg_reg(list,locpara.size,locpara.size,locpara.register,reg,shuffle);
+              a_loadmm_reg_reg(list,paraloc.location^.size,paraloc.location^.size,paraloc.location^.register,reg,shuffle);
             end;
             end;
           LOC_REFERENCE,
           LOC_REFERENCE,
           LOC_CREFERENCE:
           LOC_CREFERENCE:
             begin
             begin
-              reference_reset_base(href,locpara.reference.index,locpara.reference.offset);
-{
-              This is now a normal imaginary register, allocated the usual way (JM)
-              getexplicitregister(list,reg);
-}
-              a_load_ref_reg(list,locpara.size,locpara.size,href,reg);
+              reference_reset_base(href,paraloc.location^.reference.index,paraloc.location^.reference.offset);
+              a_load_ref_reg(list,paraloc.location^.size,paraloc.location^.size,href,reg);
             end;
             end;
           else
           else
             internalerror(2003053010);
             internalerror(2003053010);
@@ -1119,18 +1115,17 @@ implementation
       end;
       end;
 
 
 
 
-    procedure tcg.a_paramfpu_reg(list : taasmoutput;size : tcgsize;const r : tregister;const locpara : tparalocation);
+    procedure tcg.a_paramfpu_reg(list : taasmoutput;size : tcgsize;const r : tregister;const paraloc : TCGPara);
       var
       var
          ref : treference;
          ref : treference;
       begin
       begin
-         case locpara.loc of
+         paraloc.check_simple_location;
+         case paraloc.location^.loc of
             LOC_FPUREGISTER,LOC_CFPUREGISTER:
             LOC_FPUREGISTER,LOC_CFPUREGISTER:
-              a_loadfpu_reg_reg(list,size,r,locpara.register);
+              a_loadfpu_reg_reg(list,size,r,paraloc.location^.register);
             LOC_REFERENCE,LOC_CREFERENCE:
             LOC_REFERENCE,LOC_CREFERENCE:
               begin
               begin
-                 reference_reset(ref);
-                 ref.base:=locpara.reference.index;
-                 ref.offset:=locpara.reference.offset;
+                 reference_reset_base(ref,paraloc.location^.reference.index,paraloc.location^.reference.offset);
                  a_loadfpu_reg_ref(list,size,r,ref);
                  a_loadfpu_reg_ref(list,size,r,ref);
               end
               end
             else
             else
@@ -1139,18 +1134,17 @@ implementation
       end;
       end;
 
 
 
 
-    procedure tcg.a_paramfpu_ref(list : taasmoutput;size : tcgsize;const ref : treference;const locpara : tparalocation);
+    procedure tcg.a_paramfpu_ref(list : taasmoutput;size : tcgsize;const ref : treference;const paraloc : TCGPara);
       var
       var
          href : treference;
          href : treference;
       begin
       begin
-        case locpara.loc of
+         paraloc.check_simple_location;
+         case paraloc.location^.loc of
           LOC_FPUREGISTER,LOC_CFPUREGISTER:
           LOC_FPUREGISTER,LOC_CFPUREGISTER:
-            a_loadfpu_ref_reg(list,size,ref,locpara.register);
+            a_loadfpu_ref_reg(list,size,ref,paraloc.location^.register);
           LOC_REFERENCE,LOC_CREFERENCE:
           LOC_REFERENCE,LOC_CREFERENCE:
             begin
             begin
-              reference_reset(href);
-              href.base:=locpara.reference.index;
-              href.offset:=locpara.reference.offset;
+              reference_reset_base(href,paraloc.location^.reference.index,paraloc.location^.reference.offset);
               { concatcopy should choose the best way to copy the data }
               { concatcopy should choose the best way to copy the data }
               g_concatcopy(list,ref,href,tcgsize2size[size],false,false);
               g_concatcopy(list,ref,href,tcgsize2size[size],false,false);
             end
             end
@@ -1161,10 +1155,8 @@ implementation
 
 
 
 
     procedure tcg.a_op_const_ref(list : taasmoutput; Op: TOpCG; size: TCGSize; a: aint; const ref: TReference);
     procedure tcg.a_op_const_ref(list : taasmoutput; Op: TOpCG; size: TCGSize; a: aint; const ref: TReference);
-
       var
       var
-        tmpreg: tregister;
-
+        tmpreg : tregister;
       begin
       begin
         tmpreg:=getintregister(list,size);
         tmpreg:=getintregister(list,size);
         a_load_ref_reg(list,size,size,ref,tmpreg);
         a_load_ref_reg(list,size,size,ref,tmpreg);
@@ -1175,7 +1167,6 @@ implementation
 
 
 
 
     procedure tcg.a_op_const_loc(list : taasmoutput; Op: TOpCG; a: aint; const loc: tlocation);
     procedure tcg.a_op_const_loc(list : taasmoutput; Op: TOpCG; a: aint; const loc: tlocation);
-
       begin
       begin
         case loc.loc of
         case loc.loc of
           LOC_REGISTER, LOC_CREGISTER:
           LOC_REGISTER, LOC_CREGISTER:
@@ -1189,10 +1180,8 @@ implementation
 
 
 
 
     procedure tcg.a_op_reg_ref(list : taasmoutput; Op: TOpCG; size: TCGSize;reg: TRegister;  const ref: TReference);
     procedure tcg.a_op_reg_ref(list : taasmoutput; Op: TOpCG; size: TCGSize;reg: TRegister;  const ref: TReference);
-
       var
       var
-        tmpreg: tregister;
-
+        tmpreg : tregister;
       begin
       begin
         tmpreg:=getintregister(list,size);
         tmpreg:=getintregister(list,size);
         a_load_ref_reg(list,size,size,ref,tmpreg);
         a_load_ref_reg(list,size,size,ref,tmpreg);
@@ -1405,19 +1394,18 @@ implementation
       end;
       end;
 
 
 
 
-    procedure tcg.a_parammm_reg(list: taasmoutput; size: tcgsize; reg: tregister;const locpara : tparalocation;shuffle : pmmshuffle);
+    procedure tcg.a_parammm_reg(list: taasmoutput; size: tcgsize; reg: tregister;const paraloc : TCGPara;shuffle : pmmshuffle);
       var
       var
-        ref : treference;
+        href : treference;
       begin
       begin
-        case locpara.loc of
+         paraloc.check_simple_location;
+         case paraloc.location^.loc of
           LOC_MMREGISTER,LOC_CMMREGISTER:
           LOC_MMREGISTER,LOC_CMMREGISTER:
-            a_loadmm_reg_reg(list,size,locpara.size,reg,locpara.register,shuffle);
+            a_loadmm_reg_reg(list,size,paraloc.location^.size,reg,paraloc.location^.register,shuffle);
           LOC_REFERENCE,LOC_CREFERENCE:
           LOC_REFERENCE,LOC_CREFERENCE:
             begin
             begin
-              reference_reset(ref);
-              ref.base:=locpara.reference.index;
-              ref.offset:=locpara.reference.offset;
-              a_loadmm_reg_ref(list,size,locpara.size,reg,ref,shuffle);
+              reference_reset_base(href,paraloc.location^.reference.index,paraloc.location^.reference.offset);
+              a_loadmm_reg_ref(list,size,paraloc.location^.size,reg,href,shuffle);
             end
             end
           else
           else
             internalerror(200310123);
             internalerror(200310123);
@@ -1425,32 +1413,33 @@ implementation
       end;
       end;
 
 
 
 
-    procedure tcg.a_parammm_ref(list: taasmoutput; size: tcgsize;const ref: treference;const locpara : tparalocation;shuffle : pmmshuffle);
+    procedure tcg.a_parammm_ref(list: taasmoutput; size: tcgsize;const ref: treference;const paraloc : TCGPara;shuffle : pmmshuffle);
       var
       var
          hr : tregister;
          hr : tregister;
          hs : tmmshuffle;
          hs : tmmshuffle;
       begin
       begin
-         hr:=getmmregister(list,locpara.size);
-         a_loadmm_ref_reg(list,size,locpara.size,ref,hr,shuffle);
+         paraloc.check_simple_location;
+         hr:=getmmregister(list,paraloc.location^.size);
+         a_loadmm_ref_reg(list,size,paraloc.location^.size,ref,hr,shuffle);
          if realshuffle(shuffle) then
          if realshuffle(shuffle) then
            begin
            begin
              hs:=shuffle^;
              hs:=shuffle^;
              removeshuffles(hs);
              removeshuffles(hs);
-             a_parammm_reg(list,locpara.size,hr,locpara,@hs);
+             a_parammm_reg(list,paraloc.location^.size,hr,paraloc,@hs);
            end
            end
          else
          else
-           a_parammm_reg(list,locpara.size,hr,locpara,shuffle);
+           a_parammm_reg(list,paraloc.location^.size,hr,paraloc,shuffle);
          ungetregister(list,hr);
          ungetregister(list,hr);
       end;
       end;
 
 
 
 
-    procedure tcg.a_parammm_loc(list: taasmoutput;const loc: tlocation; const locpara : tparalocation;shuffle : pmmshuffle);
+    procedure tcg.a_parammm_loc(list: taasmoutput;const loc: tlocation; const paraloc : TCGPara;shuffle : pmmshuffle);
       begin
       begin
         case loc.loc of
         case loc.loc of
           LOC_MMREGISTER,LOC_CMMREGISTER:
           LOC_MMREGISTER,LOC_CMMREGISTER:
-            a_parammm_reg(list,loc.size,loc.register,locpara,shuffle);
+            a_parammm_reg(list,loc.size,loc.register,paraloc,shuffle);
           LOC_REFERENCE,LOC_CREFERENCE:
           LOC_REFERENCE,LOC_CREFERENCE:
-            a_parammm_ref(list,loc.size,loc.reference,locpara,shuffle);
+            a_parammm_ref(list,loc.size,loc.reference,paraloc,shuffle);
           else
           else
             internalerror(200310123);
             internalerror(200310123);
         end;
         end;
@@ -1512,16 +1501,51 @@ implementation
       end;
       end;
 
 
 
 
+    procedure tcg.g_concatcopy_unaligned(list : taasmoutput;const source,dest : treference;len : aint;delsource,loadref : boolean);
+      var
+        paraloc1,paraloc2,paraloc3 : TCGPara;
+      begin
+        paraloc1.init;
+        paraloc2.init;
+        paraloc3.init;
+        paramanager.getintparaloc(pocall_default,1,paraloc1);
+        paramanager.getintparaloc(pocall_default,2,paraloc2);
+        paramanager.getintparaloc(pocall_default,3,paraloc3);
+        paramanager.allocparaloc(list,paraloc3);
+        a_param_const(list,OS_INT,len,paraloc3);
+        paramanager.allocparaloc(list,paraloc2);
+        a_paramaddr_ref(list,dest,paraloc2);
+        paramanager.allocparaloc(list,paraloc2);
+        if loadref then
+          a_param_ref(list,OS_ADDR,source,paraloc1)
+        else
+          a_paramaddr_ref(list,source,paraloc1);
+        if delsource then
+         reference_release(list,source);
+        paramanager.freeparaloc(list,paraloc3);
+        paramanager.freeparaloc(list,paraloc2);
+        paramanager.freeparaloc(list,paraloc1);
+        allocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
+        allocexplicitregisters(list,R_FPUREGISTER,paramanager.get_volatile_registers_fpu(pocall_default));
+        a_call_name(list,'FPC_MOVE');
+        deallocexplicitregisters(list,R_FPUREGISTER,paramanager.get_volatile_registers_fpu(pocall_default));
+        deallocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
+        paraloc3.done;
+        paraloc2.done;
+        paraloc1.done;
+      end;
+
+
     procedure tcg.g_copyshortstring(list : taasmoutput;const source,dest : treference;len:byte;delsource,loadref : boolean);
     procedure tcg.g_copyshortstring(list : taasmoutput;const source,dest : treference;len:byte;delsource,loadref : boolean);
       var
       var
-        paraloc1,paraloc2,paraloc3 : tparalocation;
-      begin
-{$ifdef FPC}
-        {$warning FIX ME!}
-{$endif}
-        paraloc1:=paramanager.getintparaloc(pocall_default,1);
-        paraloc2:=paramanager.getintparaloc(pocall_default,2);
-        paraloc3:=paramanager.getintparaloc(pocall_default,3);
+        paraloc1,paraloc2,paraloc3 : TCGPara;
+      begin
+        paraloc1.init;
+        paraloc2.init;
+        paraloc3.init;
+        paramanager.getintparaloc(pocall_default,1,paraloc1);
+        paramanager.getintparaloc(pocall_default,2,paraloc2);
+        paramanager.getintparaloc(pocall_default,3,paraloc3);
         paramanager.allocparaloc(list,paraloc3);
         paramanager.allocparaloc(list,paraloc3);
         a_paramaddr_ref(list,dest,paraloc3);
         a_paramaddr_ref(list,dest,paraloc3);
         paramanager.allocparaloc(list,paraloc2);
         paramanager.allocparaloc(list,paraloc2);
@@ -1537,8 +1561,13 @@ implementation
         paramanager.freeparaloc(list,paraloc2);
         paramanager.freeparaloc(list,paraloc2);
         paramanager.freeparaloc(list,paraloc1);
         paramanager.freeparaloc(list,paraloc1);
         allocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
         allocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
+        allocexplicitregisters(list,R_FPUREGISTER,paramanager.get_volatile_registers_fpu(pocall_default));
         a_call_name(list,'FPC_SHORTSTR_ASSIGN');
         a_call_name(list,'FPC_SHORTSTR_ASSIGN');
+        deallocexplicitregisters(list,R_FPUREGISTER,paramanager.get_volatile_registers_fpu(pocall_default));
         deallocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
         deallocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
+        paraloc3.done;
+        paraloc2.done;
+        paraloc1.done;
       end;
       end;
 
 
 
 
@@ -1546,10 +1575,12 @@ implementation
       var
       var
         href : treference;
         href : treference;
         incrfunc : string;
         incrfunc : string;
-        paraloc1,paraloc2 : tparalocation;
+        paraloc1,paraloc2 : TCGPara;
       begin
       begin
-         paraloc1:=paramanager.getintparaloc(pocall_default,1);
-         paraloc2:=paramanager.getintparaloc(pocall_default,2);
+         paraloc1.init;
+         paraloc2.init;
+         paramanager.getintparaloc(pocall_default,1,paraloc1);
+         paramanager.getintparaloc(pocall_default,2,paraloc2);
          { These functions should not change the registers (they use
          { These functions should not change the registers (they use
            the saveregister proc directive }
            the saveregister proc directive }
          if is_interfacecom(t) then
          if is_interfacecom(t) then
@@ -1601,7 +1632,9 @@ implementation
             allocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
             allocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
             a_call_name(list,'FPC_ADDREF');
             a_call_name(list,'FPC_ADDREF');
             deallocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
             deallocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
-         end;
+          end;
+         paraloc2.done;
+         paraloc1.done;
       end;
       end;
 
 
 
 
@@ -1611,14 +1644,16 @@ implementation
         href : treference;
         href : treference;
         decrfunc : string;
         decrfunc : string;
         needrtti : boolean;
         needrtti : boolean;
-        paraloc1,paraloc2 : tparalocation;
-      begin
-         paraloc1:=paramanager.getintparaloc(pocall_default,1);
-         paraloc2:=paramanager.getintparaloc(pocall_default,2);
-         needrtti:=false;
-         if is_interfacecom(t) then
+        paraloc1,paraloc2 : TCGPara;
+      begin
+        paraloc1.init;
+        paraloc2.init;
+        paramanager.getintparaloc(pocall_default,1,paraloc1);
+        paramanager.getintparaloc(pocall_default,2,paraloc2);
+        needrtti:=false;
+        if is_interfacecom(t) then
           decrfunc:='FPC_INTF_DECR_REF'
           decrfunc:='FPC_INTF_DECR_REF'
-         else if is_ansistring(t) then
+        else if is_ansistring(t) then
        {$ifdef ansistring_bits}
        {$ifdef ansistring_bits}
            begin
            begin
              case Tstringdef(t).string_typ of
              case Tstringdef(t).string_typ of
@@ -1693,16 +1728,20 @@ implementation
             else
             else
               a_load_const_ref(list,OS_ADDR,0,ref);
               a_load_const_ref(list,OS_ADDR,0,ref);
           end;
           end;
+        paraloc2.done;
+        paraloc1.done;
       end;
       end;
 
 
 
 
     procedure tcg.g_initialize(list : taasmoutput;t : tdef;const ref : treference;loadref : boolean);
     procedure tcg.g_initialize(list : taasmoutput;t : tdef;const ref : treference;loadref : boolean);
       var
       var
          href : treference;
          href : treference;
-         paraloc1,paraloc2 : tparalocation;
+         paraloc1,paraloc2 : TCGPara;
       begin
       begin
-         paraloc1:=paramanager.getintparaloc(pocall_default,1);
-         paraloc2:=paramanager.getintparaloc(pocall_default,2);
+        paraloc1.init;
+        paraloc2.init;
+        paramanager.getintparaloc(pocall_default,1,paraloc1);
+        paramanager.getintparaloc(pocall_default,2,paraloc2);
          if is_ansistring(t) or
          if is_ansistring(t) or
             is_widestring(t) or
             is_widestring(t) or
             is_interfacecom(t) or
             is_interfacecom(t) or
@@ -1721,9 +1760,13 @@ implementation
               paramanager.freeparaloc(list,paraloc1);
               paramanager.freeparaloc(list,paraloc1);
               paramanager.freeparaloc(list,paraloc2);
               paramanager.freeparaloc(list,paraloc2);
               allocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
               allocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
+              allocexplicitregisters(list,R_FPUREGISTER,paramanager.get_volatile_registers_fpu(pocall_default));
               a_call_name(list,'FPC_INITIALIZE');
               a_call_name(list,'FPC_INITIALIZE');
+              deallocexplicitregisters(list,R_FPUREGISTER,paramanager.get_volatile_registers_fpu(pocall_default));
               deallocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
               deallocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
            end;
            end;
+        paraloc1.done;
+        paraloc2.done;
       end;
       end;
 
 
 
 
@@ -1731,10 +1774,12 @@ implementation
       var
       var
          hreg : tregister;
          hreg : tregister;
          href : treference;
          href : treference;
-         paraloc1,paraloc2 : tparalocation;
+         paraloc1,paraloc2 : TCGPara;
       begin
       begin
-         paraloc1:=paramanager.getintparaloc(pocall_default,1);
-         paraloc2:=paramanager.getintparaloc(pocall_default,2);
+        paraloc1.init;
+        paraloc2.init;
+        paramanager.getintparaloc(pocall_default,1,paraloc1);
+        paramanager.getintparaloc(pocall_default,2,paraloc2);
          if is_ansistring(t) or
          if is_ansistring(t) or
             is_widestring(t) or
             is_widestring(t) or
             is_interfacecom(t) then
             is_interfacecom(t) then
@@ -1768,9 +1813,13 @@ implementation
               paramanager.freeparaloc(list,paraloc1);
               paramanager.freeparaloc(list,paraloc1);
               paramanager.freeparaloc(list,paraloc2);
               paramanager.freeparaloc(list,paraloc2);
               allocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
               allocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
+              allocexplicitregisters(list,R_FPUREGISTER,paramanager.get_volatile_registers_fpu(pocall_default));
               a_call_name(list,'FPC_FINALIZE');
               a_call_name(list,'FPC_FINALIZE');
+              deallocexplicitregisters(list,R_FPUREGISTER,paramanager.get_volatile_registers_fpu(pocall_default));
               deallocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
               deallocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
            end;
            end;
+        paraloc1.done;
+        paraloc2.done;
       end;
       end;
 
 
 
 
@@ -1927,19 +1976,21 @@ implementation
     procedure tcg.g_maybe_testself(list : taasmoutput;reg:tregister);
     procedure tcg.g_maybe_testself(list : taasmoutput;reg:tregister);
       var
       var
         OKLabel : tasmlabel;
         OKLabel : tasmlabel;
-        paraloc1 : tparalocation;
+        paraloc1 : TCGPara;
       begin
       begin
         if (cs_check_object in aktlocalswitches) or
         if (cs_check_object in aktlocalswitches) or
            (cs_check_range in aktlocalswitches) then
            (cs_check_range in aktlocalswitches) then
          begin
          begin
            objectlibrary.getlabel(oklabel);
            objectlibrary.getlabel(oklabel);
            a_cmp_const_reg_label(list,OS_ADDR,OC_NE,0,reg,oklabel);
            a_cmp_const_reg_label(list,OS_ADDR,OC_NE,0,reg,oklabel);
-           paraloc1:=paramanager.getintparaloc(pocall_default,1);
+           paraloc1.init;
+           paramanager.getintparaloc(pocall_default,1,paraloc1);
            paramanager.allocparaloc(list,paraloc1);
            paramanager.allocparaloc(list,paraloc1);
            a_param_const(list,OS_INT,210,paraloc1);
            a_param_const(list,OS_INT,210,paraloc1);
            paramanager.freeparaloc(list,paraloc1);
            paramanager.freeparaloc(list,paraloc1);
            a_call_name(list,'FPC_HANDLEERROR');
            a_call_name(list,'FPC_HANDLEERROR');
            a_label(list,oklabel);
            a_label(list,oklabel);
+           paraloc1.done;
          end;
          end;
       end;
       end;
 
 
@@ -1947,10 +1998,12 @@ implementation
     procedure tcg.g_maybe_testvmt(list : taasmoutput;reg:tregister;objdef:tobjectdef);
     procedure tcg.g_maybe_testvmt(list : taasmoutput;reg:tregister;objdef:tobjectdef);
       var
       var
         hrefvmt : treference;
         hrefvmt : treference;
-        paraloc1,paraloc2 : tparalocation;
+        paraloc1,paraloc2 : TCGPara;
       begin
       begin
-        paraloc1:=paramanager.getintparaloc(pocall_default,1);
-        paraloc2:=paramanager.getintparaloc(pocall_default,2);
+        paraloc1.init;
+        paraloc2.init;
+        paramanager.getintparaloc(pocall_default,1,paraloc1);
+        paramanager.getintparaloc(pocall_default,2,paraloc2);
         if (cs_check_object in aktlocalswitches) then
         if (cs_check_object in aktlocalswitches) then
          begin
          begin
            reference_reset_symbol(hrefvmt,objectlibrary.newasmsymbol(objdef.vmt_mangledname,AB_EXTERNAL,AT_DATA),0);
            reference_reset_symbol(hrefvmt,objectlibrary.newasmsymbol(objdef.vmt_mangledname,AB_EXTERNAL,AT_DATA),0);
@@ -1974,6 +2027,8 @@ implementation
             a_call_name(list,'FPC_CHECK_OBJECT');
             a_call_name(list,'FPC_CHECK_OBJECT');
             deallocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
             deallocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
           end;
           end;
+        paraloc1.done;
+        paraloc2.done;
       end;
       end;
 
 
 
 
@@ -1984,7 +2039,7 @@ implementation
     procedure tcg.g_copyvaluepara_openarray(list : taasmoutput;const ref, lenref:treference;elesize:aint);
     procedure tcg.g_copyvaluepara_openarray(list : taasmoutput;const ref, lenref:treference;elesize:aint);
       var
       var
         sizereg,sourcereg,destreg : tregister;
         sizereg,sourcereg,destreg : tregister;
-        paraloc1,paraloc2,paraloc3 : tparalocation;
+        paraloc1,paraloc2,paraloc3 : TCGPara;
       begin
       begin
         { because ppc abi doesn't support dynamic stack allocation properly
         { because ppc abi doesn't support dynamic stack allocation properly
           open array value parameters are copied onto the heap
           open array value parameters are copied onto the heap
@@ -2002,20 +2057,27 @@ implementation
         a_load_ref_reg(list,OS_ADDR,OS_ADDR,ref,sourcereg);
         a_load_ref_reg(list,OS_ADDR,OS_ADDR,ref,sourcereg);
 
 
         { do getmem call }
         { do getmem call }
-        paraloc1:=paramanager.getintparaloc(pocall_default,1);
+        paraloc1.init;
+        paramanager.getintparaloc(pocall_default,1,paraloc1);
         paramanager.allocparaloc(list,paraloc1);
         paramanager.allocparaloc(list,paraloc1);
         a_param_reg(list,OS_INT,sizereg,paraloc1);
         a_param_reg(list,OS_INT,sizereg,paraloc1);
         paramanager.freeparaloc(list,paraloc1);
         paramanager.freeparaloc(list,paraloc1);
         allocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
         allocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
+        allocexplicitregisters(list,R_FPUREGISTER,paramanager.get_volatile_registers_fpu(pocall_default));
         a_call_name(list,'FPC_GETMEM');
         a_call_name(list,'FPC_GETMEM');
+        deallocexplicitregisters(list,R_FPUREGISTER,paramanager.get_volatile_registers_fpu(pocall_default));
         deallocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
         deallocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
-	a_load_reg_reg(list,OS_ADDR,OS_ADDR,NR_FUNCTION_RESULT_REG,destreg);
-	a_load_reg_ref(list,OS_ADDR,OS_ADDR,NR_FUNCTION_RESULT_REG,ref);
+        a_load_reg_reg(list,OS_ADDR,OS_ADDR,NR_FUNCTION_RESULT_REG,destreg);
+        a_load_reg_ref(list,OS_ADDR,OS_ADDR,NR_FUNCTION_RESULT_REG,ref);
+        paraloc1.done;
 
 
         { do move call }
         { do move call }
-        paraloc1:=paramanager.getintparaloc(pocall_default,1);
-        paraloc2:=paramanager.getintparaloc(pocall_default,2);
-        paraloc3:=paramanager.getintparaloc(pocall_default,3);
+        paraloc1.init;
+        paraloc2.init;
+        paraloc3.init;
+        paramanager.getintparaloc(pocall_default,1,paraloc1);
+        paramanager.getintparaloc(pocall_default,2,paraloc2);
+        paramanager.getintparaloc(pocall_default,3,paraloc3);
         { load size }
         { load size }
         paramanager.allocparaloc(list,paraloc3);
         paramanager.allocparaloc(list,paraloc3);
         a_param_reg(list,OS_INT,sizereg,paraloc3);
         a_param_reg(list,OS_INT,sizereg,paraloc3);
@@ -2029,8 +2091,13 @@ implementation
         paramanager.freeparaloc(list,paraloc2);
         paramanager.freeparaloc(list,paraloc2);
         paramanager.freeparaloc(list,paraloc1);
         paramanager.freeparaloc(list,paraloc1);
         allocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
         allocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
+        allocexplicitregisters(list,R_FPUREGISTER,paramanager.get_volatile_registers_fpu(pocall_default));
         a_call_name(list,'FPC_MOVE');
         a_call_name(list,'FPC_MOVE');
+        deallocexplicitregisters(list,R_FPUREGISTER,paramanager.get_volatile_registers_fpu(pocall_default));
         deallocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
         deallocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
+        paraloc3.done;
+        paraloc2.done;
+        paraloc1.done;
 
 
         { release used registers }
         { release used registers }
         ungetregister(list,sizereg);
         ungetregister(list,sizereg);
@@ -2041,17 +2108,21 @@ implementation
 
 
     procedure tcg.g_releasevaluepara_openarray(list : taasmoutput;const ref:treference);
     procedure tcg.g_releasevaluepara_openarray(list : taasmoutput;const ref:treference);
       var
       var
-        paraloc : tparalocation;
+        paraloc1 : TCGPara;
       begin
       begin
         { do move call }
         { do move call }
-        paraloc:=paramanager.getintparaloc(pocall_default,1);
+        paraloc1.init;
+        paramanager.getintparaloc(pocall_default,1,paraloc1);
         { load source }
         { load source }
-        paramanager.allocparaloc(list,paraloc);
-        a_param_ref(list,OS_ADDR,ref,paraloc);
-        paramanager.freeparaloc(list,paraloc);
+        paramanager.allocparaloc(list,paraloc1);
+        a_param_ref(list,OS_ADDR,ref,paraloc1);
+        paramanager.freeparaloc(list,paraloc1);
         allocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
         allocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
+        allocexplicitregisters(list,R_FPUREGISTER,paramanager.get_volatile_registers_fpu(pocall_default));
         a_call_name(list,'FPC_FREEMEM');
         a_call_name(list,'FPC_FREEMEM');
+        deallocexplicitregisters(list,R_FPUREGISTER,paramanager.get_volatile_registers_fpu(pocall_default));
         deallocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
         deallocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
+        paraloc1.done;
       end;
       end;
 
 
 
 
@@ -2195,7 +2266,24 @@ finalization
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.168  2004-07-09 23:41:04  jonas
+  Revision 1.169  2004-09-21 17:25:12  peter
+    * paraloc branch merged
+
+  Revision 1.168.4.4  2004/09/20 20:45:57  peter
+    * remove cg64.a_reg_alloc, it should not be used since it
+      create more register conflicts
+
+  Revision 1.168.4.3  2004/09/18 20:22:40  jonas
+    * allocate the volatile fpu registers around procedures that might use
+      them (e.g. FPCMOVE may use them)
+
+  Revision 1.168.4.2  2004/09/12 13:36:40  peter
+    * fixed alignment issues
+
+  Revision 1.168.4.1  2004/08/31 20:43:06  peter
+    * paraloc patch
+
+  Revision 1.168  2004/07/09 23:41:04  jonas
     * support register parameters for inlined procedures + some inline
     * support register parameters for inlined procedures + some inline
       cleanups
       cleanups
 
 

+ 8 - 1
compiler/fpcdefs.inc

@@ -79,6 +79,7 @@
 {$ifdef sparc}
 {$ifdef sparc}
   {$define noopt}
   {$define noopt}
   {$define oldset}
   {$define oldset}
+  {$define cputargethasfixedstack}
 {$endif sparc}
 {$endif sparc}
 
 
 {$ifdef cpusparc}
 {$ifdef cpusparc}
@@ -106,7 +107,13 @@
 
 
 {
 {
   $Log$
   $Log$
-  Revision 1.39  2004-08-15 13:30:18  florian
+  Revision 1.40  2004-09-21 17:25:12  peter
+    * paraloc branch merged
+
+  Revision 1.39.4.1  2004/08/31 20:43:06  peter
+    * paraloc patch
+
+  Revision 1.39  2004/08/15 13:30:18  florian
     * fixed alignment of variant records
     * fixed alignment of variant records
     * more alignment problems fixed
     * more alignment problems fixed
 
 

+ 76 - 14
compiler/globals.pas

@@ -310,7 +310,7 @@ interface
     function  GetEnvPChar(const envname:string):pchar;
     function  GetEnvPChar(const envname:string):pchar;
     procedure FreeEnvPChar(p:pchar);
     procedure FreeEnvPChar(p:pchar);
 
 
-    function SetFPUExceptionMask(const Mask : TFPUExceptionMask) : TFPUExceptionMask;
+    procedure SetFPUExceptionMask(const Mask: TFPUExceptionMask);
     function is_number_float(d : double) : boolean;
     function is_number_float(d : double) : boolean;
 
 
     Function SetCompileMode(const s:string; changeInit: boolean):boolean;
     Function SetCompileMode(const s:string; changeInit: boolean):boolean;
@@ -461,12 +461,16 @@ implementation
                                File Handling
                                File Handling
 ****************************************************************************}
 ****************************************************************************}
 
 
-   function GetCurrentDir:string;
      var
      var
-       CurrentDir : string;
+       CachedCurrentDir : string;
+   function GetCurrentDir:string;
      begin
      begin
-       GetDir(0,CurrentDir);
-       GetCurrentDir:=FixPath(CurrentDir,false);
+       if CachedCurrentDir='' then
+         begin
+           GetDir(0,CachedCurrentDir);
+           CachedCurrentDir:=FixPath(CachedCurrentDir,false);
+         end;
+       result:=CachedCurrentDir;
      end;
      end;
 
 
 
 
@@ -1398,7 +1402,8 @@ implementation
       {$endif}
       {$endif}
 
 
 
 
-{$ifdef CPUI386}
+{$if defined(CPUI386) or defined(CPUX86_64)}
+  {$define HASSETFPUEXCEPTIONMASK}
       { later, this should be replaced by the math unit }
       { later, this should be replaced by the math unit }
       const
       const
         Default8087CW : word = $1332;
         Default8087CW : word = $1332;
@@ -1420,17 +1425,18 @@ implementation
         end;
         end;
 
 
 
 
-      function SetFPUExceptionMask(const Mask: TFPUExceptionMask): TFPUExceptionMask;
+      procedure SetFPUExceptionMask(const Mask: TFPUExceptionMask);
         var
         var
           CtlWord: Word;
           CtlWord: Word;
         begin
         begin
           CtlWord:=Get8087CW;
           CtlWord:=Get8087CW;
           Set8087CW( (CtlWord and $FFC0) or Byte(Longint(Mask)) );
           Set8087CW( (CtlWord and $FFC0) or Byte(Longint(Mask)) );
-          Result:=TFPUExceptionMask(Longint(CtlWord and $3F));
         end;
         end;
-{$else CPUI386}
+{$endif CPUI386 OR CPUX86_64}
+
 {$ifdef CPUPOWERPC}
 {$ifdef CPUPOWERPC}
-      function SetFPUExceptionMask(const Mask: TFPUExceptionMask): TFPUExceptionMask;
+  {$define HASSETFPUEXCEPTIONMASK}
+      procedure SetFPUExceptionMask(const Mask: TFPUExceptionMask);
         var
         var
           newmask: record
           newmask: record
             case byte of
             case byte of
@@ -1480,12 +1486,59 @@ implementation
             mtfsf 255,f0
             mtfsf 255,f0
           end;
           end;
         end;
         end;
-{$else CPUPOWERPC}
+{$endif CPUPOWERPC}
+
+{$ifdef CPUSPARC}
+  {$define HASSETFPUEXCEPTIONMASK}
+      procedure SetFPUExceptionMask(const Mask: TFPUExceptionMask);
+        var
+          fsr : cardinal;
+        begin
+          { load current control register contents }
+          asm
+            st %fsr,fsr
+          end;
+          { invalid operation: bit 27 }
+          if (exInvalidOp in mask) then
+            fsr:=fsr and not(1 shl 27)
+          else
+            fsr:=fsr or (1 shl 27);
+
+          { zero divide: bit 24 }
+          if (exZeroDivide in mask) then
+            fsr:=fsr and not(1 shl 24)
+          else
+            fsr:=fsr or (1 shl 24);
+
+          { overflow: bit 26 }
+          if (exOverflow in mask) then
+            fsr:=fsr and not(1 shl 26)
+          else
+            fsr:=fsr or (1 shl 26);
+
+          { underflow: bit 25 }
+          if (exUnderflow in mask) then
+            fsr:=fsr and not(1 shl 25)
+          else
+            fsr:=fsr or (1 shl 25);
+
+          { Precision (inexact result): bit 23 }
+          if (exPrecision in mask) then
+            fsr:=fsr and not(1 shl 23)
+          else
+            fsr:=fsr or (1 shl 23);
+          { update control register contents }
+          asm
+            ld fsr,%fsr
+          end;
+        end;
+{$endif CPUSPARC}
+
+{$ifndef HASSETFPUEXCEPTIONMASK}
       function SetFPUExceptionMask(const Mask: TFPUExceptionMask): TFPUExceptionMask;
       function SetFPUExceptionMask(const Mask: TFPUExceptionMask): TFPUExceptionMask;
         begin
         begin
         end;
         end;
-{$endif CPUPOWERPC}
-{$endif CPUI386}
+{$endif HASSETFPUEXCEPTIONMASK}
 
 
       function is_number_float(d : double) : boolean;
       function is_number_float(d : double) : boolean;
         var
         var
@@ -1960,7 +2013,10 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.138  2004-09-08 11:23:31  michael
+  Revision 1.139  2004-09-21 17:25:12  peter
+    * paraloc branch merged
+
+  Revision 1.138  2004/09/08 11:23:31  michael
   + Check if outputdir exists,  Fix exitcode when displaying help pages
   + Check if outputdir exists,  Fix exitcode when displaying help pages
 
 
   Revision 1.137  2004/08/31 22:02:30  olle
   Revision 1.137  2004/08/31 22:02:30  olle
@@ -1968,6 +2024,12 @@ end.
       compiler directives which take paths, will support quotes.
       compiler directives which take paths, will support quotes.
     * uppdated TranslateMacPath
     * uppdated TranslateMacPath
 
 
+  Revision 1.136.4.2  2004/09/12 18:31:26  peter
+    * fpu exception support for sparc and x86_64
+
+  Revision 1.136.4.1  2004/09/12 15:30:16  peter
+    * cache currentdir
+
   Revision 1.136  2004/08/28 20:25:25  peter
   Revision 1.136  2004/08/28 20:25:25  peter
     * optimized search for noncasesensitive names. It now searches
     * optimized search for noncasesensitive names. It now searches
       first for NormalCase and skips double tests
       first for NormalCase and skips double tests

+ 46 - 34
compiler/i386/cgcpu.pas

@@ -20,8 +20,6 @@
 
 
  ****************************************************************************
  ****************************************************************************
 }
 }
-{ This unit implements the code generator for the i386.
-}
 unit cgcpu;
 unit cgcpu;
 
 
 {$i fpcdefs.inc}
 {$i fpcdefs.inc}
@@ -32,7 +30,7 @@ unit cgcpu;
        globtype,
        globtype,
        cgbase,cgobj,cg64f32,cgx86,
        cgbase,cgobj,cg64f32,cgx86,
        aasmbase,aasmtai,aasmcpu,
        aasmbase,aasmtai,aasmcpu,
-       cpubase,cpuinfo,
+       cpubase,cpuinfo,parabase,
        node,symconst
        node,symconst
 {$ifdef delphi}
 {$ifdef delphi}
        ,dmisc
        ,dmisc
@@ -43,13 +41,13 @@ unit cgcpu;
       tcg386 = class(tcgx86)
       tcg386 = class(tcgx86)
         procedure init_register_allocators;override;
         procedure init_register_allocators;override;
         { passing parameter using push instead of mov }
         { passing parameter using push instead of mov }
-        procedure a_param_reg(list : taasmoutput;size : tcgsize;r : tregister;const locpara : tparalocation);override;
-        procedure a_param_const(list : taasmoutput;size : tcgsize;a : aint;const locpara : tparalocation);override;
-        procedure a_param_ref(list : taasmoutput;size : tcgsize;const r : treference;const locpara : tparalocation);override;
-        procedure a_paramaddr_ref(list : taasmoutput;const r : treference;const locpara : tparalocation);override;
+        procedure a_param_reg(list : taasmoutput;size : tcgsize;r : tregister;const cgpara : tcgpara);override;
+        procedure a_param_const(list : taasmoutput;size : tcgsize;a : aint;const cgpara : tcgpara);override;
+        procedure a_param_ref(list : taasmoutput;size : tcgsize;const r : treference;const cgpara : tcgpara);override;
+        procedure a_paramaddr_ref(list : taasmoutput;const r : treference;const cgpara : tcgpara);override;
 
 
         procedure g_save_all_registers(list : taasmoutput);override;
         procedure g_save_all_registers(list : taasmoutput);override;
-        procedure g_restore_all_registers(list : taasmoutput;const funcretparaloc:tparalocation);override;
+        procedure g_restore_all_registers(list : taasmoutput;const funcretparaloc:tcgpara);override;
         procedure g_proc_exit(list : taasmoutput;parasize:longint;nostackframe:boolean);override;
         procedure g_proc_exit(list : taasmoutput;parasize:longint;nostackframe:boolean);override;
         procedure g_copyvaluepara_openarray(list : taasmoutput;const ref, lenref:treference;elesize:aint);override;
         procedure g_copyvaluepara_openarray(list : taasmoutput;const ref, lenref:treference;elesize:aint);override;
 
 
@@ -71,7 +69,7 @@ unit cgcpu;
 
 
     uses
     uses
        globals,verbose,systems,cutils,
        globals,verbose,systems,cutils,
-       symdef,symsym,defutil,paramgr,procinfo,
+       paramgr,procinfo,
        rgcpu,rgx86,tgobj,
        rgcpu,rgx86,tgobj,
        cgutils;
        cgutils;
 
 
@@ -88,47 +86,50 @@ unit cgcpu;
       end;
       end;
 
 
 
 
-    procedure tcg386.a_param_reg(list : taasmoutput;size : tcgsize;r : tregister;const locpara : tparalocation);
+    procedure tcg386.a_param_reg(list : taasmoutput;size : tcgsize;r : tregister;const cgpara : tcgpara);
       var
       var
         pushsize : tcgsize;
         pushsize : tcgsize;
       begin
       begin
         check_register_size(size,r);
         check_register_size(size,r);
-        with locpara do
-          if (loc=LOC_REFERENCE) and
-             (reference.index=NR_STACK_POINTER_REG) then
+        with cgpara do
+          if assigned(location) and
+             (location^.loc=LOC_REFERENCE) and
+             (location^.reference.index=NR_STACK_POINTER_REG) then
             begin
             begin
               pushsize:=int_cgsize(alignment);
               pushsize:=int_cgsize(alignment);
               list.concat(taicpu.op_reg(A_PUSH,tcgsize2opsize[pushsize],makeregsize(list,r,pushsize)));
               list.concat(taicpu.op_reg(A_PUSH,tcgsize2opsize[pushsize],makeregsize(list,r,pushsize)));
             end
             end
           else
           else
-            inherited a_param_reg(list,size,r,locpara);
+            inherited a_param_reg(list,size,r,cgpara);
       end;
       end;
 
 
 
 
-    procedure tcg386.a_param_const(list : taasmoutput;size : tcgsize;a : aint;const locpara : tparalocation);
+    procedure tcg386.a_param_const(list : taasmoutput;size : tcgsize;a : aint;const cgpara : tcgpara);
       var
       var
         pushsize : tcgsize;
         pushsize : tcgsize;
       begin
       begin
-        with locpara do
-          if (loc=LOC_REFERENCE) and
-             (reference.index=NR_STACK_POINTER_REG) then
+        with cgpara do
+          if assigned(location) and
+             (location^.loc=LOC_REFERENCE) and
+             (location^.reference.index=NR_STACK_POINTER_REG) then
             begin
             begin
               pushsize:=int_cgsize(alignment);
               pushsize:=int_cgsize(alignment);
               list.concat(taicpu.op_const(A_PUSH,tcgsize2opsize[pushsize],a));
               list.concat(taicpu.op_const(A_PUSH,tcgsize2opsize[pushsize],a));
             end
             end
           else
           else
-            inherited a_param_const(list,size,a,locpara);
+            inherited a_param_const(list,size,a,cgpara);
       end;
       end;
 
 
 
 
-    procedure tcg386.a_param_ref(list : taasmoutput;size : tcgsize;const r : treference;const locpara : tparalocation);
+    procedure tcg386.a_param_ref(list : taasmoutput;size : tcgsize;const r : treference;const cgpara : tcgpara);
       var
       var
         pushsize : tcgsize;
         pushsize : tcgsize;
         tmpreg : tregister;
         tmpreg : tregister;
       begin
       begin
-        with locpara do
-          if (loc=LOC_REFERENCE) and
-             (reference.index=NR_STACK_POINTER_REG) then
+        with cgpara do
+          if assigned(location) and
+             (location^.loc=LOC_REFERENCE) and
+             (location^.reference.index=NR_STACK_POINTER_REG) then
             begin
             begin
               pushsize:=int_cgsize(alignment);
               pushsize:=int_cgsize(alignment);
               if tcgsize2size[size]<alignment then
               if tcgsize2size[size]<alignment then
@@ -142,11 +143,11 @@ unit cgcpu;
                 list.concat(taicpu.op_ref(A_PUSH,TCgsize2opsize[pushsize],r));
                 list.concat(taicpu.op_ref(A_PUSH,TCgsize2opsize[pushsize],r));
             end
             end
           else
           else
-            inherited a_param_ref(list,size,r,locpara);
+            inherited a_param_ref(list,size,r,cgpara);
       end;
       end;
 
 
 
 
-    procedure tcg386.a_paramaddr_ref(list : taasmoutput;const r : treference;const locpara : tparalocation);
+    procedure tcg386.a_paramaddr_ref(list : taasmoutput;const r : treference;const cgpara : tcgpara);
       var
       var
         tmpreg : tregister;
         tmpreg : tregister;
         opsize : topsize;
         opsize : topsize;
@@ -155,9 +156,10 @@ unit cgcpu;
           begin
           begin
             if (segment<>NR_NO) then
             if (segment<>NR_NO) then
               cgmessage(cg_e_cant_use_far_pointer_there);
               cgmessage(cg_e_cant_use_far_pointer_there);
-            with locpara do
-              if (locpara.loc=LOC_REFERENCE) and
-                 (locpara.reference.index=NR_STACK_POINTER_REG) then
+            with cgpara do
+              if assigned(location) and
+                 (location^.loc=LOC_REFERENCE) and
+                 (location^.reference.index=NR_STACK_POINTER_REG) then
                 begin
                 begin
                   opsize:=tcgsize2opsize[OS_ADDR];
                   opsize:=tcgsize2opsize[OS_ADDR];
                   if (base=NR_NO) and (index=NR_NO) then
                   if (base=NR_NO) and (index=NR_NO) then
@@ -182,7 +184,7 @@ unit cgcpu;
                     end;
                     end;
                 end
                 end
               else
               else
-                inherited a_paramaddr_ref(list,r,locpara);
+                inherited a_paramaddr_ref(list,r,cgpara);
         end;
         end;
       end;
       end;
 
 
@@ -195,13 +197,14 @@ unit cgcpu;
       end;
       end;
 
 
 
 
-    procedure tcg386.g_restore_all_registers(list : taasmoutput;const funcretparaloc:tparalocation);
+    procedure tcg386.g_restore_all_registers(list : taasmoutput;const funcretparaloc:tcgpara);
       var
       var
         href : treference;
         href : treference;
       begin
       begin
         a_load_ref_reg(list,OS_ADDR,OS_ADDR,current_procinfo.save_regs_ref,NR_STACK_POINTER_REG);
         a_load_ref_reg(list,OS_ADDR,OS_ADDR,current_procinfo.save_regs_ref,NR_STACK_POINTER_REG);
         tg.UnGetTemp(list,current_procinfo.save_regs_ref);
         tg.UnGetTemp(list,current_procinfo.save_regs_ref);
-        if funcretparaloc.loc=LOC_REGISTER then
+        if assigned(funcretparaloc.location) and
+           (funcretparaloc.location^.loc=LOC_REGISTER) then
           begin
           begin
             if funcretparaloc.size in [OS_64,OS_S64] then
             if funcretparaloc.size in [OS_64,OS_S64] then
               begin
               begin
@@ -252,13 +255,16 @@ unit cgcpu;
         { return from proc }
         { return from proc }
         if (po_interrupt in current_procinfo.procdef.procoptions) then
         if (po_interrupt in current_procinfo.procdef.procoptions) then
           begin
           begin
-            if current_procinfo.procdef.funcret_paraloc[calleeside].loc=LOC_REGISTER then
+            if assigned(current_procinfo.procdef.funcret_paraloc[calleeside].location) and
+               (current_procinfo.procdef.funcret_paraloc[calleeside].location^.loc=LOC_REGISTER) then
               list.concat(Taicpu.Op_const_reg(A_ADD,S_L,4,NR_ESP))
               list.concat(Taicpu.Op_const_reg(A_ADD,S_L,4,NR_ESP))
             else
             else
               list.concat(Taicpu.Op_reg(A_POP,S_L,NR_EAX));
               list.concat(Taicpu.Op_reg(A_POP,S_L,NR_EAX));
             list.concat(Taicpu.Op_reg(A_POP,S_L,NR_EBX));
             list.concat(Taicpu.Op_reg(A_POP,S_L,NR_EBX));
             list.concat(Taicpu.Op_reg(A_POP,S_L,NR_ECX));
             list.concat(Taicpu.Op_reg(A_POP,S_L,NR_ECX));
-            if current_procinfo.procdef.funcret_paraloc[calleeside].lochigh=LOC_REGISTER then
+            if assigned(current_procinfo.procdef.funcret_paraloc[calleeside].location) and
+               assigned(current_procinfo.procdef.funcret_paraloc[calleeside].location^.next) and
+               (current_procinfo.procdef.funcret_paraloc[calleeside].location^.next^.loc=LOC_REGISTER) then
               list.concat(Taicpu.Op_const_reg(A_ADD,S_L,4,NR_ESP))
               list.concat(Taicpu.Op_const_reg(A_ADD,S_L,4,NR_ESP))
             else
             else
               list.concat(Taicpu.Op_reg(A_POP,S_L,NR_EDX));
               list.concat(Taicpu.Op_reg(A_POP,S_L,NR_EDX));
@@ -552,7 +558,13 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.51  2004-07-09 23:30:13  jonas
+  Revision 1.52  2004-09-21 17:25:12  peter
+    * paraloc branch merged
+
+  Revision 1.51.4.1  2004/08/31 20:43:06  peter
+    * paraloc patch
+
+  Revision 1.51  2004/07/09 23:30:13  jonas
     *  changed first_sse_imreg to first_mm_imreg
     *  changed first_sse_imreg to first_mm_imreg
 
 
   Revision 1.50  2004/06/20 08:55:31  florian
   Revision 1.50  2004/06/20 08:55:31  florian

+ 167 - 112
compiler/i386/cpupara.pas

@@ -20,8 +20,6 @@
 
 
  ****************************************************************************
  ****************************************************************************
 }
 }
-{ Generates the argument location information for i386.
-}
 unit cpupara;
 unit cpupara;
 
 
 {$i fpcdefs.inc}
 {$i fpcdefs.inc}
@@ -30,10 +28,9 @@ unit cpupara;
 
 
     uses
     uses
        cclasses,globtype,
        cclasses,globtype,
-       aasmtai,
-       cpubase,
-       cgbase,
-       symconst,symtype,symdef,paramgr;
+       aasmtai,cpubase,cgbase,
+       symconst,symtype,symdef,
+       parabase,paramgr;
 
 
     type
     type
        ti386paramanager = class(tparamanager)
        ti386paramanager = class(tparamanager)
@@ -48,9 +45,10 @@ unit cpupara;
             and if the calling conventions for the helper routines of the
             and if the calling conventions for the helper routines of the
             rtl are used.
             rtl are used.
           }
           }
-          function getintparaloc(calloption : tproccalloption; nr : longint) : tparalocation;override;
+          procedure getintparaloc(calloption : tproccalloption; nr : longint;var cgpara:TCGPara);override;
           function create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;override;
           function create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;override;
           function create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargspara):longint;override;
           function create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargspara):longint;override;
+          procedure createtempparaloc(list: taasmoutput;calloption : tproccalloption;paraitem : tparaitem;var cgpara:TCGPara);override;
        private
        private
           procedure create_funcret_paraloc_info(p : tabstractprocdef; side: tcallercallee);
           procedure create_funcret_paraloc_info(p : tabstractprocdef; side: tcallercallee);
           procedure create_stdcall_paraloc_info(p : tabstractprocdef; side: tcallercallee;firstpara:tparaitem;
           procedure create_stdcall_paraloc_info(p : tabstractprocdef; side: tcallercallee;firstpara:tparaitem;
@@ -64,8 +62,7 @@ unit cpupara;
     uses
     uses
        cutils,
        cutils,
        systems,verbose,
        systems,verbose,
-       defutil,
-       cpuinfo;
+       defutil;
 
 
       const
       const
         parasupregs : array[0..2] of tsuperregister = (RS_EAX,RS_EDX,RS_ECX);
         parasupregs : array[0..2] of tsuperregister = (RS_EAX,RS_EDX,RS_ECX);
@@ -190,76 +187,105 @@ unit cpupara;
       end;
       end;
 
 
 
 
-    function ti386paramanager.getintparaloc(calloption : tproccalloption; nr : longint) : tparalocation;
+    procedure ti386paramanager.getintparaloc(calloption : tproccalloption; nr : longint;var cgpara:TCGPara);
+      var
+        paraloc : pcgparalocation;
       begin
       begin
-         fillchar(result,sizeof(tparalocation),0);
-         result.size:=OS_INT;
-         result.lochigh:=LOC_INVALID;
-         result.alignment:=get_para_align(calloption);
-         if calloption=pocall_register then
-           begin
-             if (nr<=high(parasupregs)+1) then
-               begin
-                 if nr=0 then
-                   internalerror(200309271);
-                 result.loc:=LOC_REGISTER;
-                 result.register:=newreg(R_INTREGISTER,parasupregs[nr-1],R_SUBWHOLE);
-               end
-             else
-               begin
-                 result.loc:=LOC_REFERENCE;
-                 result.reference.index:=NR_STACK_POINTER_REG;
-                 result.reference.offset:=sizeof(aint)*nr;
-               end;
-           end
-         else
-           begin
-             result.loc:=LOC_REFERENCE;
-             result.reference.index:=NR_STACK_POINTER_REG;
-             result.reference.offset:=sizeof(aint)*nr;
-           end;
+        cgpara.reset;
+        cgpara.size:=OS_INT;
+        cgpara.alignment:=get_para_align(calloption);
+        paraloc:=cgpara.add_location;
+        with paraloc^ do
+         begin
+           size:=OS_INT;
+           if calloption=pocall_register then
+             begin
+               if (nr<=high(parasupregs)+1) then
+                 begin
+                   if nr=0 then
+                     internalerror(200309271);
+                   loc:=LOC_REGISTER;
+                   register:=newreg(R_INTREGISTER,parasupregs[nr-1],R_SUBWHOLE);
+                 end
+               else
+                 begin
+                   loc:=LOC_REFERENCE;
+                   reference.index:=NR_STACK_POINTER_REG;
+                   reference.offset:=sizeof(aint)*nr;
+                 end;
+             end
+           else
+             begin
+               loc:=LOC_REFERENCE;
+               reference.index:=NR_STACK_POINTER_REG;
+               reference.offset:=sizeof(aint)*nr;
+             end;
+          end;
       end;
       end;
 
 
 
 
     procedure ti386paramanager.create_funcret_paraloc_info(p : tabstractprocdef; side: tcallercallee);
     procedure ti386paramanager.create_funcret_paraloc_info(p : tabstractprocdef; side: tcallercallee);
       var
       var
-        paraloc : tparalocation;
+        hiparaloc,
+        paraloc : pcgparalocation;
+        retcgsize  : tcgsize;
       begin
       begin
-        { Function return }
-        fillchar(paraloc,sizeof(tparalocation),0);
+        { Constructors return self instead of a boolean }
         if (p.proctypeoption=potype_constructor) then
         if (p.proctypeoption=potype_constructor) then
-          paraloc.size:=OS_ADDR
+          retcgsize:=OS_ADDR
         else
         else
-          paraloc.size:=def_cgsize(p.rettype.def);
-        paraloc.lochigh:=LOC_INVALID;
-        if paraloc.size<>OS_NO then
+          retcgsize:=def_cgsize(p.rettype.def);
+        p.funcret_paraloc[side].reset;
+        p.funcret_paraloc[side].Alignment:=std_param_align;
+        p.funcret_paraloc[side].size:=retcgsize;
+        { void has no location }
+        if is_void(p.rettype.def) then
+          exit;
+        paraloc:=p.funcret_paraloc[side].add_location;
+        { Return in FPU register? }
+        if p.rettype.def.deftype=floatdef then
           begin
           begin
-            { Return in FPU register? }
-            if p.rettype.def.deftype=floatdef then
-              begin
-                paraloc.loc:=LOC_FPUREGISTER;
-                paraloc.register:=NR_FPU_RESULT_REG;
-              end
-            else
-             { Return in register? }
-             if not ret_in_param(p.rettype.def,p.proccalloption) then
-              begin
-                paraloc.loc:=LOC_REGISTER;
-                if paraloc.size in [OS_64,OS_S64] then
-                  begin
-                    paraloc.lochigh:=LOC_REGISTER;
-                    paraloc.register64.reglo:=NR_FUNCTION_RETURN64_LOW_REG;
-                    paraloc.register64.reghi:=NR_FUNCTION_RETURN64_HIGH_REG;
-                  end
-                else
-                  paraloc.register:=newreg(R_INTREGISTER,RS_FUNCTION_RETURN_REG,cgsize2subreg(paraloc.size));
-              end
+            paraloc^.loc:=LOC_FPUREGISTER;
+            paraloc^.register:=NR_FPU_RESULT_REG;
+            paraloc^.size:=retcgsize;
+          end
+        else
+         { Return in register? }
+         if not ret_in_param(p.rettype.def,p.proccalloption) then
+          begin
+            if retcgsize in [OS_64,OS_S64] then
+             begin
+               { low 32bits }
+               paraloc^.loc:=LOC_REGISTER;
+               paraloc^.size:=OS_32;
+               if side=callerside then
+                 paraloc^.register:=NR_FUNCTION_RESULT64_LOW_REG
+               else
+                 paraloc^.register:=NR_FUNCTION_RETURN64_LOW_REG;
+               { high 32bits }
+               hiparaloc:=p.funcret_paraloc[side].add_location;
+               hiparaloc^.loc:=LOC_REGISTER;
+               hiparaloc^.size:=OS_32;
+               if side=callerside then
+                 hiparaloc^.register:=NR_FUNCTION_RESULT64_HIGH_REG
+               else
+                 hiparaloc^.register:=NR_FUNCTION_RETURN64_HIGH_REG;
+             end
             else
             else
-              begin
-                paraloc.loc:=LOC_REFERENCE;
-              end;
+             begin
+               paraloc^.loc:=LOC_REGISTER;
+               paraloc^.size:=retcgsize;
+               if side=callerside then
+                 paraloc^.register:=newreg(R_INTREGISTER,RS_FUNCTION_RESULT_REG,cgsize2subreg(retcgsize))
+               else
+                 paraloc^.register:=newreg(R_INTREGISTER,RS_FUNCTION_RETURN_REG,cgsize2subreg(retcgsize));
+             end;
+          end
+        else
+          begin
+            paraloc^.loc:=LOC_REFERENCE;
+            paraloc^.size:=retcgsize;
           end;
           end;
-        p.funcret_paraloc[side]:=paraloc;
       end;
       end;
 
 
 
 
@@ -267,10 +293,11 @@ unit cpupara;
                                                            var parasize:longint);
                                                            var parasize:longint);
       var
       var
         hp : tparaitem;
         hp : tparaitem;
-        paraloc : tparalocation;
+        paraloc : pcgparalocation;
         l,
         l,
         varalign,
         varalign,
         paraalign : longint;
         paraalign : longint;
+        paracgsize : tcgsize;
       begin
       begin
         paraalign:=get_para_align(p.proccalloption);
         paraalign:=get_para_align(p.proccalloption);
         { we push Flags and CS as long
         { we push Flags and CS as long
@@ -284,28 +311,34 @@ unit cpupara;
            mov [esp+4],para2
            mov [esp+4],para2
            mov [esp],para1
            mov [esp],para1
            call function
            call function
-          That means the for pushes the para with the
+          That means for pushes the para with the
           highest offset (see para3) needs to be pushed first
           highest offset (see para3) needs to be pushed first
         }
         }
         hp:=firstpara;
         hp:=firstpara;
         while assigned(hp) do
         while assigned(hp) do
           begin
           begin
-            if hp.paratyp in [vs_var,vs_out] then
-              paraloc.size:=OS_ADDR
+            if push_addr_param(hp.paratyp,hp.paratype.def,p.proccalloption) then
+              paracgsize:=OS_ADDR
             else
             else
-              paraloc.size:=def_cgsize(hp.paratype.def);
-            paraloc.loc:=LOC_REFERENCE;
-            paraloc.lochigh:=LOC_INVALID;
-            paraloc.alignment:=paraalign;
+              begin
+                paracgsize:=def_cgSize(hp.paratype.def);
+                if paracgsize=OS_NO then
+                  paracgsize:=OS_ADDR;
+              end;
+            hp.paraloc[side].reset;
+            hp.paraloc[side].size:=paracgsize;
+            hp.paraloc[side].Alignment:=paraalign;
+            paraloc:=hp.paraloc[side].add_location;
+            paraloc^.loc:=LOC_REFERENCE;
+            paraloc^.size:=paracgsize;
             if side=callerside then
             if side=callerside then
-              paraloc.reference.index:=NR_STACK_POINTER_REG
+              paraloc^.reference.index:=NR_STACK_POINTER_REG
             else
             else
-              paraloc.reference.index:=NR_FRAME_POINTER_REG;
+              paraloc^.reference.index:=NR_FRAME_POINTER_REG;
             l:=push_size(hp.paratyp,hp.paratype.def,p.proccalloption);
             l:=push_size(hp.paratyp,hp.paratype.def,p.proccalloption);
             varalign:=used_align(size_2_align(l),paraalign,paraalign);
             varalign:=used_align(size_2_align(l),paraalign,paraalign);
-            paraloc.reference.offset:=parasize;
+            paraloc^.reference.offset:=parasize;
             parasize:=align(parasize+l,varalign);
             parasize:=align(parasize+l,varalign);
-            hp.paraloc[side]:=paraloc;
             hp:=tparaitem(hp.next);
             hp:=tparaitem(hp.next);
           end;
           end;
         { Adapt offsets for left-to-right calling }
         { Adapt offsets for left-to-right calling }
@@ -317,9 +350,12 @@ unit cpupara;
                 l:=push_size(hp.paratyp,hp.paratype.def,p.proccalloption);
                 l:=push_size(hp.paratyp,hp.paratype.def,p.proccalloption);
                 varalign:=used_align(size_2_align(l),paraalign,paraalign);
                 varalign:=used_align(size_2_align(l),paraalign,paraalign);
                 l:=align(l,varalign);
                 l:=align(l,varalign);
-                hp.paraloc[side].reference.offset:=parasize-hp.paraloc[side].reference.offset-l;
-                if side=calleeside then
-                  inc(hp.paraloc[side].reference.offset,target_info.first_parm_offset);
+                with hp.paraloc[side].location^ do
+                  begin
+                    reference.offset:=parasize-reference.offset-l;
+                    if side=calleeside then
+                      inc(reference.offset,target_info.first_parm_offset);
+                  end;
                 hp:=tparaitem(hp.next);
                 hp:=tparaitem(hp.next);
               end;
               end;
           end
           end
@@ -332,7 +368,7 @@ unit cpupara;
                 hp:=tparaitem(p.para.first);
                 hp:=tparaitem(p.para.first);
                 while assigned(hp) do
                 while assigned(hp) do
                   begin
                   begin
-                    inc(hp.paraloc[side].reference.offset,target_info.first_parm_offset);
+                    inc(hp.paraloc[side].location^.reference.offset,target_info.first_parm_offset);
                     hp:=tparaitem(hp.next);
                     hp:=tparaitem(hp.next);
                   end;
                   end;
                end;
                end;
@@ -344,10 +380,10 @@ unit cpupara;
                                                             var parareg,parasize:longint);
                                                             var parareg,parasize:longint);
       var
       var
         hp : tparaitem;
         hp : tparaitem;
-        paraloc : tparalocation;
-        subreg : tsubregister;
+        paraloc : pcgparalocation;
         pushaddr,
         pushaddr,
         is_64bit : boolean;
         is_64bit : boolean;
+        paracgsize : tcgsize;
         l,
         l,
         varalign,
         varalign,
         paraalign : longint;
         paraalign : longint;
@@ -359,11 +395,13 @@ unit cpupara;
           begin
           begin
             pushaddr:=push_addr_param(hp.paratyp,hp.paratype.def,p.proccalloption);
             pushaddr:=push_addr_param(hp.paratyp,hp.paratype.def,p.proccalloption);
             if pushaddr then
             if pushaddr then
-              paraloc.size:=OS_ADDR
+              paracgsize:=OS_ADDR
             else
             else
-              paraloc.size:=def_cgsize(hp.paratype.def);
-            paraloc.alignment:=paraalign;
-            is_64bit:=(paraloc.size in [OS_64,OS_S64,OS_F64]);
+              paracgsize:=def_cgsize(hp.paratype.def);
+            is_64bit:=(paracgsize in [OS_64,OS_S64,OS_F64]);
+            hp.paraloc[side].reset;
+            hp.paraloc[side].size:=paracgsize;
+            hp.paraloc[side].Alignment:=paraalign;
             {
             {
               EAX
               EAX
               EDX
               EDX
@@ -374,6 +412,8 @@ unit cpupara;
               64bit values,floats,arrays and records are always
               64bit values,floats,arrays and records are always
               on the stack.
               on the stack.
             }
             }
+            paraloc:=hp.paraloc[side].add_location;
+            paraloc^.size:=paracgsize;
             if (parareg<=high(parasupregs)) and
             if (parareg<=high(parasupregs)) and
                not(
                not(
                    is_64bit or
                    is_64bit or
@@ -381,31 +421,23 @@ unit cpupara;
                     (not pushaddr))
                     (not pushaddr))
                   ) then
                   ) then
               begin
               begin
-                paraloc.loc:=LOC_REGISTER;
-                paraloc.lochigh:=LOC_INVALID;
-                if (paraloc.size=OS_NO) or is_64bit then
-                  subreg:=R_SUBWHOLE
-                else
-                  subreg:=cgsize2subreg(paraloc.size);
-                paraloc.alignment:=paraalign;
-                paraloc.register:=newreg(R_INTREGISTER,parasupregs[parareg],subreg);
+                paraloc^.loc:=LOC_REGISTER;
+                paraloc^.register:=newreg(R_INTREGISTER,parasupregs[parareg],cgsize2subreg(paracgsize));
                 inc(parareg);
                 inc(parareg);
               end
               end
             else
             else
               begin
               begin
-                paraloc.loc:=LOC_REFERENCE;
-                paraloc.lochigh:=LOC_INVALID;
+                paraloc^.loc:=LOC_REFERENCE;
                 if side=callerside then
                 if side=callerside then
-                  paraloc.reference.index:=NR_STACK_POINTER_REG
+                  paraloc^.reference.index:=NR_STACK_POINTER_REG
                 else
                 else
-                  paraloc.reference.index:=NR_FRAME_POINTER_REG;
+                  paraloc^.reference.index:=NR_FRAME_POINTER_REG;
                 l:=push_size(hp.paratyp,hp.paratype.def,p.proccalloption);
                 l:=push_size(hp.paratyp,hp.paratype.def,p.proccalloption);
                 varalign:=size_2_align(l);
                 varalign:=size_2_align(l);
-                paraloc.reference.offset:=parasize;
+                paraloc^.reference.offset:=parasize;
                 varalign:=used_align(varalign,paraalign,paraalign);
                 varalign:=used_align(varalign,paraalign,paraalign);
                 parasize:=align(parasize+l,varalign);
                 parasize:=align(parasize+l,varalign);
               end;
               end;
-            hp.paraloc[side]:=paraloc;
             hp:=tparaitem(hp.next);
             hp:=tparaitem(hp.next);
           end;
           end;
         { Register parameters are assigned from left-to-right, adapt offset
         { Register parameters are assigned from left-to-right, adapt offset
@@ -413,15 +445,18 @@ unit cpupara;
         hp:=tparaitem(p.para.first);
         hp:=tparaitem(p.para.first);
         while assigned(hp) do
         while assigned(hp) do
           begin
           begin
-            if (hp.paraloc[side].loc=LOC_REFERENCE) then
+            with hp.paraloc[side].location^ do
               begin
               begin
-                l:=push_size(hp.paratyp,hp.paratype.def,p.proccalloption);
-                varalign:=used_align(size_2_align(l),paraalign,paraalign);
-                l:=align(l,varalign);
-                hp.paraloc[side].reference.offset:=parasize-hp.paraloc[side].reference.offset-l;
-                if side=calleeside then
-                  inc(hp.paraloc[side].reference.offset,target_info.first_parm_offset);
-              end;
+                if (loc=LOC_REFERENCE) then
+                  begin
+                    l:=push_size(hp.paratyp,hp.paratype.def,p.proccalloption);
+                    varalign:=used_align(size_2_align(l),paraalign,paraalign);
+                    l:=align(l,varalign);
+                    reference.offset:=parasize-reference.offset-l;
+                    if side=calleeside then
+                      inc(reference.offset,target_info.first_parm_offset);
+                  end;
+               end;
             hp:=tparaitem(hp.next);
             hp:=tparaitem(hp.next);
           end;
           end;
       end;
       end;
@@ -468,13 +503,33 @@ unit cpupara;
       end;
       end;
 
 
 
 
+    procedure ti386paramanager.createtempparaloc(list: taasmoutput;calloption : tproccalloption;paraitem : tparaitem;var cgpara:TCGPara);
+      var
+        paraloc : pcgparalocation;
+      begin
+        paraloc:=paraitem.paraloc[callerside].location;
+        { No need for temps when value is pushed }
+        if assigned(paraloc) and
+           (paraloc^.loc=LOC_REFERENCE) and
+           (paraloc^.reference.index=NR_STACK_POINTER_REG) then
+          duplicateparaloc(list,calloption,paraitem,cgpara)
+        else
+          inherited createtempparaloc(list,calloption,paraitem,cgpara);
+      end;
+
 
 
 begin
 begin
    paramanager:=ti386paramanager.create;
    paramanager:=ti386paramanager.create;
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.54  2004-07-09 23:30:13  jonas
+  Revision 1.55  2004-09-21 17:25:12  peter
+    * paraloc branch merged
+
+  Revision 1.54.4.1  2004/08/31 20:43:06  peter
+    * paraloc patch
+
+  Revision 1.54  2004/07/09 23:30:13  jonas
     *  changed first_sse_imreg to first_mm_imreg
     *  changed first_sse_imreg to first_mm_imreg
 
 
   Revision 1.53  2004/07/09 23:09:02  peter
   Revision 1.53  2004/07/09 23:09:02  peter

+ 8 - 2
compiler/i386/csopt386.pas

@@ -1988,7 +1988,7 @@ begin
                               if (memreg <> NR_NO) and
                               if (memreg <> NR_NO) and
                                  (not getNextInstruction(p,hp1) or
                                  (not getNextInstruction(p,hp1) or
                                   (RegLoadedWithNewValue(getsupreg(memreg),false,hp1) or
                                   (RegLoadedWithNewValue(getsupreg(memreg),false,hp1) or
-                                   FindRegDealloc(regcounter,hp1))) then
+                                   FindRegDealloc(getsupreg(memreg),hp1))) then
                                 begin
                                 begin
                                   hp1 := Tai_Marker.Create(NoPropInfoEnd);
                                   hp1 := Tai_Marker.Create(NoPropInfoEnd);
                                   insertllitem(asml,p,p.next,hp1);
                                   insertllitem(asml,p,p.next,hp1);
@@ -2109,7 +2109,13 @@ end.
 
 
 {
 {
   $Log$
   $Log$
-  Revision 1.64  2004-07-23 13:30:19  jonas
+  Revision 1.65  2004-09-21 17:25:12  peter
+    * paraloc branch merged
+
+  Revision 1.64.4.1  2004/09/20 19:28:23  peter
+    * fixed valgrind warning
+
+  Revision 1.64  2004/07/23 13:30:19  jonas
     * fixed some more potential regvar bugs
     * fixed some more potential regvar bugs
 
 
   Revision 1.63  2004/06/20 08:55:31  florian
   Revision 1.63  2004/06/20 08:55:31  florian

+ 7 - 5
compiler/nadd.pas

@@ -1758,11 +1758,7 @@ implementation
                   if nodetype in [addn,subn,muln,andn,orn,xorn] then
                   if nodetype in [addn,subn,muln,andn,orn,xorn] then
                     expectloc:=LOC_REGISTER
                     expectloc:=LOC_REGISTER
                   else
                   else
-{$ifdef sparc}
-                    expectloc:=LOC_FLAGS;
-{$else sparc}
                     expectloc:=LOC_JUMP;
                     expectloc:=LOC_JUMP;
-{$endif sparc}
                   calcregisters(self,2,0,0)
                   calcregisters(self,2,0,0)
                end
                end
 {$endif cpu64bit}
 {$endif cpu64bit}
@@ -2034,10 +2030,16 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.128  2004-09-13 20:32:53  peter
+  Revision 1.129  2004-09-21 17:25:12  peter
+    * paraloc branch merged
+
+  Revision 1.128  2004/09/13 20:32:53  peter
     * only make both operands the same for xor,and,or when both are
     * only make both operands the same for xor,and,or when both are
       integer types
       integer types
 
 
+  Revision 1.127.4.1  2004/09/19 18:08:30  peter
+    * int64 compare fixed
+
   Revision 1.127  2004/08/17 19:04:36  jonas
   Revision 1.127  2004/08/17 19:04:36  jonas
     * fixed "if @procvar_of_object <> nil" in Delphi/TP mode for for non-x86
     * fixed "if @procvar_of_object <> nil" in Delphi/TP mode for for non-x86
 
 

+ 15 - 7
compiler/ncal.pas

@@ -29,7 +29,7 @@ interface
     uses
     uses
        cutils,cclasses,
        cutils,cclasses,
        globtype,cpuinfo,
        globtype,cpuinfo,
-       paramgr,
+       paramgr,parabase,
        node,nbas,nutils,
        node,nbas,nutils,
        {$ifdef state_tracking}
        {$ifdef state_tracking}
        nstate,
        nstate,
@@ -1787,8 +1787,10 @@ type
               Used order:
               Used order:
                 1. LOC_REFERENCE with smallest offset (x86 only)
                 1. LOC_REFERENCE with smallest offset (x86 only)
                 2. LOC_REFERENCE with most registers
                 2. LOC_REFERENCE with most registers
-                3. LOC_REGISTER with most registers }
-            currloc:=hpcurr.paraitem.paraloc[callerside].loc;
+                3. LOC_REGISTER with most registers
+              For the moment we only look at the first parameter field. Combining it
+              with multiple parameter fields will make things a lot complexer (PFV) }
+            currloc:=hpcurr.paraitem.paraloc[callerside].location^.loc;
             hpprev:=nil;
             hpprev:=nil;
             hp:=hpfirst;
             hp:=hpfirst;
             while assigned(hp) do
             while assigned(hp) do
@@ -1796,7 +1798,7 @@ type
                 case currloc of
                 case currloc of
                   LOC_REFERENCE :
                   LOC_REFERENCE :
                     begin
                     begin
-                      case hp.paraitem.paraloc[callerside].loc of
+                      case hp.paraitem.paraloc[callerside].location^.loc of
                         LOC_REFERENCE :
                         LOC_REFERENCE :
                           begin
                           begin
                             { Offset is calculated like:
                             { Offset is calculated like:
@@ -1810,7 +1812,7 @@ type
                             }
                             }
                             if (hpcurr.registersint>hp.registersint)
                             if (hpcurr.registersint>hp.registersint)
 {$ifdef x86}
 {$ifdef x86}
-                               or (hpcurr.paraitem.paraloc[callerside].reference.offset>hp.paraitem.paraloc[callerside].reference.offset)
+                               or (hpcurr.paraitem.paraloc[callerside].location^.reference.offset>hp.paraitem.paraloc[callerside].location^.reference.offset)
 {$endif x86}
 {$endif x86}
                                then
                                then
                               break;
                               break;
@@ -1823,7 +1825,7 @@ type
                   LOC_FPUREGISTER,
                   LOC_FPUREGISTER,
                   LOC_REGISTER :
                   LOC_REGISTER :
                     begin
                     begin
-                      if (hp.paraitem.paraloc[callerside].loc=currloc) and
+                      if (hp.paraitem.paraloc[callerside].location^.loc=currloc) and
                          (hpcurr.registersint>hp.registersint) then
                          (hpcurr.registersint>hp.registersint) then
                         break;
                         break;
                     end;
                     end;
@@ -2384,9 +2386,15 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.247  2004-09-13 20:29:00  peter
+  Revision 1.248  2004-09-21 17:25:12  peter
+    * paraloc branch merged
+
+  Revision 1.247  2004/09/13 20:29:00  peter
     * use realname for abstract procs found
     * use realname for abstract procs found
 
 
+  Revision 1.246.4.1  2004/08/31 20:43:06  peter
+    * paraloc patch
+
   Revision 1.246  2004/08/28 20:00:50  peter
   Revision 1.246  2004/08/28 20:00:50  peter
     * use objrealname in Message1
     * use objrealname in Message1
 
 

+ 8 - 2
compiler/ncgbas.pas

@@ -174,7 +174,7 @@ interface
                       begin
                       begin
                         op.typ:=top_ref;
                         op.typ:=top_ref;
                         new(op.ref);
                         new(op.ref);
-                        reference_reset_base(op.ref^,sym.localloc.reference.index,sym.localloc.reference.offset+sofs);
+                        reference_reset_base(op.ref^,sym.localloc.reference.base,sym.localloc.reference.offset+sofs);
                         op.ref^.index:=indexreg;
                         op.ref^.index:=indexreg;
 {$ifdef x86}
 {$ifdef x86}
                         op.ref^.scalefactor:=scale;
                         op.ref^.scalefactor:=scale;
@@ -496,7 +496,13 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.65  2004-07-16 19:45:15  jonas
+  Revision 1.66  2004-09-21 17:25:12  peter
+    * paraloc branch merged
+
+  Revision 1.65.4.1  2004/08/31 20:43:06  peter
+    * paraloc patch
+
+  Revision 1.65  2004/07/16 19:45:15  jonas
     + temps can now also hold fpu values in registers (take care with use,
     + temps can now also hold fpu values in registers (take care with use,
       bacause of the x86 fpu stack)
       bacause of the x86 fpu stack)
     * fpu parameters to node-inlined procedures can now also be put in
     * fpu parameters to node-inlined procedures can now also be put in

+ 219 - 213
compiler/ncgcal.pas

@@ -29,16 +29,18 @@ interface
     uses
     uses
       cpubase,
       cpubase,
       globtype,
       globtype,
+      parabase,
       symdef,node,ncal;
       symdef,node,ncal;
 
 
     type
     type
        tcgcallparanode = class(tcallparanode)
        tcgcallparanode = class(tcallparanode)
        private
        private
-          tempparaloc : tparalocation;
-          procedure allocate_tempparaloc;
+          tempcgpara : tcgpara;
           procedure push_addr_para;
           procedure push_addr_para;
           procedure push_value_para;
           procedure push_value_para;
        public
        public
+          constructor create(expr,next : tnode);override;
+          destructor destroy;override;
           procedure secondcallparan;override;
           procedure secondcallparan;override;
        end;
        end;
 
 
@@ -50,7 +52,7 @@ interface
           procedure pushparas;
           procedure pushparas;
           procedure freeparas;
           procedure freeparas;
        protected
        protected
-          framepointer_paraloc : tparalocation;
+          framepointer_paraloc : tcgpara;
           refcountedtemp : treference;
           refcountedtemp : treference;
           procedure handle_return_value;
           procedure handle_return_value;
           {# This routine is used to push the current frame pointer
           {# This routine is used to push the current frame pointer
@@ -100,22 +102,17 @@ implementation
                              TCGCALLPARANODE
                              TCGCALLPARANODE
 *****************************************************************************}
 *****************************************************************************}
 
 
-    procedure tcgcallparanode.allocate_tempparaloc;
+    constructor tcgcallparanode.create(expr,next : tnode);
       begin
       begin
-         { Allocate (temporary) paralocation }
-         tempparaloc:=paraitem.paraloc[callerside];
-         case tempparaloc.loc of
-           LOC_REGISTER,LOC_FPUREGISTER,LOC_MMREGISTER:
-             paramanager.alloctempregs(exprasmlist,tempparaloc);
-{$ifdef cputargethasfixedstack}
-           LOC_REFERENCE:
-             begin
-               { currently, we copy the value always to a secure location }
-               if not(assigned(aktcallnode.inlinecode)) then
-                 paramanager.alloctempparaloc(exprasmlist,aktcallnode.procdefinition.proccalloption,paraitem,tempparaloc);
-             end;
-{$endif cputargethasfixedstack}
-         end;
+        inherited create(expr,next);
+        tempcgpara.init;
+      end;
+
+
+    destructor tcgcallparanode.destroy;
+      begin
+        tempcgpara.done;
+        inherited destroy;
       end;
       end;
 
 
 
 
@@ -124,7 +121,7 @@ implementation
         if not(left.location.loc in [LOC_CREFERENCE,LOC_REFERENCE]) then
         if not(left.location.loc in [LOC_CREFERENCE,LOC_REFERENCE]) then
           internalerror(200304235);
           internalerror(200304235);
         location_release(exprasmlist,left.location);
         location_release(exprasmlist,left.location);
-        cg.a_paramaddr_ref(exprasmlist,left.location.reference,tempparaloc);
+        cg.a_paramaddr_ref(exprasmlist,left.location.reference,tempcgpara);
       end;
       end;
 
 
 
 
@@ -149,46 +146,46 @@ implementation
          begin
          begin
            location_release(exprasmlist,left.location);
            location_release(exprasmlist,left.location);
 {$ifdef i386}
 {$ifdef i386}
-           if tempparaloc.loc<>LOC_REFERENCE then
+           if tempcgpara.location^.loc<>LOC_REFERENCE then
              internalerror(200309291);
              internalerror(200309291);
            case left.location.loc of
            case left.location.loc of
              LOC_FPUREGISTER,
              LOC_FPUREGISTER,
              LOC_CFPUREGISTER:
              LOC_CFPUREGISTER:
                begin
                begin
-                 size:=align(TCGSize2Size[left.location.size],tempparaloc.alignment);
-                 if tempparaloc.reference.index=NR_STACK_POINTER_REG then
+                 size:=align(TCGSize2Size[left.location.size],tempcgpara.alignment);
+                 if tempcgpara.location^.reference.index=NR_STACK_POINTER_REG then
                    begin
                    begin
                      cg.g_stackpointer_alloc(exprasmlist,size);
                      cg.g_stackpointer_alloc(exprasmlist,size);
                      reference_reset_base(href,NR_STACK_POINTER_REG,0);
                      reference_reset_base(href,NR_STACK_POINTER_REG,0);
                    end
                    end
                  else
                  else
-                   reference_reset_base(href,tempparaloc.reference.index,tempparaloc.reference.offset);
+                   reference_reset_base(href,tempcgpara.location^.reference.index,tempcgpara.location^.reference.offset);
                  cg.a_loadfpu_reg_ref(exprasmlist,left.location.size,left.location.register,href);
                  cg.a_loadfpu_reg_ref(exprasmlist,left.location.size,left.location.register,href);
                end;
                end;
              LOC_MMREGISTER,
              LOC_MMREGISTER,
              LOC_CMMREGISTER:
              LOC_CMMREGISTER:
                begin
                begin
-                 size:=align(tfloatdef(left.resulttype.def).size,tempparaloc.alignment);
-                 if tempparaloc.reference.index=NR_STACK_POINTER_REG then
+                 size:=align(tfloatdef(left.resulttype.def).size,tempcgpara.alignment);
+                 if tempcgpara.location^.reference.index=NR_STACK_POINTER_REG then
                    begin
                    begin
                      cg.g_stackpointer_alloc(exprasmlist,size);
                      cg.g_stackpointer_alloc(exprasmlist,size);
                      reference_reset_base(href,NR_STACK_POINTER_REG,0);
                      reference_reset_base(href,NR_STACK_POINTER_REG,0);
                    end
                    end
                  else
                  else
-                   reference_reset_base(href,tempparaloc.reference.index,tempparaloc.reference.offset);
+                   reference_reset_base(href,tempcgpara.location^.reference.index,tempcgpara.location^.reference.offset);
                  cg.a_loadmm_reg_ref(exprasmlist,left.location.size,left.location.size,left.location.register,href,mms_movescalar);
                  cg.a_loadmm_reg_ref(exprasmlist,left.location.size,left.location.size,left.location.register,href,mms_movescalar);
                end;
                end;
              LOC_REFERENCE,
              LOC_REFERENCE,
              LOC_CREFERENCE :
              LOC_CREFERENCE :
                begin
                begin
-                 size:=align(left.resulttype.def.size,tempparaloc.alignment);
-                 if tempparaloc.reference.index=NR_STACK_POINTER_REG then
+                 size:=align(left.resulttype.def.size,tempcgpara.alignment);
+                 if tempcgpara.location^.reference.index=NR_STACK_POINTER_REG then
                    begin
                    begin
                      href:=left.location.reference;
                      href:=left.location.reference;
                      inc(href.offset,size);
                      inc(href.offset,size);
                      while (size>0) do
                      while (size>0) do
                       begin
                       begin
-                        if (size>=4) or (tempparaloc.alignment>=4) then
+                        if (size>=4) or (tempcgpara.alignment>=4) then
                          begin
                          begin
                            cgsize:=OS_32;
                            cgsize:=OS_32;
                            dec(href.offset,4);
                            dec(href.offset,4);
@@ -200,12 +197,12 @@ implementation
                            dec(href.offset,2);
                            dec(href.offset,2);
                            dec(size,2);
                            dec(size,2);
                          end;
                          end;
-                        cg.a_param_ref(exprasmlist,cgsize,href,tempparaloc);
+                        cg.a_param_ref(exprasmlist,cgsize,href,tempcgpara);
                       end;
                       end;
                    end
                    end
                  else
                  else
                    begin
                    begin
-                     reference_reset_base(href,tempparaloc.reference.index,tempparaloc.reference.offset);
+                     reference_reset_base(href,tempcgpara.location^.reference.index,tempcgpara.location^.reference.offset);
                      cg.g_concatcopy(exprasmlist,left.location.reference,href,size,false,false);
                      cg.g_concatcopy(exprasmlist,left.location.reference,href,size,false,false);
                    end;
                    end;
                end;
                end;
@@ -216,29 +213,29 @@ implementation
            case left.location.loc of
            case left.location.loc of
              LOC_MMREGISTER,
              LOC_MMREGISTER,
              LOC_CMMREGISTER:
              LOC_CMMREGISTER:
-               case tempparaloc.loc of
+               case tempcgpara.location^.loc of
                  LOC_REFERENCE,
                  LOC_REFERENCE,
                  LOC_CREFERENCE,
                  LOC_CREFERENCE,
                  LOC_MMREGISTER,
                  LOC_MMREGISTER,
                  LOC_CMMREGISTER:
                  LOC_CMMREGISTER:
-                   cg.a_parammm_reg(exprasmlist,left.location.size,left.location.register,tempparaloc,mms_movescalar);
+                   cg.a_parammm_reg(exprasmlist,left.location.size,left.location.register,tempcgpara,mms_movescalar);
                  LOC_FPUREGISTER,
                  LOC_FPUREGISTER,
                  LOC_CFPUREGISTER:
                  LOC_CFPUREGISTER:
                    begin
                    begin
                      location_force_fpureg(exprasmlist,left.location,false);
                      location_force_fpureg(exprasmlist,left.location,false);
-                     cg.a_paramfpu_reg(exprasmlist,left.location.size,left.location.register,tempparaloc);
+                     cg.a_paramfpu_reg(exprasmlist,left.location.size,left.location.register,tempcgpara);
                    end;
                    end;
                  else
                  else
                    internalerror(2002042433);
                    internalerror(2002042433);
                end;
                end;
              LOC_FPUREGISTER,
              LOC_FPUREGISTER,
              LOC_CFPUREGISTER:
              LOC_CFPUREGISTER:
-               case tempparaloc.loc of
+               case tempcgpara.location^.loc of
                  LOC_MMREGISTER,
                  LOC_MMREGISTER,
                  LOC_CMMREGISTER:
                  LOC_CMMREGISTER:
                    begin
                    begin
                      location_force_mmregscalar(exprasmlist,left.location,false);
                      location_force_mmregscalar(exprasmlist,left.location,false);
-                     cg.a_parammm_reg(exprasmlist,left.location.size,left.location.register,tempparaloc,mms_movescalar);
+                     cg.a_parammm_reg(exprasmlist,left.location.size,left.location.register,tempcgpara,mms_movescalar);
                    end;
                    end;
 {$ifdef x86_64}
 {$ifdef x86_64}
                  { x86_64 pushes s64comp in normal register }
                  { x86_64 pushes s64comp in normal register }
@@ -248,7 +245,7 @@ implementation
                      location_force_mem(exprasmlist,left.location);
                      location_force_mem(exprasmlist,left.location);
                      { force integer size }
                      { force integer size }
                      left.location.size:=int_cgsize(tcgsize2size[left.location.size]);
                      left.location.size:=int_cgsize(tcgsize2size[left.location.size]);
-                     cg.a_param_ref(exprasmlist,left.location.size,left.location.reference,tempparaloc);
+                     cg.a_param_ref(exprasmlist,left.location.size,left.location.reference,tempcgpara);
                    end;
                    end;
 {$endif x86_64}
 {$endif x86_64}
 {$ifdef sparc}
 {$ifdef sparc}
@@ -260,16 +257,26 @@ implementation
                  LOC_CREFERENCE,
                  LOC_CREFERENCE,
                  LOC_FPUREGISTER,
                  LOC_FPUREGISTER,
                  LOC_CFPUREGISTER:
                  LOC_CFPUREGISTER:
-                   cg.a_paramfpu_reg(exprasmlist,left.location.size,left.location.register,tempparaloc);
+                   cg.a_paramfpu_reg(exprasmlist,left.location.size,left.location.register,tempcgpara);
                  else
                  else
                    internalerror(2002042433);
                    internalerror(2002042433);
                end;
                end;
              LOC_REFERENCE,
              LOC_REFERENCE,
              LOC_CREFERENCE:
              LOC_CREFERENCE:
-               case tempparaloc.loc of
+               case tempcgpara.location^.loc of
                  LOC_MMREGISTER,
                  LOC_MMREGISTER,
                  LOC_CMMREGISTER:
                  LOC_CMMREGISTER:
-                   cg.a_parammm_ref(exprasmlist,left.location.size,left.location.reference,tempparaloc,mms_movescalar);
+                   cg.a_parammm_ref(exprasmlist,left.location.size,left.location.reference,tempcgpara,mms_movescalar);
+{$ifdef x86_64}
+                 { x86_64 pushes s64comp in normal register }
+                 LOC_REGISTER,
+                 LOC_CREGISTER :
+                   begin
+                     { force integer size }
+                     left.location.size:=int_cgsize(tcgsize2size[left.location.size]);
+                     cg.a_param_ref(exprasmlist,left.location.size,left.location.reference,tempcgpara);
+                   end;
+{$endif x86_64}
 {$ifdef sparc}
 {$ifdef sparc}
                  { sparc pushes floats in normal registers }
                  { sparc pushes floats in normal registers }
                  LOC_REGISTER,
                  LOC_REGISTER,
@@ -279,7 +286,7 @@ implementation
                  LOC_CREFERENCE,
                  LOC_CREFERENCE,
                  LOC_FPUREGISTER,
                  LOC_FPUREGISTER,
                  LOC_CFPUREGISTER:
                  LOC_CFPUREGISTER:
-                   cg.a_paramfpu_ref(exprasmlist,left.location.size,left.location.reference,tempparaloc);
+                   cg.a_paramfpu_ref(exprasmlist,left.location.size,left.location.reference,tempcgpara);
                  else
                  else
                    internalerror(2002042431);
                    internalerror(2002042431);
                end;
                end;
@@ -298,22 +305,22 @@ implementation
             begin
             begin
               location_release(exprasmlist,left.location);
               location_release(exprasmlist,left.location);
 {$ifdef i386}
 {$ifdef i386}
-              if tempparaloc.loc<>LOC_REFERENCE then
+              if tempcgpara.location^.loc<>LOC_REFERENCE then
                 internalerror(200309292);
                 internalerror(200309292);
               if not (left.location.loc in [LOC_REFERENCE,LOC_CREFERENCE]) then
               if not (left.location.loc in [LOC_REFERENCE,LOC_CREFERENCE]) then
                 internalerror(200204241);
                 internalerror(200204241);
               { push on stack }
               { push on stack }
-              size:=align(left.resulttype.def.size,tempparaloc.alignment);
-              if tempparaloc.reference.index=NR_STACK_POINTER_REG then
+              size:=align(left.resulttype.def.size,tempcgpara.alignment);
+              if tempcgpara.location^.reference.index=NR_STACK_POINTER_REG then
                 begin
                 begin
                   cg.g_stackpointer_alloc(exprasmlist,size);
                   cg.g_stackpointer_alloc(exprasmlist,size);
                   reference_reset_base(href,NR_STACK_POINTER_REG,0);
                   reference_reset_base(href,NR_STACK_POINTER_REG,0);
                 end
                 end
               else
               else
-                reference_reset_base(href,tempparaloc.reference.index,tempparaloc.reference.offset);
+                reference_reset_base(href,tempcgpara.location^.reference.index,tempcgpara.location^.reference.offset);
               cg.g_concatcopy(exprasmlist,left.location.reference,href,size,false,false);
               cg.g_concatcopy(exprasmlist,left.location.reference,href,size,false,false);
 {$else i386}
 {$else i386}
-              cg.a_param_copy_ref(exprasmlist,left.resulttype.def.size,left.location.reference,tempparaloc);
+              cg.a_param_copy_ref(exprasmlist,left.resulttype.def.size,left.location.reference,tempcgpara);
 {$endif i386}
 {$endif i386}
             end
             end
            else
            else
@@ -328,14 +335,14 @@ implementation
 {$ifndef cpu64bit}
 {$ifndef cpu64bit}
                     if left.location.size in [OS_64,OS_S64] then
                     if left.location.size in [OS_64,OS_S64] then
                      begin
                      begin
-                       cg64.a_param64_loc(exprasmlist,left.location,tempparaloc);
+                       cg64.a_param64_loc(exprasmlist,left.location,tempcgpara);
                        location_release(exprasmlist,left.location);
                        location_release(exprasmlist,left.location);
                      end
                      end
                     else
                     else
 {$endif cpu64bit}
 {$endif cpu64bit}
                      begin
                      begin
                        location_release(exprasmlist,left.location);
                        location_release(exprasmlist,left.location);
-                       cg.a_param_loc(exprasmlist,left.location,tempparaloc);
+                       cg.a_param_loc(exprasmlist,left.location,tempcgpara);
                      end;
                      end;
                   end;
                   end;
 {$ifdef SUPPORT_MMX}
 {$ifdef SUPPORT_MMX}
@@ -376,7 +383,10 @@ implementation
              objectlibrary.getlabel(falselabel);
              objectlibrary.getlabel(falselabel);
              secondpass(left);
              secondpass(left);
 
 
-             allocate_tempparaloc;
+             if not(assigned(aktcallnode.inlinecode)) then
+               paramanager.createtempparaloc(exprasmlist,aktcallnode.procdefinition.proccalloption,paraitem,tempcgpara)
+             else
+               paramanager.duplicateparaloc(exprasmlist,aktcallnode.procdefinition.proccalloption,paraitem,tempcgpara);
 
 
              { handle varargs first, because paraitem.parasym is not valid }
              { handle varargs first, because paraitem.parasym is not valid }
              if (cpf_varargs_para in callparaflags) then
              if (cpf_varargs_para in callparaflags) then
@@ -416,7 +426,7 @@ implementation
                      (not(nf_procvarload in hp.flags)) then
                      (not(nf_procvarload in hp.flags)) then
                     begin
                     begin
                       location_release(exprasmlist,left.location);
                       location_release(exprasmlist,left.location);
-                      cg.a_param_loc(exprasmlist,left.location,tempparaloc);
+                      cg.a_param_loc(exprasmlist,left.location,tempcgpara);
                     end
                     end
                   else
                   else
                     push_addr_para;
                     push_addr_para;
@@ -488,13 +498,14 @@ implementation
 
 
     procedure tcgcallnode.handle_return_value;
     procedure tcgcallnode.handle_return_value;
       var
       var
-        cgsize : tcgsize;
+        cgsize    : tcgsize;
+        retloc    : tlocation;
         hregister : tregister;
         hregister : tregister;
-        tempnode: tnode;
-        resultloc : tparalocation;
+        tempnode  : tnode;
+        resultparaloc : pcgparalocation;
       begin
       begin
-        resultloc:=procdefinition.funcret_paraloc[callerside];
-        cgsize:=resultloc.size;
+        resultparaloc:=procdefinition.funcret_paraloc[callerside].location;
+        cgsize:=procdefinition.funcret_paraloc[callerside].size;
 
 
         { structured results are easy to handle....
         { structured results are easy to handle....
           needed also when result_no_used !! }
           needed also when result_no_used !! }
@@ -520,9 +531,9 @@ implementation
                 end
                 end
               else
               else
                 begin
                 begin
-                  cg.ungetregister(exprasmlist,resultloc.register);
+                  cg.ungetregister(exprasmlist,resultparaloc^.register);
                   hregister := cg.getaddressregister(exprasmlist);
                   hregister := cg.getaddressregister(exprasmlist);
-                  cg.a_load_reg_reg(exprasmlist,OS_ADDR,OS_ADDR,resultloc.register,hregister);
+                  cg.a_load_reg_reg(exprasmlist,OS_ADDR,OS_ADDR,resultparaloc^.register,hregister);
                   { in case of a regular funcretnode with ret_in_param, the }
                   { in case of a regular funcretnode with ret_in_param, the }
                   { original funcretnode isn't touched -> make sure it's    }
                   { original funcretnode isn't touched -> make sure it's    }
                   { the same here (not sure if it's necessary)              }
                   { the same here (not sure if it's necessary)              }
@@ -549,12 +560,12 @@ implementation
             { we have only to handle the result if it is used }
             { we have only to handle the result if it is used }
             if (cnf_return_value_used in callnodeflags) then
             if (cnf_return_value_used in callnodeflags) then
               begin
               begin
-                location.loc:=resultloc.loc;
-                case resultloc.loc of
+                location.loc:=resultparaloc^.loc;
+                case resultparaloc^.loc of
                    LOC_FPUREGISTER:
                    LOC_FPUREGISTER:
                      begin
                      begin
                        location_reset(location,LOC_FPUREGISTER,cgsize);
                        location_reset(location,LOC_FPUREGISTER,cgsize);
-                       location.register:=procdefinition.funcret_paraloc[callerside].register;
+                       location.register:=resultparaloc^.register;
 {$ifdef x86}
 {$ifdef x86}
                        tcgx86(cg).inc_fpu_stack;
                        tcgx86(cg).inc_fpu_stack;
 {$else x86}
 {$else x86}
@@ -573,31 +584,29 @@ implementation
 {$ifndef cpu64bit}
 {$ifndef cpu64bit}
                           if cgsize in [OS_64,OS_S64] then
                           if cgsize in [OS_64,OS_S64] then
                            begin
                            begin
-                             { Move the function result to free registers, preferably the
-                               FUNCTION_RESULT_REG/FUNCTION_RESULTHIGH_REG, so no move is necessary.}
-                             { the FUNCTION_RESULT_LOW_REG/FUNCTION_RESULT_HIGH_REG
-                               are already allocated }
-                             cg.ungetregister(exprasmlist,NR_FUNCTION_RESULT64_LOW_REG);
+                             procdefinition.funcret_paraloc[callerside].get_location(retloc);
+                             if retloc.loc<>LOC_REGISTER then
+                               internalerror(200409141);
+                             { the function result registers are already allocated }
+                             cg.ungetregister(exprasmlist,retloc.registerlow);
                              location.registerlow:=cg.getintregister(exprasmlist,OS_32);
                              location.registerlow:=cg.getintregister(exprasmlist,OS_32);
-                             cg.a_load_reg_reg(exprasmlist,OS_32,OS_32,NR_FUNCTION_RESULT64_LOW_REG,location.registerlow);
-                             cg.ungetregister(exprasmlist,NR_FUNCTION_RESULT64_HIGH_REG);
+                             cg.a_load_reg_reg(exprasmlist,OS_32,OS_32,retloc.registerlow,location.registerlow);
+                             cg.ungetregister(exprasmlist,retloc.registerhigh);
                              location.registerhigh:=cg.getintregister(exprasmlist,OS_32);
                              location.registerhigh:=cg.getintregister(exprasmlist,OS_32);
-                             cg.a_load_reg_reg(exprasmlist,OS_32,OS_32,NR_FUNCTION_RESULT64_HIGH_REG,location.registerhigh);
+                             cg.a_load_reg_reg(exprasmlist,OS_32,OS_32,retloc.registerhigh,location.registerhigh);
                            end
                            end
                           else
                           else
 {$endif cpu64bit}
 {$endif cpu64bit}
                            begin
                            begin
-                             { Move the function result to a free register, preferably the
-                               FUNCTION_RESULT_REG, so no move is necessary.}
-                             { the FUNCTION_RESULT_REG is already allocated }
-                             cg.ungetregister(exprasmlist,resultloc.register);
+                             { the function result register are already allocated }
+                             cg.ungetregister(exprasmlist,resultparaloc^.register);
                              { change register size after the unget because the
                              { change register size after the unget because the
                                getregister was done for the full register
                                getregister was done for the full register
 
 
                                def_cgsize(resulttype.def) is used here because
                                def_cgsize(resulttype.def) is used here because
                                it could be a constructor call }
                                it could be a constructor call }
                              location.register:=cg.getintregister(exprasmlist,def_cgsize(resulttype.def));
                              location.register:=cg.getintregister(exprasmlist,def_cgsize(resulttype.def));
-                             cg.a_load_reg_reg(exprasmlist,cgsize,def_cgsize(resulttype.def),resultloc.register,location.register);
+                             cg.a_load_reg_reg(exprasmlist,cgsize,def_cgsize(resulttype.def),resultparaloc^.register,location.register);
                            end;
                            end;
                         end
                         end
                        else
                        else
@@ -610,9 +619,9 @@ implementation
                    LOC_MMREGISTER:
                    LOC_MMREGISTER:
                      begin
                      begin
                        location_reset(location,LOC_MMREGISTER,cgsize);
                        location_reset(location,LOC_MMREGISTER,cgsize);
-                       cg.ungetregister(exprasmlist,resultloc.register);
+                       cg.ungetregister(exprasmlist,resultparaloc^.register);
                        location.register:=cg.getmmregister(exprasmlist,cgsize);
                        location.register:=cg.getmmregister(exprasmlist,cgsize);
-                       cg.a_loadmm_reg_reg(exprasmlist,cgsize,cgsize,resultloc.register,location.register,mms_movescalar);
+                       cg.a_loadmm_reg_reg(exprasmlist,cgsize,cgsize,resultparaloc^.register,location.register,mms_movescalar);
                      end;
                      end;
 
 
                    else
                    else
@@ -623,11 +632,11 @@ implementation
               begin
               begin
 {$ifdef x86}
 {$ifdef x86}
                 { release FPU stack }
                 { release FPU stack }
-                if resultloc.loc=LOC_FPUREGISTER then
+                if resultparaloc^.loc=LOC_FPUREGISTER then
                   emit_reg(A_FSTP,S_NO,NR_FPU_RESULT_REG);
                   emit_reg(A_FSTP,S_NO,NR_FPU_RESULT_REG);
 {$endif x86}
 {$endif x86}
                 if cgsize<>OS_NO then
                 if cgsize<>OS_NO then
-                  paramanager.freeparaloc(exprasmlist,resultloc);
+                  paramanager.freeparaloc(exprasmlist,procdefinition.funcret_paraloc[callerside]);
                 location_reset(location,LOC_VOID,OS_NO);
                 location_reset(location,LOC_VOID,OS_NO);
               end;
               end;
            end;
            end;
@@ -671,7 +680,10 @@ implementation
      procedure tcgcallnode.pushparas;
      procedure tcgcallnode.pushparas;
        var
        var
          ppn : tcgcallparanode;
          ppn : tcgcallparanode;
+         callerparaloc,
+         tmpparaloc : pcgparalocation;
 {$ifdef cputargethasfixedstack}
 {$ifdef cputargethasfixedstack}
+         htempref,
          href : treference;
          href : treference;
 {$endif cputargethasfixedstack}
 {$endif cputargethasfixedstack}
        begin
        begin
@@ -682,97 +694,83 @@ implementation
              if (ppn.left.nodetype<>nothingn) then
              if (ppn.left.nodetype<>nothingn) then
                begin
                begin
                  { better check for the real location of the parameter here, when stack passed parameters
                  { better check for the real location of the parameter here, when stack passed parameters
-                   are saved temporary in registers, checking for the tempparaloc.loc is wrong
+                   are saved temporary in registers, checking for the tmpparaloc.loc is wrong
                  }
                  }
-                 case ppn.paraitem.paraloc[callerside].loc of
-                   LOC_REGISTER:
-                     begin
-                       if not assigned(inlinecode) then
+                 if not assigned(inlinecode) then
+                   paramanager.freeparaloc(exprasmlist,ppn.tempcgpara);
+                 tmpparaloc:=ppn.tempcgpara.location;
+                 callerparaloc:=ppn.paraitem.paraloc[callerside].location;
+                 while assigned(callerparaloc) do
+                   begin
+                     { Every paraloc must have a matching tmpparaloc }
+                     if not assigned(tmpparaloc) then
+                       internalerror(200408224);
+                     if callerparaloc^.size<>tmpparaloc^.size then
+                       internalerror(200408225);
+                     case callerparaloc^.loc of
+                       LOC_REGISTER:
                          begin
                          begin
-                           paramanager.freeparaloc(exprasmlist,ppn.tempparaloc);
-                           paramanager.allocparaloc(exprasmlist,ppn.paraitem.paraloc[callerside]);
+                           if tmpparaloc^.loc<>LOC_REGISTER then
+                             internalerror(200408221);
+                           if getsupreg(callerparaloc^.register)<first_int_imreg then
+                             cg.getexplicitregister(exprasmlist,callerparaloc^.register);
+                           cg.a_load_reg_reg(exprasmlist,tmpparaloc^.size,tmpparaloc^.size,
+                               tmpparaloc^.register,callerparaloc^.register);
                          end;
                          end;
-  {$ifdef sparc}
-                       case ppn.tempparaloc.size of
-                         OS_F32 :
-                           ppn.tempparaloc.size:=OS_32;
-                         OS_F64 :
-                           ppn.tempparaloc.size:=OS_64;
-                       end;
-  {$endif sparc}
-  {$ifndef cpu64bit}
-                       if ppn.tempparaloc.size in [OS_64,OS_S64] then
-                         begin
-                           cg.a_load_reg_reg(exprasmlist,OS_32,OS_32,ppn.tempparaloc.registerlow,
-                              ppn.paraitem.paraloc[callerside].registerlow);
-                           cg.a_load_reg_reg(exprasmlist,OS_32,OS_32,ppn.tempparaloc.registerhigh,
-                              ppn.paraitem.paraloc[callerside].registerhigh);
-                         end
-                       else
-  {$endif cpu64bit}
-                         cg.a_load_reg_reg(exprasmlist,ppn.tempparaloc.size,ppn.tempparaloc.size,
-                             ppn.tempparaloc.register,ppn.paraitem.paraloc[callerside].register);
-                     end;
-                   LOC_FPUREGISTER:
-                     begin
-                       if not assigned(inlinecode) then
+                       LOC_FPUREGISTER:
                          begin
                          begin
-                           paramanager.freeparaloc(exprasmlist,ppn.tempparaloc);
-                           paramanager.allocparaloc(exprasmlist,ppn.paraitem.paraloc[callerside]);
-                           cg.a_loadfpu_reg_reg(exprasmlist,ppn.tempparaloc.size,
-                             ppn.tempparaloc.register,ppn.paraitem.paraloc[callerside].register);
+                           if tmpparaloc^.loc<>LOC_FPUREGISTER then
+                             internalerror(200408222);
+                           if getsupreg(callerparaloc^.register)<first_fpu_imreg then
+                             cg.getexplicitregister(exprasmlist,callerparaloc^.register);
+                           cg.a_loadfpu_reg_reg(exprasmlist,ppn.tempcgpara.size,tmpparaloc^.register,callerparaloc^.register);
                          end;
                          end;
-                     end;
-                   LOC_MMREGISTER:
-                     begin
-                       if not assigned(inlinecode) then
+                       LOC_MMREGISTER:
                          begin
                          begin
-                           paramanager.freeparaloc(exprasmlist,ppn.tempparaloc);
-                           paramanager.allocparaloc(exprasmlist,ppn.paraitem.paraloc[callerside]);
+                           if tmpparaloc^.loc<>LOC_MMREGISTER then
+                             internalerror(200408223);
+                           if getsupreg(callerparaloc^.register)<first_mm_imreg then
+                             cg.getexplicitregister(exprasmlist,callerparaloc^.register);
+                           cg.a_loadmm_reg_reg(exprasmlist,tmpparaloc^.size,tmpparaloc^.size,
+                             tmpparaloc^.register,callerparaloc^.register,mms_movescalar);
                          end;
                          end;
-                       cg.a_loadmm_reg_reg(exprasmlist,ppn.tempparaloc.size,
-                         ppn.tempparaloc.size,ppn.tempparaloc.register,ppn.paraitem.paraloc[callerside].register,mms_movescalar);
-                     end;
-                   LOC_REFERENCE:
-                     begin
-                       if not assigned(inlinecode) then
+                       LOC_REFERENCE:
                          begin
                          begin
+                           if not assigned(inlinecode) then
+                             begin
 {$ifdef cputargethasfixedstack}
 {$ifdef cputargethasfixedstack}
-                           { copy parameters in case they were moved to a temp. location because we've a fixed stack }
-                           paramanager.freeparaloc(exprasmlist,ppn.tempparaloc);
-                           paramanager.allocparaloc(exprasmlist,ppn.paraitem.paraloc[callerside]);
-                           case ppn.tempparaloc.loc of
-                             LOC_REFERENCE:
-                               begin
-                                 reference_reset_base(href,ppn.tempparaloc.reference.index,ppn.tempparaloc.reference.offset);
-                                 if ppn.paraitem.paraloc[callerside].size=OS_NO then
-                                   cg.a_param_copy_ref(exprasmlist,ppn.paraitem.paratype.def.size,href,ppn.paraitem.paraloc[callerside])
+                               reference_reset_base(href,callerparaloc^.reference.index,callerparaloc^.reference.offset);
+                               { copy parameters in case they were moved to a temp. location because we've a fixed stack }
+                               case tmpparaloc^.loc of
+                                 LOC_REFERENCE:
+                                   begin
+                                     reference_reset_base(htempref,tmpparaloc^.reference.index,tmpparaloc^.reference.offset);
+                                     { use concatcopy, because it can also be a float which fails when
+                                       load_ref_ref is used }
+                                     cg.g_concatcopy(exprasmlist,htempref,href,tcgsize2size[tmpparaloc^.size],false,false);
+                                   end;
+                                 LOC_REGISTER:
+                                   cg.a_load_reg_ref(exprasmlist,tmpparaloc^.size,tmpparaloc^.size,tmpparaloc^.register,href);
+                                 LOC_FPUREGISTER:
+                                   cg.a_loadfpu_reg_ref(exprasmlist,tmpparaloc^.size,tmpparaloc^.register,href);
+                                 LOC_MMREGISTER:
+                                   cg.a_loadmm_reg_ref(exprasmlist,tmpparaloc^.size,tmpparaloc^.size,tmpparaloc^.register,href,mms_movescalar);
                                  else
                                  else
-                                   cg.a_param_ref(exprasmlist,ppn.paraitem.paraloc[callerside].size,href,ppn.paraitem.paraloc[callerside]);
+                                   internalerror(200402081);
                                end;
                                end;
-                             LOC_REGISTER:
-      {$ifndef cpu64bit}
-                               if ppn.tempparaloc.size in [OS_64,OS_S64] then
-                                 cg64.a_param64_reg(exprasmlist,ppn.tempparaloc.register64,ppn.paraitem.paraloc[callerside])
-                               else
-      {$endif cpu64bit}
-                                 cg.a_param_reg(exprasmlist,ppn.paraitem.paraloc[callerside].size,ppn.tempparaloc.register,ppn.paraitem.paraloc[callerside]);
-                             LOC_FPUREGISTER:
-                               cg.a_paramfpu_reg(exprasmlist,ppn.paraitem.paraloc[callerside].size,ppn.tempparaloc.register,ppn.paraitem.paraloc[callerside]);
-                             else
-                               internalerror(200402081);
-                           end;
-  {$endif cputargethasfixedstack}
+{$endif cputargethasfixedstack}
+                             end;
                          end;
                          end;
                      end;
                      end;
-                   else
-                     internalerror(200402091);
-                 end;
+                     callerparaloc:=callerparaloc^.next;
+                     tmpparaloc:=tmpparaloc^.next;
+                   end;
                end;
                end;
              ppn:=tcgcallparanode(ppn.right);
              ppn:=tcgcallparanode(ppn.right);
            end;
            end;
        end;
        end;
 
 
+
      procedure tcgcallnode.freeparas;
      procedure tcgcallnode.freeparas;
        var
        var
          ppn : tcgcallparanode;
          ppn : tcgcallparanode;
@@ -782,7 +780,7 @@ implementation
          while assigned(ppn) do
          while assigned(ppn) do
            begin
            begin
              if not assigned(inlinecode) or
              if not assigned(inlinecode) or
-                (ppn.paraitem.paraloc[callerside].loc <> LOC_REFERENCE) then
+                (ppn.paraitem.paraloc[callerside].location^.loc <> LOC_REFERENCE) then
                paramanager.freeparaloc(exprasmlist,ppn.paraitem.paraloc[callerside]);
                paramanager.freeparaloc(exprasmlist,ppn.paraitem.paraloc[callerside]);
              ppn:=tcgcallparanode(ppn.right);
              ppn:=tcgcallparanode(ppn.right);
            end;
            end;
@@ -792,15 +790,15 @@ implementation
 
 
     procedure tcgcallnode.normal_pass_2;
     procedure tcgcallnode.normal_pass_2;
       var
       var
-         regs_to_push_fpu,
-         regs_to_alloc,
-         regs_to_free : Tcpuregisterset;
+         regs_to_save_int,
+         regs_to_save_fpu,
+         regs_to_save_mm   : Tcpuregisterset;
          href : treference;
          href : treference;
          pop_size : longint;
          pop_size : longint;
          pvreg,
          pvreg,
          vmtreg : tregister;
          vmtreg : tregister;
          oldaktcallnode : tcallnode;
          oldaktcallnode : tcallnode;
-
+         funcretloc : pcgparalocation;
       begin
       begin
          if not assigned(procdefinition) or
          if not assigned(procdefinition) or
             not procdefinition.has_paraloc_info then
             not procdefinition.has_paraloc_info then
@@ -814,34 +812,29 @@ implementation
              cg.g_decrrefcount(exprasmlist,resulttype.def,refcountedtemp,false);
              cg.g_decrrefcount(exprasmlist,resulttype.def,refcountedtemp,false);
            end;
            end;
 
 
-        regs_to_alloc:=paramanager.get_volatile_registers_int(procdefinition.proccalloption);
-        regs_to_push_fpu:=paramanager.get_volatile_registers_fpu(procdefinition.proccalloption);
+        regs_to_save_int:=paramanager.get_volatile_registers_int(procdefinition.proccalloption);
+        regs_to_save_fpu:=paramanager.get_volatile_registers_fpu(procdefinition.proccalloption);
+        regs_to_save_mm:=paramanager.get_volatile_registers_mm(procdefinition.proccalloption);
 
 
         { Include Function result registers }
         { Include Function result registers }
         if (not is_void(resulttype.def)) then
         if (not is_void(resulttype.def)) then
           begin
           begin
-            case procdefinition.funcret_paraloc[callerside].loc of
-              LOC_REGISTER,LOC_CREGISTER:
-                begin
-{$ifndef cpu64bit}
-                  if procdefinition.funcret_paraloc[callerside].size in [OS_S64,OS_64] then
-                    begin
-                      include(regs_to_alloc,getsupreg(procdefinition.funcret_paraloc[callerside].registerlow));
-                      include(regs_to_alloc,getsupreg(procdefinition.funcret_paraloc[callerside].registerhigh));
-                    end
-                 else
-{$endif cpu64bit}
-                   include(regs_to_alloc,getsupreg(procdefinition.funcret_paraloc[callerside].register));
-                end;
-              LOC_FPUREGISTER,LOC_CFPUREGISTER:
-                begin
-                  include(regs_to_push_fpu,getsupreg(procdefinition.funcret_paraloc[callerside].register));
-                end;
-              LOC_MMREGISTER,LOC_CMMREGISTER:
-                begin
-                  include(regs_to_alloc,getsupreg(procdefinition.funcret_paraloc[callerside].register));
+            funcretloc:=procdefinition.funcret_paraloc[callerside].location;
+            while assigned(funcretloc) do
+              begin
+                case funcretloc^.loc of
+                  LOC_REGISTER,
+                  LOC_CREGISTER:
+                    include(regs_to_save_int,getsupreg(funcretloc^.register));
+                  LOC_FPUREGISTER,
+                  LOC_CFPUREGISTER:
+                    include(regs_to_save_fpu,getsupreg(funcretloc^.register));
+                  LOC_MMREGISTER,
+                  LOC_CMMREGISTER:
+                    include(regs_to_save_mm,getsupreg(funcretloc^.register));
                 end;
                 end;
-            end;
+                funcretloc:=funcretloc^.next;
+              end;
           end;
           end;
 
 
          { Process parameters, register parameters will be loaded
          { Process parameters, register parameters will be loaded
@@ -900,11 +893,11 @@ implementation
                    { Release register containing procvar }
                    { Release register containing procvar }
                    cg.ungetregister(exprasmlist,pvreg);
                    cg.ungetregister(exprasmlist,pvreg);
 
 
-                   cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,regs_to_alloc);
+                   cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,regs_to_save_int);
                    if cg.uses_registers(R_FPUREGISTER) then
                    if cg.uses_registers(R_FPUREGISTER) then
-                     cg.allocexplicitregisters(exprasmlist,R_FPUREGISTER,regs_to_push_fpu);
+                     cg.allocexplicitregisters(exprasmlist,R_FPUREGISTER,regs_to_save_fpu);
                    if cg.uses_registers(R_MMREGISTER) then
                    if cg.uses_registers(R_MMREGISTER) then
-                     cg.allocexplicitregisters(exprasmlist,R_MMREGISTER,paramanager.get_volatile_registers_mm(procdefinition.proccalloption));
+                     cg.allocexplicitregisters(exprasmlist,R_MMREGISTER,regs_to_save_mm);
 
 
                    { call method }
                    { call method }
                    extra_call_code;
                    extra_call_code;
@@ -920,11 +913,11 @@ implementation
                   { free the resources allocated for the parameters }
                   { free the resources allocated for the parameters }
                   freeparas;
                   freeparas;
 
 
-                  cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,regs_to_alloc);
+                  cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,regs_to_save_int);
                   if cg.uses_registers(R_FPUREGISTER) then
                   if cg.uses_registers(R_FPUREGISTER) then
-                    cg.allocexplicitregisters(exprasmlist,R_FPUREGISTER,regs_to_push_fpu);
+                    cg.allocexplicitregisters(exprasmlist,R_FPUREGISTER,regs_to_save_fpu);
                   if cg.uses_registers(R_MMREGISTER) then
                   if cg.uses_registers(R_MMREGISTER) then
-                    cg.allocexplicitregisters(exprasmlist,R_MMREGISTER,paramanager.get_volatile_registers_mm(procdefinition.proccalloption));
+                    cg.allocexplicitregisters(exprasmlist,R_MMREGISTER,regs_to_save_mm);
 
 
                   if procdefinition.proccalloption=pocall_syscall then
                   if procdefinition.proccalloption=pocall_syscall then
                     do_syscall
                     do_syscall
@@ -964,11 +957,11 @@ implementation
               { Release register containing procvar }
               { Release register containing procvar }
               cg.ungetregister(exprasmlist,pvreg);
               cg.ungetregister(exprasmlist,pvreg);
 
 
-              cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,regs_to_alloc);
+              cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,regs_to_save_int);
               if cg.uses_registers(R_FPUREGISTER) then
               if cg.uses_registers(R_FPUREGISTER) then
-                cg.allocexplicitregisters(exprasmlist,R_FPUREGISTER,regs_to_push_fpu);
+                cg.allocexplicitregisters(exprasmlist,R_FPUREGISTER,regs_to_save_fpu);
               if cg.uses_registers(R_MMREGISTER) then
               if cg.uses_registers(R_MMREGISTER) then
-                cg.allocexplicitregisters(exprasmlist,R_MMREGISTER,paramanager.get_volatile_registers_mm(procdefinition.proccalloption));
+                cg.allocexplicitregisters(exprasmlist,R_MMREGISTER,regs_to_save_mm);
 
 
               { Calling interrupt from the same code requires some
               { Calling interrupt from the same code requires some
                 extra code }
                 extra code }
@@ -994,33 +987,30 @@ implementation
 
 
          { Release registers, but not the registers that contain the
          { Release registers, but not the registers that contain the
            function result }
            function result }
-         regs_to_free:=regs_to_alloc;
          if (not is_void(resulttype.def)) then
          if (not is_void(resulttype.def)) then
            begin
            begin
-             case procdefinition.funcret_paraloc[callerside].loc of
-               LOC_REGISTER,LOC_CREGISTER:
-                 begin
-{$ifndef cpu64bit}
-                   if procdefinition.funcret_paraloc[callerside].size in [OS_S64,OS_64] then
-                     begin
-                       exclude(regs_to_free,getsupreg(procdefinition.funcret_paraloc[callerside].registerlow));
-                       exclude(regs_to_free,getsupreg(procdefinition.funcret_paraloc[callerside].registerhigh));
-                     end
-                   else
-{$endif cpu64bit}
-                     exclude(regs_to_free,getsupreg(procdefinition.funcret_paraloc[callerside].register));
-                 end;
-               LOC_FPUREGISTER,LOC_CFPUREGISTER:
-                 begin
-                   exclude(regs_to_push_fpu,getsupreg(procdefinition.funcret_paraloc[callerside].register));
-                 end;
-             end;
+            funcretloc:=procdefinition.funcret_paraloc[callerside].location;
+            while assigned(funcretloc) do
+              begin
+                case funcretloc^.loc of
+                  LOC_REGISTER,
+                  LOC_CREGISTER:
+                    exclude(regs_to_save_int,getsupreg(funcretloc^.register));
+                  LOC_FPUREGISTER,
+                  LOC_CFPUREGISTER:
+                    exclude(regs_to_save_fpu,getsupreg(funcretloc^.register));
+                  LOC_MMREGISTER,
+                  LOC_CMMREGISTER:
+                    exclude(regs_to_save_mm,getsupreg(funcretloc^.register));
+                end;
+                funcretloc:=funcretloc^.next;
+              end;
            end;
            end;
          if cg.uses_registers(R_MMREGISTER) then
          if cg.uses_registers(R_MMREGISTER) then
-           cg.deallocexplicitregisters(exprasmlist,R_MMREGISTER,paramanager.get_volatile_registers_mm(procdefinition.proccalloption));
+           cg.deallocexplicitregisters(exprasmlist,R_MMREGISTER,regs_to_save_mm);
          if cg.uses_registers(R_FPUREGISTER) then
          if cg.uses_registers(R_FPUREGISTER) then
-           cg.deallocexplicitregisters(exprasmlist,R_FPUREGISTER,regs_to_push_fpu);
-         cg.deallocexplicitregisters(exprasmlist,R_INTREGISTER,regs_to_free);
+           cg.deallocexplicitregisters(exprasmlist,R_FPUREGISTER,regs_to_save_fpu);
+         cg.deallocexplicitregisters(exprasmlist,R_INTREGISTER,regs_to_save_int);
 
 
          { handle function results }
          { handle function results }
          if (not is_void(resulttype.def)) then
          if (not is_void(resulttype.def)) then
@@ -1079,7 +1069,8 @@ implementation
          paramanager.create_inline_paraloc_info(procdefinition);
          paramanager.create_inline_paraloc_info(procdefinition);
 
 
          { Allocate parameters and locals }
          { Allocate parameters and locals }
-         gen_alloc_inline_parast(exprasmlist,tparasymtable(procdefinition.parast));
+         gen_alloc_inline_parast(exprasmlist,tprocdef(procdefinition));
+         gen_alloc_inline_funcret(exprasmlist,tprocdef(procdefinition));
          if tprocdef(procdefinition).localst.symtabletype=localsymtable then
          if tprocdef(procdefinition).localst.symtabletype=localsymtable then
            gen_alloc_localst(exprasmlist,tlocalsymtable(tprocdef(procdefinition).localst));
            gen_alloc_localst(exprasmlist,tlocalsymtable(tprocdef(procdefinition).localst));
 
 
@@ -1148,7 +1139,7 @@ implementation
          gen_load_para_value(inlineentrycode);
          gen_load_para_value(inlineentrycode);
          { now that we've loaded the para's, free them }
          { now that we've loaded the para's, free them }
          freeparas;
          freeparas;
-         gen_initialize_code(inlineentrycode,true);
+         gen_initialize_code(inlineentrycode);
          if po_assembler in current_procinfo.procdef.procoptions then
          if po_assembler in current_procinfo.procdef.procoptions then
            inlineentrycode.insert(Tai_marker.Create(asmblockstart));
            inlineentrycode.insert(Tai_marker.Create(asmblockstart));
          exprasmList.concatlist(inlineentrycode);
          exprasmList.concatlist(inlineentrycode);
@@ -1157,7 +1148,7 @@ implementation
          secondpass(inlinecode);
          secondpass(inlinecode);
 
 
          cg.a_label(exprasmlist,current_procinfo.aktexitlabel);
          cg.a_label(exprasmlist,current_procinfo.aktexitlabel);
-         gen_finalize_code(inlineexitcode,true);
+         gen_finalize_code(inlineexitcode);
          gen_load_return_value(inlineexitcode);
          gen_load_return_value(inlineexitcode);
          if po_assembler in current_procinfo.procdef.procoptions then
          if po_assembler in current_procinfo.procdef.procoptions then
            inlineexitcode.concat(Tai_marker.Create(asmblockend));
            inlineexitcode.concat(Tai_marker.Create(asmblockend));
@@ -1263,7 +1254,22 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.173  2004-07-12 10:47:42  michael
+  Revision 1.174  2004-09-21 17:25:12  peter
+    * paraloc branch merged
+
+  Revision 1.173.4.3  2004/09/20 20:46:34  peter
+    * register allocation optimized for 64bit loading of parameters
+      and return values
+
+  Revision 1.173.4.2  2004/09/17 17:19:26  peter
+    * fixed 64 bit unaryminus for sparc
+    * fixed 64 bit inlining
+    * signness of not operation
+
+  Revision 1.173.4.1  2004/08/31 20:43:06  peter
+    * paraloc patch
+
+  Revision 1.173  2004/07/12 10:47:42  michael
   + Fix for bug 3207 from Peter
   + Fix for bug 3207 from Peter
 
 
   Revision 1.172  2004/07/11 19:01:13  peter
   Revision 1.172  2004/07/11 19:01:13  peter

+ 43 - 20
compiler/ncgflw.pas

@@ -84,16 +84,13 @@ implementation
     uses
     uses
       verbose,globals,systems,globtype,
       verbose,globals,systems,globtype,
       symconst,symdef,symsym,aasmbase,aasmtai,aasmcpu,defutil,
       symconst,symdef,symsym,aasmbase,aasmtai,aasmcpu,defutil,
-      procinfo,cgbase,pass_2,
+      procinfo,cgbase,pass_2,parabase,
       cpubase,cpuinfo,
       cpubase,cpuinfo,
       nld,ncon,
       nld,ncon,
       ncgutil,
       ncgutil,
       tgobj,paramgr,
       tgobj,paramgr,
       regvars,
       regvars,
       cgutils,cgobj
       cgutils,cgobj
-{$ifndef cpu64bit}
-      ,cg64f32
-{$endif cpu64bit}
       ;
       ;
 
 
 {*****************************************************************************
 {*****************************************************************************
@@ -778,11 +775,14 @@ implementation
       var
       var
          a : tasmlabel;
          a : tasmlabel;
          href2: treference;
          href2: treference;
-         paraloc1,paraloc2,paraloc3 : tparalocation;
+         paraloc1,paraloc2,paraloc3 : tcgpara;
       begin
       begin
-         paraloc1:=paramanager.getintparaloc(pocall_default,1);
-         paraloc2:=paramanager.getintparaloc(pocall_default,2);
-         paraloc3:=paramanager.getintparaloc(pocall_default,3);
+         paraloc1.init;
+         paraloc2.init;
+         paraloc3.init;
+         paramanager.getintparaloc(pocall_default,1,paraloc1);
+         paramanager.getintparaloc(pocall_default,2,paraloc2);
+         paramanager.getintparaloc(pocall_default,3,paraloc3);
          location_reset(location,LOC_VOID,OS_NO);
          location_reset(location,LOC_VOID,OS_NO);
 
 
          if assigned(left) then
          if assigned(left) then
@@ -847,6 +847,9 @@ implementation
               cg.a_call_name(exprasmlist,'FPC_RERAISE');
               cg.a_call_name(exprasmlist,'FPC_RERAISE');
               cg.deallocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
               cg.deallocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
            end;
            end;
+         paraloc1.done;
+         paraloc2.done;
+         paraloc3.done;
        end;
        end;
 
 
 
 
@@ -862,18 +865,20 @@ implementation
     { in the except block                                    }
     { in the except block                                    }
     procedure cleanupobjectstack;
     procedure cleanupobjectstack;
       var
       var
-        paraloc1 : tparalocation;
+        paraloc1 : tcgpara;
       begin
       begin
          cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
          cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
          cg.a_call_name(exprasmlist,'FPC_POPOBJECTSTACK');
          cg.a_call_name(exprasmlist,'FPC_POPOBJECTSTACK');
          cg.deallocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
          cg.deallocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
-         paraloc1:=paramanager.getintparaloc(pocall_default,1);
+         paraloc1.init;
+         paramanager.getintparaloc(pocall_default,1,paraloc1);
          paramanager.allocparaloc(exprasmlist,paraloc1);
          paramanager.allocparaloc(exprasmlist,paraloc1);
          cg.a_param_reg(exprasmlist,OS_ADDR,NR_FUNCTION_RESULT_REG,paraloc1);
          cg.a_param_reg(exprasmlist,OS_ADDR,NR_FUNCTION_RESULT_REG,paraloc1);
          paramanager.freeparaloc(exprasmlist,paraloc1);
          paramanager.freeparaloc(exprasmlist,paraloc1);
          cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
          cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
          cg.a_call_name(exprasmlist,'FPC_DESTROYEXCEPTION');
          cg.a_call_name(exprasmlist,'FPC_DESTROYEXCEPTION');
          cg.deallocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
          cg.deallocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
+         paraloc1.done;
       end;
       end;
 
 
 
 
@@ -897,7 +902,7 @@ implementation
          exceptflowcontrol : tflowcontrol;
          exceptflowcontrol : tflowcontrol;
          destroytemps,
          destroytemps,
          excepttemps : texceptiontemps;
          excepttemps : texceptiontemps;
-         paraloc1 : tparalocation;
+         paraloc1 : tcgpara;
       label
       label
          errorexit;
          errorexit;
       begin
       begin
@@ -906,6 +911,8 @@ implementation
          oldflowcontrol:=flowcontrol;
          oldflowcontrol:=flowcontrol;
          flowcontrol:=[];
          flowcontrol:=[];
          { this can be called recursivly }
          { this can be called recursivly }
+         oldaktbreaklabel:=nil;
+         oldaktcontinuelabel:=nil;
          oldendexceptlabel:=endexceptlabel;
          oldendexceptlabel:=endexceptlabel;
 
 
          { save the old labels for control flow statements }
          { save the old labels for control flow statements }
@@ -977,13 +984,15 @@ implementation
               { FPC_CATCHES must be called with
               { FPC_CATCHES must be called with
                 'default handler' flag (=-1)
                 'default handler' flag (=-1)
               }
               }
-              paraloc1:=paramanager.getintparaloc(pocall_default,1);
+              paraloc1.init;
+              paramanager.getintparaloc(pocall_default,1,paraloc1);
               paramanager.allocparaloc(exprasmlist,paraloc1);
               paramanager.allocparaloc(exprasmlist,paraloc1);
               cg.a_param_const(exprasmlist,OS_ADDR,-1,paraloc1);
               cg.a_param_const(exprasmlist,OS_ADDR,-1,paraloc1);
               paramanager.freeparaloc(exprasmlist,paraloc1);
               paramanager.freeparaloc(exprasmlist,paraloc1);
               cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
               cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
               cg.a_call_name(exprasmlist,'FPC_CATCHES');
               cg.a_call_name(exprasmlist,'FPC_CATCHES');
               cg.deallocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
               cg.deallocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
+              paraloc1.done;
 
 
               { the destruction of the exception object must be also }
               { the destruction of the exception object must be also }
               { guarded by an exception frame                        }
               { guarded by an exception frame                        }
@@ -1006,13 +1015,15 @@ implementation
               cg.a_call_name(exprasmlist,'FPC_POPSECONDOBJECTSTACK');
               cg.a_call_name(exprasmlist,'FPC_POPSECONDOBJECTSTACK');
               cg.deallocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
               cg.deallocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
 
 
-              paraloc1:=paramanager.getintparaloc(pocall_default,1);
+              paraloc1.init;
+              paramanager.getintparaloc(pocall_default,1,paraloc1);
               paramanager.allocparaloc(exprasmlist,paraloc1);
               paramanager.allocparaloc(exprasmlist,paraloc1);
               cg.a_param_reg(exprasmlist, OS_ADDR, NR_FUNCTION_RESULT_REG, paraloc1);
               cg.a_param_reg(exprasmlist, OS_ADDR, NR_FUNCTION_RESULT_REG, paraloc1);
               paramanager.freeparaloc(exprasmlist,paraloc1);
               paramanager.freeparaloc(exprasmlist,paraloc1);
               cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
               cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
               cg.a_call_name(exprasmlist,'FPC_DESTROYEXCEPTION');
               cg.a_call_name(exprasmlist,'FPC_DESTROYEXCEPTION');
               cg.deallocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
               cg.deallocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
+              paraloc1.done;
               { we don't need to restore esi here because reraise never }
               { we don't need to restore esi here because reraise never }
               { returns                                                 }
               { returns                                                 }
               cg.a_call_name(exprasmlist,'FPC_RERAISE');
               cg.a_call_name(exprasmlist,'FPC_RERAISE');
@@ -1134,8 +1145,9 @@ implementation
          excepttemps : texceptiontemps;
          excepttemps : texceptiontemps;
          exceptref,
          exceptref,
          href2: treference;
          href2: treference;
-         paraloc1 : tparalocation;
+         paraloc1 : tcgpara;
       begin
       begin
+         paraloc1.init;
          location_reset(location,LOC_VOID,OS_NO);
          location_reset(location,LOC_VOID,OS_NO);
 
 
          oldflowcontrol:=flowcontrol;
          oldflowcontrol:=flowcontrol;
@@ -1144,7 +1156,7 @@ implementation
 
 
          { send the vmt parameter }
          { send the vmt parameter }
          reference_reset_symbol(href2,objectlibrary.newasmsymbol(excepttype.vmt_mangledname,AB_EXTERNAL,AT_DATA),0);
          reference_reset_symbol(href2,objectlibrary.newasmsymbol(excepttype.vmt_mangledname,AB_EXTERNAL,AT_DATA),0);
-         paraloc1:=paramanager.getintparaloc(pocall_default,1);
+         paramanager.getintparaloc(pocall_default,1,paraloc1);
          paramanager.allocparaloc(exprasmlist,paraloc1);
          paramanager.allocparaloc(exprasmlist,paraloc1);
          cg.a_paramaddr_ref(exprasmlist,href2,paraloc1);
          cg.a_paramaddr_ref(exprasmlist,href2,paraloc1);
          paramanager.freeparaloc(exprasmlist,paraloc1);
          paramanager.freeparaloc(exprasmlist,paraloc1);
@@ -1161,9 +1173,7 @@ implementation
              tvarsym(exceptsymtable.symindex.first).localloc.loc:=LOC_REFERENCE;
              tvarsym(exceptsymtable.symindex.first).localloc.loc:=LOC_REFERENCE;
              tg.GetLocal(exprasmlist,sizeof(aint),voidpointertype.def,
              tg.GetLocal(exprasmlist,sizeof(aint),voidpointertype.def,
                 tvarsym(exceptsymtable.symindex.first).localloc.reference);
                 tvarsym(exceptsymtable.symindex.first).localloc.reference);
-             reference_reset_base(href2,tvarsym(exceptsymtable.symindex.first).localloc.reference.index,
-                tvarsym(exceptsymtable.symindex.first).localloc.reference.offset);
-             cg.a_load_reg_ref(exprasmlist,OS_ADDR,OS_ADDR,NR_FUNCTION_RESULT_REG,href2);
+             cg.a_load_reg_ref(exprasmlist,OS_ADDR,OS_ADDR,NR_FUNCTION_RESULT_REG,tvarsym(exceptsymtable.symindex.first).localloc.reference);
            end
            end
          else
          else
            begin
            begin
@@ -1179,6 +1189,8 @@ implementation
          get_exception_temps(exprasmlist,excepttemps);
          get_exception_temps(exprasmlist,excepttemps);
          new_exception(exprasmlist,excepttemps,1,doobjectdestroyandreraise);
          new_exception(exprasmlist,excepttemps,1,doobjectdestroyandreraise);
 
 
+         oldaktbreaklabel:=nil;
+         oldaktcontinuelabel:=nil;
          if assigned(right) then
          if assigned(right) then
            begin
            begin
               oldaktexitlabel:=current_procinfo.aktexitlabel;
               oldaktexitlabel:=current_procinfo.aktexitlabel;
@@ -1204,7 +1216,7 @@ implementation
          cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
          cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
          cg.a_call_name(exprasmlist,'FPC_POPSECONDOBJECTSTACK');
          cg.a_call_name(exprasmlist,'FPC_POPSECONDOBJECTSTACK');
          cg.deallocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
          cg.deallocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
-         paraloc1:=paramanager.getintparaloc(pocall_default,1);
+         paramanager.getintparaloc(pocall_default,1,paraloc1);
          paramanager.allocparaloc(exprasmlist,paraloc1);
          paramanager.allocparaloc(exprasmlist,paraloc1);
          cg.a_param_reg(exprasmlist, OS_ADDR, NR_FUNCTION_RESULT_REG, paraloc1);
          cg.a_param_reg(exprasmlist, OS_ADDR, NR_FUNCTION_RESULT_REG, paraloc1);
          paramanager.freeparaloc(exprasmlist,paraloc1);
          paramanager.freeparaloc(exprasmlist,paraloc1);
@@ -1262,6 +1274,8 @@ implementation
          unget_exception_temps(exprasmlist,excepttemps);
          unget_exception_temps(exprasmlist,excepttemps);
          cg.a_label(exprasmlist,nextonlabel);
          cg.a_label(exprasmlist,nextonlabel);
          flowcontrol:=oldflowcontrol+flowcontrol;
          flowcontrol:=oldflowcontrol+flowcontrol;
+         paraloc1.done;
+
          { next on node }
          { next on node }
          if assigned(left) then
          if assigned(left) then
            secondpass(left);
            secondpass(left);
@@ -1440,7 +1454,16 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.97  2004-06-20 08:55:29  florian
+  Revision 1.98  2004-09-21 17:25:12  peter
+    * paraloc branch merged
+
+  Revision 1.97.4.2  2004/09/12 18:30:48  peter
+    * uninitialized vars fixed
+
+  Revision 1.97.4.1  2004/08/31 20:43:06  peter
+    * paraloc patch
+
+  Revision 1.97  2004/06/20 08:55:29  florian
     * logs truncated
     * logs truncated
 
 
   Revision 1.96  2004/06/16 20:07:08  florian
   Revision 1.96  2004/06/16 20:07:08  florian

+ 21 - 7
compiler/ncginl.pas

@@ -57,7 +57,7 @@ implementation
       globtype,systems,
       globtype,systems,
       cutils,verbose,globals,fmodule,
       cutils,verbose,globals,fmodule,
       symconst,symdef,defutil,symsym,
       symconst,symdef,defutil,symsym,
-      aasmbase,aasmtai,aasmcpu,
+      aasmbase,aasmtai,aasmcpu,parabase,
       cgbase,pass_1,pass_2,
       cgbase,pass_1,pass_2,
       cpuinfo,cpubase,paramgr,procinfo,
       cpuinfo,cpubase,paramgr,procinfo,
       nbas,ncon,ncal,ncnv,nld,
       nbas,ncon,ncal,ncnv,nld,
@@ -183,15 +183,19 @@ implementation
        hp2 : tstringconstnode;
        hp2 : tstringconstnode;
        otlabel,oflabel : tasmlabel;
        otlabel,oflabel : tasmlabel;
        paraloc1,paraloc2,
        paraloc1,paraloc2,
-       paraloc3,paraloc4 : tparalocation;
+       paraloc3,paraloc4 : tcgpara;
      begin
      begin
        { the node should be removed in the firstpass }
        { the node should be removed in the firstpass }
        if not (cs_do_assertion in aktlocalswitches) then
        if not (cs_do_assertion in aktlocalswitches) then
           internalerror(7123458);
           internalerror(7123458);
-       paraloc1:=paramanager.getintparaloc(pocall_default,1);
-       paraloc2:=paramanager.getintparaloc(pocall_default,2);
-       paraloc3:=paramanager.getintparaloc(pocall_default,3);
-       paraloc4:=paramanager.getintparaloc(pocall_default,4);
+       paraloc1.init;
+       paraloc2.init;
+       paraloc3.init;
+       paraloc4.init;
+       paramanager.getintparaloc(pocall_default,1,paraloc1);
+       paramanager.getintparaloc(pocall_default,2,paraloc2);
+       paramanager.getintparaloc(pocall_default,3,paraloc3);
+       paramanager.getintparaloc(pocall_default,4,paraloc4);
        otlabel:=truelabel;
        otlabel:=truelabel;
        oflabel:=falselabel;
        oflabel:=falselabel;
        objectlibrary.getlabel(truelabel);
        objectlibrary.getlabel(truelabel);
@@ -229,6 +233,10 @@ implementation
        cg.a_label(exprasmlist,truelabel);
        cg.a_label(exprasmlist,truelabel);
        truelabel:=otlabel;
        truelabel:=otlabel;
        falselabel:=oflabel;
        falselabel:=oflabel;
+       paraloc1.done;
+       paraloc2.done;
+       paraloc3.done;
+       paraloc4.done;
      end;
      end;
 
 
 
 
@@ -686,7 +694,13 @@ end.
 
 
 {
 {
   $Log$
   $Log$
-  Revision 1.62  2004-08-16 21:00:15  peter
+  Revision 1.63  2004-09-21 17:25:12  peter
+    * paraloc branch merged
+
+  Revision 1.62.4.1  2004/08/31 20:43:06  peter
+    * paraloc patch
+
+  Revision 1.62  2004/08/16 21:00:15  peter
     * range checks fixed
     * range checks fixed
 
 
   Revision 1.61  2004/07/12 17:58:19  peter
   Revision 1.61  2004/07/12 17:58:19  peter

+ 40 - 21
compiler/ncgld.pas

@@ -56,7 +56,7 @@ implementation
       aasmbase,aasmtai,aasmcpu,
       aasmbase,aasmtai,aasmcpu,
       cgbase,pass_2,
       cgbase,pass_2,
       procinfo,
       procinfo,
-      cpubase,
+      cpubase,parabase,
       tgobj,ncgutil,
       tgobj,ncgutil,
       cgutils,cgobj,
       cgutils,cgobj,
       ncgbas;
       ncgbas;
@@ -80,7 +80,7 @@ implementation
         newsize : tcgsize;
         newsize : tcgsize;
         endrelocatelab,
         endrelocatelab,
         norelocatelab : tasmlabel;
         norelocatelab : tasmlabel;
-        paraloc1 : tparalocation;
+        paraloc1 : tcgpara;
       begin
       begin
          { we don't know the size of all arrays }
          { we don't know the size of all arrays }
          newsize:=def_cgsize(resulttype.def);
          newsize:=def_cgsize(resulttype.def);
@@ -164,7 +164,8 @@ implementation
                        objectlibrary.getlabel(norelocatelab);
                        objectlibrary.getlabel(norelocatelab);
                        objectlibrary.getlabel(endrelocatelab);
                        objectlibrary.getlabel(endrelocatelab);
                        { make sure hregister can't allocate the register necessary for the parameter }
                        { make sure hregister can't allocate the register necessary for the parameter }
-                       paraloc1:=paramanager.getintparaloc(pocall_default,1);
+                       paraloc1.init;
+                       paramanager.getintparaloc(pocall_default,1,paraloc1);
                        hregister:=cg.getaddressregister(exprasmlist);
                        hregister:=cg.getaddressregister(exprasmlist);
                        reference_reset_symbol(href,objectlibrary.newasmsymbol('FPC_THREADVAR_RELOCATE',AB_EXTERNAL,AT_DATA),0);
                        reference_reset_symbol(href,objectlibrary.newasmsymbol('FPC_THREADVAR_RELOCATE',AB_EXTERNAL,AT_DATA),0);
                        cg.a_load_ref_reg(exprasmlist,OS_ADDR,OS_ADDR,href,hregister);
                        cg.a_load_ref_reg(exprasmlist,OS_ADDR,OS_ADDR,href,hregister);
@@ -175,6 +176,7 @@ implementation
                        paramanager.allocparaloc(exprasmlist,paraloc1);
                        paramanager.allocparaloc(exprasmlist,paraloc1);
                        cg.a_param_ref(exprasmlist,OS_ADDR,href,paraloc1);
                        cg.a_param_ref(exprasmlist,OS_ADDR,href,paraloc1);
                        paramanager.freeparaloc(exprasmlist,paraloc1);
                        paramanager.freeparaloc(exprasmlist,paraloc1);
+                       paraloc1.done;
                        cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
                        cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
                        cg.a_call_reg(exprasmlist,hregister);
                        cg.a_call_reg(exprasmlist,hregister);
                        cg.deallocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
                        cg.deallocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
@@ -235,8 +237,7 @@ implementation
                                 begin
                                 begin
                                   if tvarsym(symtableentry).localloc.loc<>LOC_REFERENCE then
                                   if tvarsym(symtableentry).localloc.loc<>LOC_REFERENCE then
                                     internalerror(2003091816);
                                     internalerror(2003091816);
-                                  location.reference.base:=tvarsym(symtableentry).localloc.reference.index;
-                                  location.reference.offset:=tvarsym(symtableentry).localloc.reference.offset;
+                                  location.reference:=tvarsym(symtableentry).localloc.reference;
                                 end;
                                 end;
                               globalsymtable,
                               globalsymtable,
                               staticsymtable :
                               staticsymtable :
@@ -254,8 +255,7 @@ implementation
                                 begin
                                 begin
                                   if tvarsym(symtableentry).localloc.loc<>LOC_REFERENCE then
                                   if tvarsym(symtableentry).localloc.loc<>LOC_REFERENCE then
                                     internalerror(2003091817);
                                     internalerror(2003091817);
-                                  location.reference.base:=tvarsym(symtableentry).localloc.reference.index;
-                                  location.reference.offset:=tvarsym(symtableentry).localloc.reference.offset;
+                                  location.reference:=tvarsym(symtableentry).localloc.reference;
                                 end;
                                 end;
                               else
                               else
                                 internalerror(200305102);
                                 internalerror(200305102);
@@ -394,6 +394,7 @@ implementation
          href : treference;
          href : treference;
          old_allow_multi_pass2,
          old_allow_multi_pass2,
          releaseright : boolean;
          releaseright : boolean;
+         len : aint;
          cgsize : tcgsize;
          cgsize : tcgsize;
          r:Tregister;
          r:Tregister;
 
 
@@ -408,14 +409,14 @@ implementation
         {
         {
           in most cases we can process first the right node which contains
           in most cases we can process first the right node which contains
           the most complex code. Exceptions for this are:
           the most complex code. Exceptions for this are:
-	    - result is in flags, loading left will then destroy the flags
-	    - result need reference count, when left points to a value used in
-	      right then decreasing the refcnt on left can possibly release
-	      the memory before right increased the refcnt, result is that an
-	      empty value is assigned
-	    - calln, call destroys most registers and is therefor 'complex'
-	
-	   But not when the result is in the flags, then
+            - result is in flags, loading left will then destroy the flags
+            - result need reference count, when left points to a value used in
+              right then decreasing the refcnt on left can possibly release
+              the memory before right increased the refcnt, result is that an
+              empty value is assigned
+            - calln, call destroys most registers and is therefor 'complex'
+
+           But not when the result is in the flags, then
           loading the left node afterwards can destroy the flags.
           loading the left node afterwards can destroy the flags.
 
 
           when the right node returns as LOC_JUMP then we will generate
           when the right node returns as LOC_JUMP then we will generate
@@ -598,10 +599,16 @@ implementation
                     LOC_REFERENCE,
                     LOC_REFERENCE,
                     LOC_CREFERENCE :
                     LOC_CREFERENCE :
                       begin
                       begin
-                        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;
+{$warning HACK: unaligned test, maybe remove all unaligned locations (array of char) from the compiler}
+                        { Use unaligned copy when the offset is not aligned }
+                        len:=left.resulttype.def.size;
+                        if (right.location.reference.offset mod sizeof(aint)<>0) and
+                           (len>sizeof(aint)) then
+                          cg.g_concatcopy_unaligned(exprasmlist,right.location.reference,
+                              left.location.reference,len,false,false)
+                        else
+                          cg.g_concatcopy(exprasmlist,right.location.reference,
+                              left.location.reference,len,false,false);
                       end;
                       end;
                     else
                     else
                       internalerror(200203284);
                       internalerror(200203284);
@@ -751,7 +758,7 @@ implementation
         dovariant : boolean;
         dovariant : boolean;
         elesize : longint;
         elesize : longint;
         tmpreg  : tregister;
         tmpreg  : tregister;
-        paraloc : tparalocation;
+        paraloc : tcgparalocation;
       begin
       begin
         dovariant:=(nf_forcevaria in flags) or tarraydef(resulttype.def).isvariant;
         dovariant:=(nf_forcevaria in flags) or tarraydef(resulttype.def).isvariant;
         if dovariant then
         if dovariant then
@@ -961,9 +968,21 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.123  2004-09-13 20:33:41  peter
+  Revision 1.124  2004-09-21 17:25:12  peter
+    * paraloc branch merged
+
+  Revision 1.123  2004/09/13 20:33:41  peter
     * pwidechar support in array of const
     * pwidechar support in array of const
 
 
+  Revision 1.122.4.3  2004/09/12 18:31:50  peter
+    * use normal concatcopy when data < sizeof(aint)
+
+  Revision 1.122.4.2  2004/09/12 13:36:40  peter
+    * fixed alignment issues
+
+  Revision 1.122.4.1  2004/08/31 20:43:06  peter
+    * paraloc patch
+
   Revision 1.122  2004/08/15 13:30:18  florian
   Revision 1.122  2004/08/15 13:30:18  florian
     * fixed alignment of variant records
     * fixed alignment of variant records
     * more alignment problems fixed
     * more alignment problems fixed

+ 12 - 3
compiler/ncgmat.pas

@@ -129,6 +129,7 @@ implementation
       globtype,systems,
       globtype,systems,
       cutils,verbose,globals,
       cutils,verbose,globals,
       symconst,aasmbase,aasmtai,aasmcpu,defutil,
       symconst,aasmbase,aasmtai,aasmcpu,defutil,
+      parabase,
       pass_2,
       pass_2,
       ncon,
       ncon,
       tgobj,ncgutil,cgobj,paramgr
       tgobj,ncgutil,cgobj,paramgr
@@ -266,7 +267,7 @@ implementation
          hdenom : tregister;
          hdenom : tregister;
          power : longint;
          power : longint;
          hl : tasmlabel;
          hl : tasmlabel;
-         paraloc1 : tparalocation;
+         paraloc1 : tcgpara;
       begin
       begin
          secondpass(left);
          secondpass(left);
          if codegenerror then
          if codegenerror then
@@ -332,11 +333,13 @@ implementation
                   }
                   }
                   objectlibrary.getlabel(hl);
                   objectlibrary.getlabel(hl);
                   cg.a_cmp_const_reg_label(exprasmlist,OS_INT,OC_NE,0,hdenom,hl);
                   cg.a_cmp_const_reg_label(exprasmlist,OS_INT,OC_NE,0,hdenom,hl);
-                  paraloc1:=paramanager.getintparaloc(pocall_default,1);
+                  paraloc1.init;
+                  paramanager.getintparaloc(pocall_default,1,paraloc1);
                   paramanager.allocparaloc(exprasmlist,paraloc1);
                   paramanager.allocparaloc(exprasmlist,paraloc1);
                   cg.a_param_const(exprasmlist,OS_S32,200,paraloc1);
                   cg.a_param_const(exprasmlist,OS_S32,200,paraloc1);
                   paramanager.freeparaloc(exprasmlist,paraloc1);
                   paramanager.freeparaloc(exprasmlist,paraloc1);
                   cg.a_call_name(exprasmlist,'FPC_HANDLERROR');
                   cg.a_call_name(exprasmlist,'FPC_HANDLERROR');
+                  paraloc1.done;
                   cg.a_label(exprasmlist,hl);
                   cg.a_label(exprasmlist,hl);
                   if nodetype = modn then
                   if nodetype = modn then
                     emit_mod_reg_reg(is_signed(left.resulttype.def),hdenom,hreg1)
                     emit_mod_reg_reg(is_signed(left.resulttype.def),hdenom,hreg1)
@@ -480,7 +483,13 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.27  2004-06-20 08:55:29  florian
+  Revision 1.28  2004-09-21 17:25:12  peter
+    * paraloc branch merged
+
+  Revision 1.27.4.1  2004/08/31 20:43:06  peter
+    * paraloc patch
+
+  Revision 1.27  2004/06/20 08:55:29  florian
     * logs truncated
     * logs truncated
 
 
   Revision 1.26  2004/06/16 20:07:08  florian
   Revision 1.26  2004/06/16 20:07:08  florian

+ 37 - 33
compiler/ncgmem.pas

@@ -21,8 +21,6 @@
 
 
  ****************************************************************************
  ****************************************************************************
 }
 }
-{ This unit generate assembler for memory related nodes.
-}
 unit ncgmem;
 unit ncgmem;
 
 
 {$i fpcdefs.inc}
 {$i fpcdefs.inc}
@@ -80,22 +78,18 @@ interface
 implementation
 implementation
 
 
     uses
     uses
-{$ifdef delphi}
-      sysutils,
-{$else}
-      strings,
-{$endif}
 {$ifdef GDB}
 {$ifdef GDB}
+      strings,
       gdb,
       gdb,
 {$endif GDB}
 {$endif GDB}
       systems,
       systems,
       cutils,verbose,globals,
       cutils,verbose,globals,
       symconst,symdef,symsym,defutil,paramgr,
       symconst,symdef,symsym,defutil,paramgr,
       aasmbase,aasmtai,
       aasmbase,aasmtai,
-      procinfo,pass_2,
+      procinfo,pass_2,parabase,
       pass_1,nld,ncon,nadd,nutils,
       pass_1,nld,ncon,nadd,nutils,
       cgutils,cgobj,
       cgutils,cgobj,
-      tgobj,ncgutil,symbase
+      tgobj,ncgutil
       ;
       ;
 
 
 
 
@@ -194,15 +188,7 @@ implementation
             hsym:=tvarsym(currpi.procdef.parast.search('parentfp'));
             hsym:=tvarsym(currpi.procdef.parast.search('parentfp'));
             if not assigned(hsym) then
             if not assigned(hsym) then
               internalerror(200309281);
               internalerror(200309281);
-            case hsym.localloc.loc of
-              LOC_REFERENCE :
-                begin
-                  reference_reset_base(href,hsym.localloc.reference.index,hsym.localloc.reference.offset);
-                  cg.a_load_ref_reg(exprasmlist,OS_ADDR,OS_ADDR,href,location.register);
-                end;
-              LOC_REGISTER :
-                cg.a_load_reg_reg(exprasmlist,OS_ADDR,OS_ADDR,hsym.localloc.register,location.register);
-            end;
+            cg.a_load_loc_reg(exprasmlist,OS_ADDR,hsym.localloc,location.register);
             { walk parents }
             { walk parents }
             while (currpi.procdef.owner.symtablelevel>parentpd.parast.symtablelevel) do
             while (currpi.procdef.owner.symtablelevel>parentpd.parast.symtablelevel) do
               begin
               begin
@@ -259,7 +245,7 @@ implementation
 
 
     procedure tcgderefnode.pass_2;
     procedure tcgderefnode.pass_2;
       var
       var
-        paraloc1 : tparalocation;
+        paraloc1 : tcgpara;
       begin
       begin
          secondpass(left);
          secondpass(left);
          location_reset(location,LOC_REFERENCE,def_cgsize(resulttype.def));
          location_reset(location,LOC_REFERENCE,def_cgsize(resulttype.def));
@@ -292,10 +278,12 @@ implementation
             not(cs_compilesystem in aktmoduleswitches) and
             not(cs_compilesystem in aktmoduleswitches) and
             (not tpointerdef(left.resulttype.def).is_far) then
             (not tpointerdef(left.resulttype.def).is_far) then
           begin
           begin
-            paraloc1:=paramanager.getintparaloc(pocall_default,1);
+            paraloc1.init;
+            paramanager.getintparaloc(pocall_default,1,paraloc1);
             paramanager.allocparaloc(exprasmlist,paraloc1);
             paramanager.allocparaloc(exprasmlist,paraloc1);
             cg.a_param_reg(exprasmlist, OS_ADDR,location.reference.base,paraloc1);
             cg.a_param_reg(exprasmlist, OS_ADDR,location.reference.base,paraloc1);
             paramanager.freeparaloc(exprasmlist,paraloc1);
             paramanager.freeparaloc(exprasmlist,paraloc1);
+            paraloc1.done;
             cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
             cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
             cg.a_call_name(exprasmlist,'FPC_CHECKPOINTER');
             cg.a_call_name(exprasmlist,'FPC_CHECKPOINTER');
             cg.deallocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
             cg.deallocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
@@ -309,11 +297,12 @@ implementation
 
 
     procedure tcgsubscriptnode.pass_2;
     procedure tcgsubscriptnode.pass_2;
       var
       var
-        paraloc1 : tparalocation;
+        paraloc1 : tcgpara;
       begin
       begin
          secondpass(left);
          secondpass(left);
          if codegenerror then
          if codegenerror then
            exit;
            exit;
+         paraloc1.init;
          { classes and interfaces must be dereferenced implicit }
          { classes and interfaces must be dereferenced implicit }
          if is_class_or_interface(left.resulttype.def) then
          if is_class_or_interface(left.resulttype.def) then
            begin
            begin
@@ -347,7 +336,7 @@ implementation
                 (cs_checkpointer in aktglobalswitches) and
                 (cs_checkpointer in aktglobalswitches) and
                 not(cs_compilesystem in aktmoduleswitches) then
                 not(cs_compilesystem in aktmoduleswitches) then
               begin
               begin
-                paraloc1:=paramanager.getintparaloc(pocall_default,1);
+                paramanager.getintparaloc(pocall_default,1,paraloc1);
                 paramanager.allocparaloc(exprasmlist,paraloc1);
                 paramanager.allocparaloc(exprasmlist,paraloc1);
                 cg.a_param_reg(exprasmlist, OS_ADDR,location.reference.base,paraloc1);
                 cg.a_param_reg(exprasmlist, OS_ADDR,location.reference.base,paraloc1);
                 paramanager.freeparaloc(exprasmlist,paraloc1);
                 paramanager.freeparaloc(exprasmlist,paraloc1);
@@ -365,7 +354,7 @@ implementation
                 (cs_checkpointer in aktglobalswitches) and
                 (cs_checkpointer in aktglobalswitches) and
                 not(cs_compilesystem in aktmoduleswitches) then
                 not(cs_compilesystem in aktmoduleswitches) then
               begin
               begin
-                paraloc1:=paramanager.getintparaloc(pocall_default,1);
+                paramanager.getintparaloc(pocall_default,1,paraloc1);
                 paramanager.allocparaloc(exprasmlist,paraloc1);
                 paramanager.allocparaloc(exprasmlist,paraloc1);
                 cg.a_param_reg(exprasmlist, OS_ADDR,location.reference.base,paraloc1);
                 cg.a_param_reg(exprasmlist, OS_ADDR,location.reference.base,paraloc1);
                 paramanager.freeparaloc(exprasmlist,paraloc1);
                 paramanager.freeparaloc(exprasmlist,paraloc1);
@@ -380,6 +369,7 @@ implementation
          inc(location.reference.offset,vs.fieldoffset);
          inc(location.reference.offset,vs.fieldoffset);
          { also update the size of the location }
          { also update the size of the location }
          location.size:=def_cgsize(resulttype.def);
          location.size:=def_cgsize(resulttype.def);
+         paraloc1.done;
       end;
       end;
 
 
 
 
@@ -520,8 +510,10 @@ implementation
          poslabel,
          poslabel,
          neglabel : tasmlabel;
          neglabel : tasmlabel;
          hreg : tregister;
          hreg : tregister;
-         paraloc1,paraloc2 : tparalocation;
+         paraloc1,paraloc2 : tcgpara;
        begin
        begin
+         paraloc1.init;
+         paraloc2.init;
          if is_open_array(left.resulttype.def) or
          if is_open_array(left.resulttype.def) or
             is_array_of_const(left.resulttype.def) then
             is_array_of_const(left.resulttype.def) then
           begin
           begin
@@ -562,8 +554,8 @@ implementation
          else
          else
           if is_dynamic_array(left.resulttype.def) then
           if is_dynamic_array(left.resulttype.def) then
             begin
             begin
-               paraloc1:=paramanager.getintparaloc(pocall_default,1);
-               paraloc2:=paramanager.getintparaloc(pocall_default,2);
+               paramanager.getintparaloc(pocall_default,1,paraloc1);
+               paramanager.getintparaloc(pocall_default,2,paraloc2);
                paramanager.allocparaloc(exprasmlist,paraloc2);
                paramanager.allocparaloc(exprasmlist,paraloc2);
                cg.a_param_loc(exprasmlist,right.location,paraloc2);
                cg.a_param_loc(exprasmlist,right.location,paraloc2);
                paramanager.allocparaloc(exprasmlist,paraloc1);
                paramanager.allocparaloc(exprasmlist,paraloc1);
@@ -576,6 +568,8 @@ implementation
             end
             end
          else
          else
            cg.g_rangecheck(exprasmlist,right.location,right.resulttype.def,left.resulttype.def);
            cg.g_rangecheck(exprasmlist,right.location,right.resulttype.def,left.resulttype.def);
+         paraloc1.done;
+         paraloc2.done;
        end;
        end;
 
 
 
 
@@ -590,8 +584,10 @@ implementation
          newsize : tcgsize;
          newsize : tcgsize;
          mulsize: longint;
          mulsize: longint;
          isjump  : boolean;
          isjump  : boolean;
-         paraloc1,paraloc2 : tparalocation;
+         paraloc1,paraloc2 : tcgpara;
       begin
       begin
+         paraloc1.init;
+         paraloc2.init;
          mulsize := get_mul_size;
          mulsize := get_mul_size;
 
 
          newsize:=def_cgsize(resulttype.def);
          newsize:=def_cgsize(resulttype.def);
@@ -628,7 +624,7 @@ implementation
                 we can use the ansistring routine here }
                 we can use the ansistring routine here }
               if (cs_check_range in aktlocalswitches) then
               if (cs_check_range in aktlocalswitches) then
                 begin
                 begin
-                   paraloc1:=paramanager.getintparaloc(pocall_default,1);
+                   paramanager.getintparaloc(pocall_default,1,paraloc1);
                    paramanager.allocparaloc(exprasmlist,paraloc1);
                    paramanager.allocparaloc(exprasmlist,paraloc1);
                    cg.a_param_reg(exprasmlist,OS_ADDR,location.reference.base,paraloc1);
                    cg.a_param_reg(exprasmlist,OS_ADDR,location.reference.base,paraloc1);
                    paramanager.freeparaloc(exprasmlist,paraloc1);
                    paramanager.freeparaloc(exprasmlist,paraloc1);
@@ -712,8 +708,8 @@ implementation
                          st_ansistring:
                          st_ansistring:
                        {$endif}
                        {$endif}
                            begin
                            begin
-                              paraloc1:=paramanager.getintparaloc(pocall_default,1);
-                              paraloc2:=paramanager.getintparaloc(pocall_default,2);
+                              paramanager.getintparaloc(pocall_default,1,paraloc1);
+                              paramanager.getintparaloc(pocall_default,2,paraloc2);
                               paramanager.allocparaloc(exprasmlist,paraloc2);
                               paramanager.allocparaloc(exprasmlist,paraloc2);
                               cg.a_param_const(exprasmlist,OS_INT,tordconstnode(right).value,paraloc2);
                               cg.a_param_const(exprasmlist,OS_INT,tordconstnode(right).value,paraloc2);
                               href:=location.reference;
                               href:=location.reference;
@@ -850,8 +846,8 @@ implementation
                          st_ansistring:
                          st_ansistring:
                        {$endif}
                        {$endif}
                            begin
                            begin
-                              paraloc1:=paramanager.getintparaloc(pocall_default,1);
-                              paraloc2:=paramanager.getintparaloc(pocall_default,2);
+                              paramanager.getintparaloc(pocall_default,1,paraloc1);
+                              paramanager.getintparaloc(pocall_default,2,paraloc2);
                               paramanager.allocparaloc(exprasmlist,paraloc2);
                               paramanager.allocparaloc(exprasmlist,paraloc2);
                               cg.a_param_reg(exprasmlist,OS_INT,right.location.register,paraloc2);
                               cg.a_param_reg(exprasmlist,OS_INT,right.location.register,paraloc2);
                               href:=location.reference;
                               href:=location.reference;
@@ -883,6 +879,8 @@ implementation
            end;
            end;
 
 
         location.size:=newsize;
         location.size:=newsize;
+        paraloc1.done;
+        paraloc2.done;
       end;
       end;
 
 
 
 
@@ -897,7 +895,13 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.95  2004-08-02 09:15:03  michael
+  Revision 1.96  2004-09-21 17:25:12  peter
+    * paraloc branch merged
+
+  Revision 1.95.4.1  2004/08/31 20:43:06  peter
+    * paraloc patch
+
+  Revision 1.95  2004/08/02 09:15:03  michael
   + Fixed range check for non-constant indexes in strings
   + Fixed range check for non-constant indexes in strings
 
 
   Revision 1.94  2004/07/12 17:58:19  peter
   Revision 1.94  2004/07/12 17:58:19  peter

+ 282 - 282
compiler/ncgutil.pas

@@ -29,7 +29,7 @@ interface
     uses
     uses
       node,cpuinfo,
       node,cpuinfo,
       globtype,
       globtype,
-      cpubase,cgbase,
+      cpubase,cgbase,parabase,
       aasmbase,aasmtai,aasmcpu,
       aasmbase,aasmtai,aasmcpu,
       symconst,symbase,symdef,symsym,symtype,symtable
       symconst,symbase,symdef,symsym,symtype,symtable
 {$ifndef cpu64bit}
 {$ifndef cpu64bit}
@@ -56,19 +56,14 @@ interface
     procedure gen_proc_entry_code(list:Taasmoutput);
     procedure gen_proc_entry_code(list:Taasmoutput);
     procedure gen_proc_exit_code(list:Taasmoutput);
     procedure gen_proc_exit_code(list:Taasmoutput);
     procedure gen_save_used_regs(list:TAAsmoutput);
     procedure gen_save_used_regs(list:TAAsmoutput);
-    procedure gen_restore_used_regs(list:TAAsmoutput;const funcretparaloc:tparalocation);
-    procedure gen_initialize_code(list:TAAsmoutput;inlined:boolean);
-    procedure gen_finalize_code(list:TAAsmoutput;inlined:boolean);
+    procedure gen_restore_used_regs(list:TAAsmoutput;const funcretparaloc:tcgpara);
+    procedure gen_initialize_code(list:TAAsmoutput);
+    procedure gen_finalize_code(list:TAAsmoutput);
     procedure gen_entry_code(list:TAAsmoutput);
     procedure gen_entry_code(list:TAAsmoutput);
     procedure gen_exit_code(list:TAAsmoutput);
     procedure gen_exit_code(list:TAAsmoutput);
     procedure gen_load_para_value(list:TAAsmoutput);
     procedure gen_load_para_value(list:TAAsmoutput);
     procedure gen_load_return_value(list:TAAsmoutput);
     procedure gen_load_return_value(list:TAAsmoutput);
 
 
-(*
-    procedure geninlineentrycode(list:TAAsmoutput;stackframe:longint);
-    procedure geninlineexitcode(list:TAAsmoutput;inlined:boolean);
-*)
-
    {#
    {#
       Allocate the buffers for exception management and setjmp environment.
       Allocate the buffers for exception management and setjmp environment.
       Return a pointer to these buffers, send them to the utility routine
       Return a pointer to these buffers, send them to the utility routine
@@ -106,7 +101,8 @@ interface
     procedure gen_alloc_localst(list:TAAsmoutput;st:tlocalsymtable);
     procedure gen_alloc_localst(list:TAAsmoutput;st:tlocalsymtable);
     procedure gen_free_localst(list:TAAsmoutput;st:tlocalsymtable);
     procedure gen_free_localst(list:TAAsmoutput;st:tlocalsymtable);
     procedure gen_alloc_parast(list:TAAsmoutput;st:tparasymtable);
     procedure gen_alloc_parast(list:TAAsmoutput;st:tparasymtable);
-    procedure gen_alloc_inline_parast(list:TAAsmoutput;st:tparasymtable);
+    procedure gen_alloc_inline_parast(list:TAAsmoutput;pd:tprocdef);
+    procedure gen_alloc_inline_funcret(list:TAAsmoutput;pd:tprocdef);
     procedure gen_free_parast(list:TAAsmoutput;st:tparasymtable);
     procedure gen_free_parast(list:TAAsmoutput;st:tparasymtable);
 
 
     { rtti and init/final }
     { rtti and init/final }
@@ -298,11 +294,14 @@ implementation
 
 
     procedure new_exception(list:TAAsmoutput;const t:texceptiontemps;a:aint;exceptlabel:tasmlabel);
     procedure new_exception(list:TAAsmoutput;const t:texceptiontemps;a:aint;exceptlabel:tasmlabel);
       var
       var
-        paraloc1,paraloc2,paraloc3 : tparalocation;
+        paraloc1,paraloc2,paraloc3 : tcgpara;
       begin
       begin
-        paraloc1:=paramanager.getintparaloc(pocall_default,1);
-        paraloc2:=paramanager.getintparaloc(pocall_default,2);
-        paraloc3:=paramanager.getintparaloc(pocall_default,3);
+        paraloc1.init;
+        paraloc2.init;
+        paraloc3.init;
+        paramanager.getintparaloc(pocall_default,1,paraloc1);
+        paramanager.getintparaloc(pocall_default,2,paraloc2);
+        paramanager.getintparaloc(pocall_default,3,paraloc3);
         paramanager.allocparaloc(list,paraloc3);
         paramanager.allocparaloc(list,paraloc3);
         cg.a_paramaddr_ref(list,t.envbuf,paraloc3);
         cg.a_paramaddr_ref(list,t.envbuf,paraloc3);
         paramanager.allocparaloc(list,paraloc2);
         paramanager.allocparaloc(list,paraloc2);
@@ -317,7 +316,7 @@ implementation
         cg.a_call_name(list,'FPC_PUSHEXCEPTADDR');
         cg.a_call_name(list,'FPC_PUSHEXCEPTADDR');
         cg.deallocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
         cg.deallocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
 
 
-        paraloc1:=paramanager.getintparaloc(pocall_default,1);
+        paramanager.getintparaloc(pocall_default,1,paraloc1);
         paramanager.allocparaloc(list,paraloc1);
         paramanager.allocparaloc(list,paraloc1);
         cg.a_param_reg(list,OS_ADDR,NR_FUNCTION_RESULT_REG,paraloc1);
         cg.a_param_reg(list,OS_ADDR,NR_FUNCTION_RESULT_REG,paraloc1);
         paramanager.freeparaloc(list,paraloc1);
         paramanager.freeparaloc(list,paraloc1);
@@ -327,6 +326,9 @@ implementation
 
 
         cg.g_exception_reason_save(list, t.reasonbuf);
         cg.g_exception_reason_save(list, t.reasonbuf);
         cg.a_cmp_const_reg_label(list,OS_S32,OC_NE,0,cg.makeregsize(list,NR_FUNCTION_RESULT_REG,OS_S32),exceptlabel);
         cg.a_cmp_const_reg_label(list,OS_S32,OC_NE,0,cg.makeregsize(list,NR_FUNCTION_RESULT_REG,OS_S32),exceptlabel);
+        paraloc1.done;
+        paraloc2.done;
+        paraloc3.done;
      end;
      end;
 
 
 
 
@@ -718,12 +720,12 @@ implementation
 
 
     procedure copyvalueparas(p : tnamedindexitem;arg:pointer);
     procedure copyvalueparas(p : tnamedindexitem;arg:pointer);
       var
       var
-        href1,href2 : treference;
+        href1 : treference;
         list:TAAsmoutput;
         list:TAAsmoutput;
         hsym : tvarsym;
         hsym : tvarsym;
         l    : longint;
         l    : longint;
         loadref : boolean;
         loadref : boolean;
-        localcopyloc : tparalocation;
+        localcopyloc : tlocation;
       begin
       begin
         list:=taasmoutput(arg);
         list:=taasmoutput(arg);
         if (tsym(p).typ=varsym) and
         if (tsym(p).typ=varsym) and
@@ -738,8 +740,7 @@ implementation
                  loadref:=false;
                  loadref:=false;
                end;
                end;
              LOC_REFERENCE :
              LOC_REFERENCE :
-               reference_reset_base(href1,tvarsym(p).localloc.reference.index,
-                   tvarsym(p).localloc.reference.offset);
+               href1:=tvarsym(p).localloc.reference;
              else
              else
                internalerror(200309181);
                internalerror(200309181);
            end;
            end;
@@ -760,8 +761,7 @@ implementation
                           so we're allowed to include pi_do_call here; after pass1 is run, this isn't allowed anymore
                           so we're allowed to include pi_do_call here; after pass1 is run, this isn't allowed anymore
                         }
                         }
                         include(current_procinfo.flags,pi_do_call);
                         include(current_procinfo.flags,pi_do_call);
-                        reference_reset_base(href2,hsym.localloc.reference.index,hsym.localloc.reference.offset);
-                        cg.g_copyvaluepara_openarray(list,href1,href2,tarraydef(tvarsym(p).vartype.def).elesize)
+                        cg.g_copyvaluepara_openarray(list,href1,hsym.localloc.reference,tarraydef(tvarsym(p).vartype.def).elesize)
                       end
                       end
                     else
                     else
                       internalerror(200309182);
                       internalerror(200309182);
@@ -778,17 +778,16 @@ implementation
               localcopyloc.size:=int_cgsize(l);
               localcopyloc.size:=int_cgsize(l);
               tg.GetLocal(list,l,tvarsym(p).vartype.def,localcopyloc.reference);
               tg.GetLocal(list,l,tvarsym(p).vartype.def,localcopyloc.reference);
               { Copy data }
               { Copy data }
-              reference_reset_base(href2,localcopyloc.reference.index,localcopyloc.reference.offset);
               if is_shortstring(tvarsym(p).vartype.def) then
               if is_shortstring(tvarsym(p).vartype.def) then
                 begin
                 begin
                   { this code is only executed before the code for the body and the entry/exit code is generated
                   { this code is only executed before the code for the body and the entry/exit code is generated
                     so we're allowed to include pi_do_call here; after pass1 is run, this isn't allowed anymore
                     so we're allowed to include pi_do_call here; after pass1 is run, this isn't allowed anymore
                   }
                   }
                   include(current_procinfo.flags,pi_do_call);
                   include(current_procinfo.flags,pi_do_call);
-                  cg.g_copyshortstring(list,href1,href2,tstringdef(tvarsym(p).vartype.def).len,false,loadref)
+                  cg.g_copyshortstring(list,href1,localcopyloc.reference,tstringdef(tvarsym(p).vartype.def).len,false,loadref)
                 end
                 end
               else
               else
-                cg.g_concatcopy(list,href1,href2,tvarsym(p).vartype.def.size,true,loadref);
+                cg.g_concatcopy(list,href1,localcopyloc.reference,tvarsym(p).vartype.def.size,true,loadref);
               { update localloc of varsym }
               { update localloc of varsym }
               tg.Ungetlocal(list,tvarsym(p).localloc.reference);
               tg.Ungetlocal(list,tvarsym(p).localloc.reference);
               tvarsym(p).localloc:=localcopyloc;
               tvarsym(p).localloc:=localcopyloc;
@@ -833,8 +832,8 @@ implementation
         hp.free;
         hp.free;
         exprasmlist:=oldexprasmlist;
         exprasmlist:=oldexprasmlist;
       end;
       end;
-      
-        
+
+
     { generates the code for finalisation of local variables }
     { generates the code for finalisation of local variables }
     procedure finalize_local_vars(p : tnamedindexitem;arg:pointer);
     procedure finalize_local_vars(p : tnamedindexitem;arg:pointer);
       begin
       begin
@@ -873,7 +872,7 @@ implementation
                      (pd.procsym=tprocsym(p)) and
                      (pd.procsym=tprocsym(p)) and
                      (pd.localst.symtabletype<>staticsymtable) then
                      (pd.localst.symtabletype<>staticsymtable) then
                     pd.localst.foreach_static(@finalize_local_typedconst,arg);
                     pd.localst.foreach_static(@finalize_local_typedconst,arg);
-                end;    
+                end;
             end;
             end;
         end;
         end;
       end;
       end;
@@ -910,7 +909,7 @@ implementation
                      (pd.procsym=tprocsym(p)) and
                      (pd.procsym=tprocsym(p)) and
                      (pd.localst.symtabletype<>staticsymtable) then
                      (pd.localst.symtabletype<>staticsymtable) then
                     pd.localst.foreach_static(@finalize_local_typedconst,arg);
                     pd.localst.foreach_static(@finalize_local_typedconst,arg);
-                end;    
+                end;
             end;
             end;
         end;
         end;
       end;
       end;
@@ -934,14 +933,13 @@ implementation
                begin
                begin
                  if tvarsym(p).localloc.loc<>LOC_REFERENCE then
                  if tvarsym(p).localloc.loc<>LOC_REFERENCE then
                    internalerror(200309187);
                    internalerror(200309187);
-                 reference_reset_base(href,tvarsym(p).localloc.reference.index,tvarsym(p).localloc.reference.offset);
-                 cg.g_incrrefcount(list,tvarsym(p).vartype.def,href,is_open_array(tvarsym(p).vartype.def));
+                 cg.g_incrrefcount(list,tvarsym(p).vartype.def,tvarsym(p).localloc.reference,is_open_array(tvarsym(p).vartype.def));
                end;
                end;
              vs_out :
              vs_out :
                begin
                begin
                  case tvarsym(p).localloc.loc of
                  case tvarsym(p).localloc.loc of
                    LOC_REFERENCE :
                    LOC_REFERENCE :
-                     reference_reset_base(href,tvarsym(p).localloc.reference.index,tvarsym(p).localloc.reference.offset);
+                     href:=tvarsym(p).localloc.reference;
                    else
                    else
                      internalerror(2003091810);
                      internalerror(2003091810);
                  end;
                  end;
@@ -959,7 +957,6 @@ implementation
     { generates the code for decrementing the reference count of parameters }
     { generates the code for decrementing the reference count of parameters }
     procedure final_paras(p : tnamedindexitem;arg:pointer);
     procedure final_paras(p : tnamedindexitem;arg:pointer);
       var
       var
-        href : treference;
         list:TAAsmoutput;
         list:TAAsmoutput;
       begin
       begin
         list:=taasmoutput(arg);
         list:=taasmoutput(arg);
@@ -972,8 +969,7 @@ implementation
               include(current_procinfo.flags,pi_needs_implicit_finally);
               include(current_procinfo.flags,pi_needs_implicit_finally);
               if tvarsym(p).localloc.loc<>LOC_REFERENCE then
               if tvarsym(p).localloc.loc<>LOC_REFERENCE then
                 internalerror(200309188);
                 internalerror(200309188);
-              reference_reset_base(href,tvarsym(p).localloc.reference.index,tvarsym(p).localloc.reference.offset);
-              cg.g_decrrefcount(list,tvarsym(p).vartype.def,href,is_open_array(tvarsym(p).vartype.def));
+              cg.g_decrrefcount(list,tvarsym(p).vartype.def,tvarsym(p).localloc.reference,is_open_array(tvarsym(p).vartype.def));
             end;
             end;
          end
          end
         else if (tsym(p).typ=varsym) and
         else if (tsym(p).typ=varsym) and
@@ -984,10 +980,7 @@ implementation
             { cdecl functions don't have a high pointer so it is not possible to generate
             { cdecl functions don't have a high pointer so it is not possible to generate
               a local copy }
               a local copy }
             if not(current_procinfo.procdef.proccalloption in [pocall_cdecl,pocall_cppdecl]) then
             if not(current_procinfo.procdef.proccalloption in [pocall_cdecl,pocall_cppdecl]) then
-              begin
-                reference_reset_base(href,tvarsym(p).localloc.reference.index,tvarsym(p).localloc.reference.offset);
-                cg.g_releasevaluepara_openarray(list,href);
-              end;
+              cg.g_releasevaluepara_openarray(list,tvarsym(p).localloc.reference);
           end;
           end;
       end;
       end;
 
 
@@ -1034,12 +1027,15 @@ implementation
 
 
     procedure gen_load_return_value(list:TAAsmoutput);
     procedure gen_load_return_value(list:TAAsmoutput);
       var
       var
+{$ifndef cpu64bit}
+        href   : treference;
+{$endif cpu64bit}
         ressym : tvarsym;
         ressym : tvarsym;
-        resloc : tlocation;
+        resloc,
+        restmploc : tlocation;
         hreg   : tregister;
         hreg   : tregister;
-        resultloc : tparalocation;
+        funcretloc : pcgparalocation;
       begin
       begin
-        resultloc:=current_procinfo.procdef.funcret_paraloc[calleeside];
         { Is the loading needed? }
         { Is the loading needed? }
         if is_void(current_procinfo.procdef.rettype.def) or
         if is_void(current_procinfo.procdef.rettype.def) or
            (
            (
@@ -1049,36 +1045,40 @@ implementation
            ) then
            ) then
            exit;
            exit;
 
 
+        funcretloc:=current_procinfo.procdef.funcret_paraloc[calleeside].location;
+        if not assigned(funcretloc) then
+          internalerror(200408202);
+
         { constructors return self }
         { constructors return self }
         if (current_procinfo.procdef.proctypeoption=potype_constructor) then
         if (current_procinfo.procdef.proctypeoption=potype_constructor) then
           ressym:=tvarsym(current_procinfo.procdef.parast.search('self'))
           ressym:=tvarsym(current_procinfo.procdef.parast.search('self'))
         else
         else
-          ressym := tvarsym(current_procinfo.procdef.funcretsym);
+          ressym:=tvarsym(current_procinfo.procdef.funcretsym);
         if (ressym.refs>0) then
         if (ressym.refs>0) then
           begin
           begin
             case ressym.localloc.loc of
             case ressym.localloc.loc of
               LOC_FPUREGISTER:
               LOC_FPUREGISTER:
                 begin
                 begin
-                  location_reset(resloc,LOC_CFPUREGISTER,resultloc.size);
-                  resloc.register:=ressym.localloc.register;
+                  location_reset(restmploc,LOC_CFPUREGISTER,funcretloc^.size);
+                  restmploc.register:=ressym.localloc.register;
                 end;
                 end;
 
 
               LOC_REGISTER:
               LOC_REGISTER:
                 begin
                 begin
-                  location_reset(resloc,LOC_CREGISTER,resultloc.size);
-                  resloc.register:=ressym.localloc.register;
+                  location_reset(restmploc,LOC_CREGISTER,funcretloc^.size);
+                  restmploc.register:=ressym.localloc.register;
                 end;
                 end;
 
 
               LOC_MMREGISTER:
               LOC_MMREGISTER:
                 begin
                 begin
-                  location_reset(resloc,LOC_CMMREGISTER,resultloc.size);
-                  resloc.register:=ressym.localloc.register;
+                  location_reset(restmploc,LOC_CMMREGISTER,funcretloc^.size);
+                  restmploc.register:=ressym.localloc.register;
                 end;
                 end;
 
 
               LOC_REFERENCE:
               LOC_REFERENCE:
                 begin
                 begin
-                  location_reset(resloc,LOC_REFERENCE,resultloc.size);
-                  reference_reset_base(resloc.reference,ressym.localloc.reference.index,ressym.localloc.reference.offset);
+                  location_reset(restmploc,LOC_REFERENCE,funcretloc^.size);
+                  restmploc.reference:=ressym.localloc.reference;
                 end;
                 end;
               else
               else
                 internalerror(200309184);
                 internalerror(200309184);
@@ -1087,40 +1087,89 @@ implementation
             { Here, we return the function result. In most architectures, the value is
             { Here, we return the function result. In most architectures, the value is
               passed into the FUNCTION_RETURN_REG, but in a windowed architecure like sparc a
               passed into the FUNCTION_RETURN_REG, but in a windowed architecure like sparc a
               function returns in a register and the caller receives it in an other one }
               function returns in a register and the caller receives it in an other one }
-            case resultloc.loc of
+            case funcretloc^.loc of
               LOC_REGISTER:
               LOC_REGISTER:
                 begin
                 begin
 {$ifndef cpu64bit}
 {$ifndef cpu64bit}
-                  if resloc.size in [OS_64,OS_S64] then
+                  if current_procinfo.procdef.funcret_paraloc[calleeside].size in [OS_64,OS_S64] then
                     begin
                     begin
-                      cg.getexplicitregister(list,NR_FUNCTION_RETURN64_LOW_REG);
-                      cg.getexplicitregister(list,NR_FUNCTION_RETURN64_HIGH_REG);
-                      cg.ungetregister(list,NR_FUNCTION_RETURN64_LOW_REG);
-                      cg.ungetregister(list,NR_FUNCTION_RETURN64_HIGH_REG);
-                      // for the optimizer
-                      cg.a_reg_alloc(list,NR_FUNCTION_RETURN64_LOW_REG);
-                      cg.a_reg_alloc(list,NR_FUNCTION_RETURN64_HIGH_REG);
-                      cg64.a_load64_loc_reg(list,resloc,joinreg64(NR_FUNCTION_RETURN64_LOW_REG,
-                                            NR_FUNCTION_RETURN64_HIGH_REG));
+                      current_procinfo.procdef.funcret_paraloc[calleeside].get_location(resloc);
+                      if resloc.loc<>LOC_REGISTER then
+                        internalerror(200409141);
+                      { Load low and high register separate to generate better register
+                        allocation info }
+                      if getsupreg(resloc.registerlow)<first_int_imreg then
+                        begin
+                          cg.getexplicitregister(list,resloc.registerlow);
+                          cg.ungetregister(list,resloc.registerlow);
+                          // for the optimizer
+                          cg.a_reg_alloc(list,resloc.registerlow);
+                        end;
+                      case restmploc.loc of
+                        LOC_REFERENCE :
+                          begin
+                            href:=restmploc.reference;
+                            if target_info.endian=ENDIAN_BIG then
+                              inc(href.offset,4);
+                            cg.a_load_ref_reg(list,OS_32,OS_32,href,resloc.registerlow);
+                          end;
+                        LOC_REGISTER :
+                          cg.a_load_reg_reg(list,OS_32,OS_32,restmploc.registerlow,resloc.registerlow);
+                        else
+                          internalerror(200409201);
+                      end;
+                      if getsupreg(resloc.registerhigh)<first_int_imreg then
+                        begin
+                          cg.getexplicitregister(list,resloc.registerhigh);
+                          cg.ungetregister(list,resloc.registerhigh);
+                          // for the optimizer
+                          cg.a_reg_alloc(list,resloc.registerhigh);
+                        end;
+                      case restmploc.loc of
+                        LOC_REFERENCE :
+                          begin
+                            href:=restmploc.reference;
+                            if target_info.endian=ENDIAN_LITTLE then
+                              inc(href.offset,4);
+                            cg.a_load_ref_reg(list,OS_32,OS_32,href,resloc.registerhigh);
+                          end;
+                        LOC_REGISTER :
+                          cg.a_load_reg_reg(list,OS_32,OS_32,restmploc.registerhigh,resloc.registerhigh);
+                        else
+                          internalerror(200409201);
+                      end;
                     end
                     end
                   else
                   else
 {$endif cpu64bit}
 {$endif cpu64bit}
                     begin
                     begin
-                      cg.getexplicitregister(list,resultloc.register);
-                      hreg:=cg.makeregsize(list,resultloc.register,resloc.size);
-                      cg.ungetregister(list,hreg);
-                      // for the optimizer
-                      cg.a_reg_alloc(list,resultloc.register);
-                      cg.a_load_loc_reg(list,resloc.size,resloc,hreg);
+                      hreg:=cg.makeregsize(list,funcretloc^.register,restmploc.size);
+                      if getsupreg(funcretloc^.register)<first_int_imreg then
+                        begin
+                          cg.getexplicitregister(list,funcretloc^.register);
+                          cg.ungetregister(list,hreg);
+                          // for the optimizer
+                          cg.a_reg_alloc(list,funcretloc^.register);
+                        end;
+                      cg.a_load_loc_reg(list,restmploc.size,restmploc,hreg);
                     end;
                     end;
                 end;
                 end;
               LOC_FPUREGISTER:
               LOC_FPUREGISTER:
                 begin
                 begin
-                  cg.a_loadfpu_loc_reg(list,resloc,resultloc.register);
+                  if getsupreg(funcretloc^.register)<first_fpu_imreg then
+                    begin
+                      cg.getexplicitregister(list,funcretloc^.register);
+                      cg.ungetregister(list,funcretloc^.register);
+                    end;
+                  cg.a_loadfpu_loc_reg(list,restmploc,funcretloc^.register);
                 end;
                 end;
               LOC_MMREGISTER:
               LOC_MMREGISTER:
                 begin
                 begin
-                  cg.a_loadmm_loc_reg(list,resloc.size,resloc,resultloc.register,mms_movescalar);
+                  if getsupreg(funcretloc^.register)<first_mm_imreg then
+                    begin
+                      cg.getexplicitregister(list,funcretloc^.register);
+                      cg.ungetregister(list,funcretloc^.register);
+                    end;
+                  cg.a_loadmm_loc_reg(list,restmploc.size,restmploc,funcretloc^.register,mms_movescalar);
                 end;
                 end;
               LOC_INVALID,
               LOC_INVALID,
               LOC_REFERENCE:
               LOC_REFERENCE:
@@ -1135,8 +1184,9 @@ implementation
     procedure gen_load_para_value(list:TAAsmoutput);
     procedure gen_load_para_value(list:TAAsmoutput);
       var
       var
         hp : tparaitem;
         hp : tparaitem;
-        href : treference;
         gotregvarparas : boolean;
         gotregvarparas : boolean;
+        hiparaloc,
+        paraloc : pcgparalocation;
       begin
       begin
         { Store register parameters in reference or in register variable }
         { Store register parameters in reference or in register variable }
         if assigned(current_procinfo.procdef.parast) and
         if assigned(current_procinfo.procdef.parast) and
@@ -1149,6 +1199,10 @@ implementation
             gotregvarparas := false;
             gotregvarparas := false;
             while assigned(hp) do
             while assigned(hp) do
               begin
               begin
+                paraloc:=hp.paraloc[calleeside].location;
+                if not assigned(paraloc) then
+                  internalerror(200408203);
+                hiparaloc:=paraloc^.next;
                 case tvarsym(hp.parasym).localloc.loc of
                 case tvarsym(hp.parasym).localloc.loc of
                   LOC_REGISTER,
                   LOC_REGISTER,
                   LOC_MMREGISTER,
                   LOC_MMREGISTER,
@@ -1162,35 +1216,26 @@ implementation
                     end;
                     end;
                   LOC_REFERENCE :
                   LOC_REFERENCE :
                     begin
                     begin
-                      if hp.paraloc[calleeside].loc<>LOC_REFERENCE then
+                      if paraloc^.loc<>LOC_REFERENCE then
                         begin
                         begin
-                          if getregtype(hp.paraloc[calleeside].register)=R_INTREGISTER then
+                          if getregtype(paraloc^.register)=R_INTREGISTER then
                             begin
                             begin
-                              if getsupreg(hp.paraloc[calleeside].register)<first_int_imreg then
+                              if getsupreg(paraloc^.register)<first_int_imreg then
                                 begin
                                 begin
 {$ifndef cpu64bit}
 {$ifndef cpu64bit}
-                                  if (hp.paraloc[calleeside].size in [OS_S64,OS_64]) then
-                                    begin
-                                      cg.getexplicitregister(list,hp.paraloc[calleeside].registerlow);
-                                      cg.getexplicitregister(list,hp.paraloc[calleeside].registerhigh);
-                                    end
-                                  else
+                                  if assigned(hiparaloc) then
+                                    cg.getexplicitregister(list,hiparaloc^.register);
 {$endif cpu64bit}
 {$endif cpu64bit}
-                                    cg.getexplicitregister(list,hp.paraloc[calleeside].register);
+                                  cg.getexplicitregister(list,paraloc^.register);
                                 end;
                                 end;
                               { Release parameter register }
                               { Release parameter register }
 {$ifndef cpu64bit}
 {$ifndef cpu64bit}
-                              if (hp.paraloc[calleeside].size in [OS_S64,OS_64]) then
-                                begin
-                                  cg.ungetregister(list,hp.paraloc[calleeside].registerlow);
-                                  cg.ungetregister(list,hp.paraloc[calleeside].registerhigh);
-                                end
-                              else
+                              if assigned(hiparaloc) then
+                                cg.ungetregister(list,hiparaloc^.register);
 {$endif cpu64bit}
 {$endif cpu64bit}
-                                cg.ungetregister(list,hp.paraloc[calleeside].register);
+                              cg.ungetregister(list,paraloc^.register);
                             end;
                             end;
-                          reference_reset_base(href,tvarsym(hp.parasym).localloc.reference.index,tvarsym(hp.parasym).localloc.reference.offset);
-                          cg.a_loadany_param_ref(list,hp.paraloc[calleeside],href,mms_movescalar);
+                          cg.a_loadany_param_ref(list,hp.paraloc[calleeside],tvarsym(hp.parasym).localloc.reference,mms_movescalar);
                         end;
                         end;
                     end;
                     end;
                   else
                   else
@@ -1219,7 +1264,7 @@ implementation
       end;
       end;
 
 
 
 
-    procedure gen_initialize_code(list:TAAsmoutput;inlined:boolean);
+    procedure gen_initialize_code(list:TAAsmoutput);
       begin
       begin
         { initialize local data like ansistrings }
         { initialize local data like ansistrings }
         case current_procinfo.procdef.proctypeoption of
         case current_procinfo.procdef.proctypeoption of
@@ -1251,7 +1296,7 @@ implementation
       end;
       end;
 
 
 
 
-    procedure gen_finalize_code(list:TAAsmoutput;inlined:boolean);
+    procedure gen_finalize_code(list:TAAsmoutput);
       begin
       begin
 {$ifdef OLDREGVARS}
 {$ifdef OLDREGVARS}
         cleanup_regvars(list);
         cleanup_regvars(list);
@@ -1288,9 +1333,12 @@ implementation
       var
       var
         href : treference;
         href : treference;
         paraloc1,
         paraloc1,
-        paraloc2 : tparalocation;
+        paraloc2 : tcgpara;
         hp   : tused_unit;
         hp   : tused_unit;
       begin
       begin
+        paraloc1.init;
+        paraloc2.init;
+
         { the actual profile code can clobber some registers,
         { the actual profile code can clobber some registers,
           therefore if the context must be saved, do it before
           therefore if the context must be saved, do it before
           the actual call to the profile code
           the actual call to the profile code
@@ -1316,8 +1364,8 @@ implementation
               (cs_profile in aktmoduleswitches) then
               (cs_profile in aktmoduleswitches) then
             begin
             begin
               reference_reset_symbol(href,objectlibrary.newasmsymbol('etext',AB_EXTERNAL,AT_DATA),0);
               reference_reset_symbol(href,objectlibrary.newasmsymbol('etext',AB_EXTERNAL,AT_DATA),0);
-              paraloc1:=paramanager.getintparaloc(pocall_default,1);
-              paraloc2:=paramanager.getintparaloc(pocall_default,2);
+              paramanager.getintparaloc(pocall_default,1,paraloc1);
+              paramanager.getintparaloc(pocall_default,2,paraloc2);
               paramanager.allocparaloc(list,paraloc2);
               paramanager.allocparaloc(list,paraloc2);
               cg.a_paramaddr_ref(list,href,paraloc2);
               cg.a_paramaddr_ref(list,href,paraloc2);
               reference_reset_symbol(href,objectlibrary.newasmsymbol('__image_base__',AB_EXTERNAL,AT_DATA),0);
               reference_reset_symbol(href,objectlibrary.newasmsymbol('__image_base__',AB_EXTERNAL,AT_DATA),0);
@@ -1360,6 +1408,9 @@ implementation
 {$ifdef OLDREGVARS}
 {$ifdef OLDREGVARS}
         load_regvars(list,nil);
         load_regvars(list,nil);
 {$endif OLDREGVARS}
 {$endif OLDREGVARS}
+
+        paraloc1.done;
+        paraloc2.done;
       end;
       end;
 
 
 
 
@@ -1504,9 +1555,11 @@ implementation
         lotemp,
         lotemp,
         stackframe : longint;
         stackframe : longint;
         check      : boolean;
         check      : boolean;
-        paraloc1   : tparalocation;
+        paraloc1   : tcgpara;
         href       : treference;
         href       : treference;
       begin
       begin
+        paraloc1.init;
+
         { generate call frame marker for dwarf call frame info }
         { generate call frame marker for dwarf call frame info }
         dwarfcfi.start_frame(list);
         dwarfcfi.start_frame(list);
 
 
@@ -1517,8 +1570,8 @@ implementation
           begin
           begin
             { Allocate tempspace to store register parameter than
             { Allocate tempspace to store register parameter than
               is destroyed when calling stackchecking code }
               is destroyed when calling stackchecking code }
-            paraloc1:=paramanager.getintparaloc(pocall_default,1);
-            if paraloc1.loc=LOC_REGISTER then
+            paramanager.getintparaloc(pocall_default,1,paraloc1);
+            if paraloc1.location^.loc=LOC_REGISTER then
               tg.GetTemp(list,sizeof(aint),tt_normal,href);
               tg.GetTemp(list,sizeof(aint),tt_normal,href);
           end;
           end;
 
 
@@ -1550,20 +1603,22 @@ implementation
            begin
            begin
              { The tempspace to store original register is already
              { The tempspace to store original register is already
                allocated above before the stackframe size is calculated. }
                allocated above before the stackframe size is calculated. }
-             if paraloc1.loc=LOC_REGISTER then
-               cg.a_load_reg_ref(list,OS_INT,OS_INT,paraloc1.register,href);
+             if paraloc1.location^.loc=LOC_REGISTER then
+               cg.a_load_reg_ref(list,OS_INT,OS_INT,paraloc1.location^.register,href);
              paramanager.allocparaloc(list,paraloc1);
              paramanager.allocparaloc(list,paraloc1);
              cg.a_param_const(list,OS_INT,stackframe,paraloc1);
              cg.a_param_const(list,OS_INT,stackframe,paraloc1);
              paramanager.freeparaloc(list,paraloc1);
              paramanager.freeparaloc(list,paraloc1);
              cg.allocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
              cg.allocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
              cg.a_call_name(list,'FPC_STACKCHECK');
              cg.a_call_name(list,'FPC_STACKCHECK');
              cg.deallocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
              cg.deallocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
-             if paraloc1.loc=LOC_REGISTER then
+             if paraloc1.location^.loc=LOC_REGISTER then
                begin
                begin
-                 cg.a_load_ref_reg(list,OS_INT,OS_INT,href,paraloc1.register);
+                 cg.a_load_ref_reg(list,OS_INT,OS_INT,href,paraloc1.location^.register);
                  tg.UnGetTemp(list,href);
                  tg.UnGetTemp(list,href);
                end;
                end;
            end;
            end;
+
+        paraloc1.done;
       end;
       end;
 
 
 
 
@@ -1586,9 +1641,7 @@ implementation
         cg.g_proc_exit(list,parasize,(po_nostackframe in current_procinfo.procdef.procoptions));
         cg.g_proc_exit(list,parasize,(po_nostackframe in current_procinfo.procdef.procoptions));
 
 
         { release return registers, needed for optimizer }
         { release return registers, needed for optimizer }
-        if current_procinfo.procdef.funcret_paraloc[calleeside].loc<>LOC_INVALID then
-          paramanager.freeparaloc(list,
-            current_procinfo.procdef.funcret_paraloc[calleeside]);
+        paramanager.freeparaloc(list,current_procinfo.procdef.funcret_paraloc[calleeside]);
 
 
         { end of frame marker for call frame info }
         { end of frame marker for call frame info }
         dwarfcfi.end_frame(list);
         dwarfcfi.end_frame(list);
@@ -1611,7 +1664,7 @@ implementation
       end;
       end;
 
 
 
 
-    procedure gen_restore_used_regs(list:TAAsmoutput;const funcretparaloc:tparalocation);
+    procedure gen_restore_used_regs(list:TAAsmoutput;const funcretparaloc:tcgpara);
       begin
       begin
         { Pure assembler routines need to save the registers themselves }
         { Pure assembler routines need to save the registers themselves }
         if (po_assembler in current_procinfo.procdef.procoptions) then
         if (po_assembler in current_procinfo.procdef.procoptions) then
@@ -1627,151 +1680,6 @@ implementation
       end;
       end;
 
 
 
 
-{****************************************************************************
-                                 Inlining
-****************************************************************************}
-
-(*
-    procedure load_inlined_return_value(list:TAAsmoutput);
-      var
-        ressym: tvarsym;
-        resloc: tlocation;
-        r,r2 : tregister;
-      begin
-        if not is_void(current_procinfo.procdef.rettype.def) then
-         begin
-           ressym := tvarsym(current_procinfo.procdef.funcretsym);
-           if ressym.reg.enum <> R_NO then
-             begin
-               if paramanager.ret_in_param(current_procinfo.procdef.rettype.def,current_procinfo.procdef.proccalloption) then
-                 location_reset(resloc,LOC_CREGISTER,OS_ADDR)
-               else
-                 if ressym.vartype.def.deftype = floatdef then
-                   location_reset(resloc,LOC_CFPUREGISTER,def_cgsize(current_procinfo.procdef.rettype.def))
-                 else
-                   location_reset(resloc,LOC_CREGISTER,def_cgsize(current_procinfo.procdef.rettype.def));
-               resloc.register := ressym.reg;
-             end
-           else
-             begin
-               location_reset(resloc,LOC_CREGISTER,def_cgsize(current_procinfo.procdef.rettype.def));
-               reference_reset_base(resloc.reference,current_procinfo.framepointer,tvarsym(current_procinfo.procdef.funcretsym).adjusted_address);
-             end;
-           { Here, we return the function result. In most architectures, the value is
-             passed into the FUNCTION_RETURN_REG, but in a windowed architecure like sparc a
-             function returns in a register and the caller receives it in an other one }
-           case current_procinfo.procdef.rettype.def.deftype of
-             orddef,
-             enumdef :
-               begin
-{$ifndef cpu64bit}
-                 if resloc.size in [OS_64,OS_S64] then
-                  begin
-                    r:=cg.getregisterint(list,OS_INT);
-                    r2:=cg.getregisterint(list,OS_INT);
-                    cg64.a_load64_loc_reg(list,resloc,joinreg64(r,r2));
-                  end
-                 else
-{$endif cpu64bit}
-                  begin
-                    r:=cg.getregisterint(list,resloc.size);
-                    cg.a_load_loc_reg(list,resloc.size,resloc,r);
-                  end;
-               end;
-             floatdef :
-               begin
-{$ifdef cpufpemu}
-                  if cs_fp_emulation in aktmoduleswitches then
-                    r.enum := FUNCTION_RETURN_REG
-                 else
-{$endif cpufpemu}
-                  r.enum:=FPU_RESULT_REG;
-                 cg.a_loadfpu_loc_reg(list,resloc,r);
-               end;
-             else
-               begin
-                 if not paramanager.ret_in_param(current_procinfo.procdef.rettype.def,current_procinfo.procdef.proccalloption) then
-                  begin
-{$ifndef cpu64bit}
-                    { Win32 can return records in EAX:EDX }
-                    if resloc.size in [OS_64,OS_S64] then
-                     begin
-                       r:=cg.getregisterint(list,OS_INT);
-                       r2:=cg.getregisterint(list,OS_INT);
-                       cg64.a_load64_loc_reg(list,resloc,joinreg64(r,r2));
-                     end
-                    else
-{$endif cpu64bit}
-                     begin
-                       r:=cg.getregisterint(list,resloc.size);
-                       cg.a_load_loc_reg(list,resloc.size,resloc,r);
-                     end;
-                   end
-               end;
-           end;
-         end;
-      end;
-
-
-    procedure geninlineentrycode(list:TAAsmoutput;stackframe:longint);
-      begin
-        { initialize return value }
-        initretvalue(list);
-
-        current_procinfo.procdef.localst.foreach_static({$ifndef TP}@{$endif}initialize_data,list);
-
-        { initialisizes temp. ansi/wide string data }
-        inittempvariables(list);
-
-        { initialize ansi/widesstring para's }
-        if assigned(current_procinfo.procdef.parast) then
-          current_procinfo.procdef.parast.foreach_static({$ifndef TP}@{$endif}init_paras,list);
-
-        { generate copies of call by value parameters }
-        if not(po_assembler in current_procinfo.procdef.procoptions) then
-          current_procinfo.procdef.parast.foreach_static({$ifndef TP}@{$endif}copyvalueparas,list);
-
-        load_regvars(list,nil);
-      end;
-
-
-   procedure geninlineexitcode(list:TAAsmoutput;inlined:boolean);
-      var
-        usesacc,
-        usesacchi,
-        usesfpu : boolean;
-      begin
-        if aktexitlabel.is_used then
-          cg.a_label(list,aktexitlabel);
-
-        cleanup_regvars(list);
-
-        { finalize temporary data }
-        finalizetempvariables(list);
-
-        current_procinfo.procdef.localst.foreach_static({$ifndef TP}@{$endif}finalize_data,list);
-
-        { finalize paras data }
-        if assigned(current_procinfo.procdef.parast) then
-          current_procinfo.procdef.parast.foreach_static({$ifndef TP}@{$endif}final_paras,list);
-
-        { handle return value, this is not done for assembler routines when
-          they didn't reference the result variable }
-        if not(po_assembler in current_procinfo.procdef.procoptions) or
-           (assigned(current_procinfo.procdef.funcretsym) and
-            (tvarsym(current_procinfo.procdef.funcretsym).refcount>1)) then
-          begin
-            if (current_procinfo.procdef.proctypeoption=potype_constructor) then
-             internalerror(200305263);
-//            load_inlined_return_value(list);
-             load_return_value(list,usesacc,usesacchi,usesfpu)
-          end;
-
-        cleanup_regvars(list);
-      end;
-*)
-
-
 {****************************************************************************
 {****************************************************************************
                                Const Data
                                Const Data
 ****************************************************************************}
 ****************************************************************************}
@@ -1853,7 +1761,7 @@ implementation
                     tg.GetLocal(list,getvaluesize,vartype.def,localloc.reference);
                     tg.GetLocal(list,getvaluesize,vartype.def,localloc.reference);
                     if cs_asm_source in aktglobalswitches then
                     if cs_asm_source in aktglobalswitches then
                       list.concat(Tai_comment.Create(strpnew('Local '+realname+' located at '+
                       list.concat(Tai_comment.Create(strpnew('Local '+realname+' located at '+
-                          std_regname(localloc.reference.index)+tostr_with_plus(localloc.reference.offset))));
+                          std_regname(localloc.reference.base)+tostr_with_plus(localloc.reference.offset))));
                   end;
                   end;
               end;
               end;
             sym:=tsym(sym.indexnext);
             sym:=tsym(sym.indexnext);
@@ -1912,7 +1820,7 @@ implementation
                   begin
                   begin
                     if not(po_assembler in current_procinfo.procdef.procoptions) then
                     if not(po_assembler in current_procinfo.procdef.procoptions) then
                       begin
                       begin
-                        case paraitem.paraloc[calleeside].loc of
+                        case paraitem.paraloc[calleeside].location^.loc of
                           LOC_MMREGISTER,
                           LOC_MMREGISTER,
                           LOC_FPUREGISTER,
                           LOC_FPUREGISTER,
                           LOC_REGISTER:
                           LOC_REGISTER:
@@ -1960,17 +1868,17 @@ implementation
                             end;
                             end;
 {$endif powerpc}
 {$endif powerpc}
                           else
                           else
-                            localloc:=paraitem.paraloc[calleeside];
+                            paraitem.paraloc[calleeside].get_location(localloc);
                         end;
                         end;
                       end
                       end
                     else
                     else
-                      localloc:=paraitem.paraloc[calleeside];
+                      paraitem.paraloc[calleeside].get_location(localloc);
                     if cs_asm_source in aktglobalswitches then
                     if cs_asm_source in aktglobalswitches then
                       case localloc.loc of
                       case localloc.loc of
                         LOC_REFERENCE :
                         LOC_REFERENCE :
                           begin
                           begin
                             list.concat(Tai_comment.Create(strpnew('Para '+realname+' located at '+
                             list.concat(Tai_comment.Create(strpnew('Para '+realname+' located at '+
-                                std_regname(localloc.reference.index)+tostr_with_plus(localloc.reference.offset))));
+                                std_regname(localloc.reference.base)+tostr_with_plus(localloc.reference.offset))));
                           end;
                           end;
                       end;
                       end;
                   end;
                   end;
@@ -1980,13 +1888,15 @@ implementation
       end;
       end;
 
 
 
 
-    procedure gen_alloc_inline_parast(list:TAAsmoutput;st:tparasymtable);
+    procedure gen_alloc_inline_parast(list:TAAsmoutput;pd:tprocdef);
       var
       var
         sym : tsym;
         sym : tsym;
+        calleeparaloc,
+        callerparaloc : pcgparalocation;
       begin
       begin
-        if (po_assembler in current_procinfo.procdef.procoptions) then
+        if (po_assembler in pd.procoptions) then
           exit;
           exit;
-        sym:=tsym(st.symindex.first);
+        sym:=tsym(pd.parast.symindex.first);
         while assigned(sym) do
         while assigned(sym) do
           begin
           begin
             if sym.typ=varsym then
             if sym.typ=varsym then
@@ -1997,34 +1907,47 @@ implementation
                     localloc.loc:=LOC_REFERENCE;
                     localloc.loc:=LOC_REFERENCE;
                     localloc.size:=int_cgsize(paramanager.push_size(varspez,vartype.def,pocall_inline));
                     localloc.size:=int_cgsize(paramanager.push_size(varspez,vartype.def,pocall_inline));
                     tg.GetLocal(list,tcgsize2size[localloc.size],vartype.def,localloc.reference);
                     tg.GetLocal(list,tcgsize2size[localloc.size],vartype.def,localloc.reference);
-                    case paraitem.paraloc[calleeside].loc of
-                      LOC_FPUREGISTER:
-                        begin
-                          paraitem.paraloc[calleeside].register := cg.getfpuregister(list,paraitem.paraloc[calleeside].size);
-                          paraitem.paraloc[callerside] := paraitem.paraloc[calleeside];
-                        end;
-                      LOC_REGISTER:
-                        begin
-                          paraitem.paraloc[calleeside].register := cg.getintregister(list,paraitem.paraloc[calleeside].size);
-                          paraitem.paraloc[callerside] := paraitem.paraloc[calleeside];
-                        end;
-                      LOC_MMREGISTER:
-                        begin
-                          paraitem.paraloc[calleeside].register := cg.getmmregister(list,paraitem.paraloc[calleeside].size);
-                          paraitem.paraloc[callerside] := paraitem.paraloc[calleeside];
-                        end;
-                      LOC_REFERENCE:
-                        begin
-                          paraitem.paraloc[calleeside] := localloc;
-                          paraitem.paraloc[callerside] := localloc;
+                    calleeparaloc:=paraitem.paraloc[calleeside].location;
+                    callerparaloc:=paraitem.paraloc[callerside].location;
+                    while assigned(calleeparaloc) do
+                      begin
+                        if not assigned(callerparaloc) then
+                          internalerror(200408281);
+                        if calleeparaloc^.loc<>callerparaloc^.loc then
+                          internalerror(200408282);
+                        case calleeparaloc^.loc of
+                          LOC_FPUREGISTER:
+                            begin
+                              calleeparaloc^.register:=cg.getfpuregister(list,calleeparaloc^.size);
+                              callerparaloc^.register:=calleeparaloc^.register;
+                            end;
+                          LOC_REGISTER:
+                            begin
+                              calleeparaloc^.register:=cg.getintregister(list,calleeparaloc^.size);
+                              callerparaloc^.register:=calleeparaloc^.register;
+                            end;
+                          LOC_MMREGISTER:
+                            begin
+                              calleeparaloc^.register:=cg.getmmregister(list,calleeparaloc^.size);
+                              callerparaloc^.register:=calleeparaloc^.register;
+                            end;
+                          LOC_REFERENCE:
+                            begin
+                              calleeparaloc^.reference.offset := localloc.reference.offset;
+                              calleeparaloc^.reference.index := localloc.reference.base;
+                              callerparaloc^.reference.offset := localloc.reference.offset;
+                              callerparaloc^.reference.index := localloc.reference.base;
+                            end;
                         end;
                         end;
-                    end;
+                        calleeparaloc:=calleeparaloc^.next;
+                        callerparaloc:=callerparaloc^.next;
+                      end;
                     if cs_asm_source in aktglobalswitches then
                     if cs_asm_source in aktglobalswitches then
                       begin
                       begin
                         case localloc.loc of
                         case localloc.loc of
                           LOC_REFERENCE :
                           LOC_REFERENCE :
                             list.concat(Tai_comment.Create(strpnew('Para '+realname+' allocated at '+
                             list.concat(Tai_comment.Create(strpnew('Para '+realname+' allocated at '+
-                                std_regname(localloc.reference.index)+tostr_with_plus(localloc.reference.offset))));
+                                std_regname(localloc.reference.base)+tostr_with_plus(localloc.reference.offset))));
                         end;
                         end;
                       end;
                       end;
                   end;
                   end;
@@ -2034,6 +1957,68 @@ implementation
       end;
       end;
 
 
 
 
+    procedure gen_alloc_inline_funcret(list:TAAsmoutput;pd:tprocdef);
+      var
+        sym : tsym;
+        calleeparaloc,
+        callerparaloc : pcgparalocation;
+      begin
+        if not assigned(pd.funcretsym) or
+           (po_assembler in pd.procoptions) then
+          exit;
+        { for localloc <> LOC_REFERENCE, we need regvar support inside inlined procedures }
+        with tvarsym(pd.funcretsym) do
+          begin
+            localloc.loc:=LOC_REFERENCE;
+            localloc.size:=int_cgsize(paramanager.push_size(varspez,vartype.def,pocall_inline));
+            tg.GetLocal(list,tcgsize2size[localloc.size],vartype.def,localloc.reference);
+            calleeparaloc:=pd.funcret_paraloc[calleeside].location;
+            callerparaloc:=pd.funcret_paraloc[callerside].location;
+            while assigned(calleeparaloc) do
+              begin
+                if not assigned(callerparaloc) then
+                  internalerror(200408281);
+                if calleeparaloc^.loc<>callerparaloc^.loc then
+                   internalerror(200408282);
+                 case calleeparaloc^.loc of
+                   LOC_FPUREGISTER:
+                     begin
+                       calleeparaloc^.register:=cg.getfpuregister(list,calleeparaloc^.size);
+                       callerparaloc^.register:=calleeparaloc^.register;
+                     end;
+                   LOC_REGISTER:
+                     begin
+                       calleeparaloc^.register:=cg.getintregister(list,calleeparaloc^.size);
+                       callerparaloc^.register:=calleeparaloc^.register;
+                     end;
+                   LOC_MMREGISTER:
+                     begin
+                       calleeparaloc^.register:=cg.getmmregister(list,calleeparaloc^.size);
+                       callerparaloc^.register:=calleeparaloc^.register;
+                     end;
+                   LOC_REFERENCE:
+                     begin
+                       calleeparaloc^.reference.offset := localloc.reference.offset;
+                       calleeparaloc^.reference.index := localloc.reference.base;
+                       callerparaloc^.reference.offset := localloc.reference.offset;
+                       callerparaloc^.reference.index := localloc.reference.base;
+                     end;
+                 end;
+                 calleeparaloc:=calleeparaloc^.next;
+                 callerparaloc:=callerparaloc^.next;
+               end;
+             if cs_asm_source in aktglobalswitches then
+               begin
+                 case localloc.loc of
+                   LOC_REFERENCE :
+                     list.concat(Tai_comment.Create(strpnew('Funcret '+realname+' allocated at '+
+                         std_regname(localloc.reference.base)+tostr_with_plus(localloc.reference.offset))));
+                 end;
+               end;
+           end;
+      end;
+
+
     procedure gen_free_parast(list:TAAsmoutput;st:tparasymtable);
     procedure gen_free_parast(list:TAAsmoutput;st:tparasymtable);
       var
       var
         sym : tsym;
         sym : tsym;
@@ -2053,7 +2038,7 @@ implementation
                         tg.UngetLocal(list,localloc.reference);
                         tg.UngetLocal(list,localloc.reference);
                       LOC_REGISTER :
                       LOC_REGISTER :
                         begin
                         begin
-                          if localloc.register<>paraitem.paraloc[calleeside].register then
+                          if localloc.register<>paraitem.paraloc[calleeside].location^.register then
                             begin
                             begin
 {$ifndef cpu64bit}
 {$ifndef cpu64bit}
                               if localloc.size in [OS_64,OS_S64] then
                               if localloc.size in [OS_64,OS_S64] then
@@ -2148,12 +2133,27 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.215  2004-09-14 16:33:46  peter
+  Revision 1.216  2004-09-21 17:25:12  peter
+    * paraloc branch merged
+
+  Revision 1.215  2004/09/14 16:33:46  peter
     * release localsymtables when module is compiled
     * release localsymtables when module is compiled
 
 
   Revision 1.214  2004/09/13 20:30:05  peter
   Revision 1.214  2004/09/13 20:30:05  peter
     * finalize all (also procedure local) typedconst at unit finalization
     * finalize all (also procedure local) typedconst at unit finalization
 
 
+  Revision 1.213.4.3  2004/09/20 20:46:34  peter
+    * register allocation optimized for 64bit loading of parameters
+      and return values
+
+  Revision 1.213.4.2  2004/09/17 17:19:26  peter
+    * fixed 64 bit unaryminus for sparc
+    * fixed 64 bit inlining
+    * signness of not operation
+
+  Revision 1.213.4.1  2004/08/31 20:43:06  peter
+    * paraloc patch
+
   Revision 1.213  2004/08/23 11:00:06  michael
   Revision 1.213  2004/08/23 11:00:06  michael
   + Patch from Peter to fix debuginfo in constructor.
   + Patch from Peter to fix debuginfo in constructor.
 
 

+ 14 - 8
compiler/nobj.pas

@@ -156,7 +156,7 @@ implementation
        gdb,
        gdb,
 {$endif GDB}
 {$endif GDB}
        aasmcpu,
        aasmcpu,
-       cpubase,cgbase,
+       cpubase,cgbase,parabase,
        cgutils,cgobj
        cgutils,cgobj
        ;
        ;
 
 
@@ -1346,7 +1346,7 @@ implementation
     var
     var
       hsym : tsym;
       hsym : tsym;
       href : treference;
       href : treference;
-      locpara : tparalocation;
+      paraloc : tcgparalocation;
     begin
     begin
       { calculate the parameter info for the procdef }
       { calculate the parameter info for the procdef }
       if not procdef.has_paraloc_info then
       if not procdef.has_paraloc_info then
@@ -1359,16 +1359,16 @@ implementation
              (hsym.typ=varsym) and
              (hsym.typ=varsym) and
              assigned(tvarsym(hsym).paraitem)) then
              assigned(tvarsym(hsym).paraitem)) then
         internalerror(200305251);
         internalerror(200305251);
-      locpara:=tvarsym(hsym).paraitem.paraloc[callerside];
-      case locpara.loc of
+      paraloc:=tvarsym(hsym).paraitem.paraloc[callerside].location^;
+      case paraloc.loc of
         LOC_REGISTER:
         LOC_REGISTER:
-          cg.a_op_const_reg(exprasmlist,OP_SUB,locpara.size,ioffset,locpara.register);
+          cg.a_op_const_reg(exprasmlist,OP_SUB,paraloc.size,ioffset,paraloc.register);
         LOC_REFERENCE:
         LOC_REFERENCE:
           begin
           begin
              { offset in the wrapper needs to be adjusted for the stored
              { offset in the wrapper needs to be adjusted for the stored
                return address }
                return address }
-             reference_reset_base(href,locpara.reference.index,locpara.reference.offset+sizeof(aint));
-             cg.a_op_const_ref(exprasmlist,OP_SUB,locpara.size,ioffset,href);
+             reference_reset_base(href,paraloc.reference.index,paraloc.reference.offset+sizeof(aint));
+             cg.a_op_const_ref(exprasmlist,OP_SUB,paraloc.size,ioffset,href);
           end
           end
         else
         else
           internalerror(200309189);
           internalerror(200309189);
@@ -1381,9 +1381,15 @@ initialization
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.75  2004-09-13 20:31:07  peter
+  Revision 1.76  2004-09-21 17:25:12  peter
+    * paraloc branch merged
+
+  Revision 1.75  2004/09/13 20:31:07  peter
     * fixed and cleanup of overriding non-visible methods
     * fixed and cleanup of overriding non-visible methods
 
 
+  Revision 1.74.4.1  2004/08/31 20:43:06  peter
+    * paraloc patch
+
   Revision 1.74  2004/07/09 22:17:32  peter
   Revision 1.74  2004/07/09 22:17:32  peter
     * revert has_localst patch
     * revert has_localst patch
     * replace aktstaticsymtable/aktglobalsymtable with current_module
     * replace aktstaticsymtable/aktglobalsymtable with current_module

+ 13 - 5
compiler/options.pas

@@ -727,11 +727,16 @@ begin
                   exclude(initglobalswitches,cs_gdb_lineinfo);
                   exclude(initglobalswitches,cs_gdb_lineinfo);
                   exclude(initglobalswitches,cs_checkpointer);
                   exclude(initglobalswitches,cs_checkpointer);
                 end
                 end
-{$ifdef GDB}
                else
                else
                 begin
                 begin
+{$ifdef GDB}
                   include(initmoduleswitches,cs_debuginfo);
                   include(initmoduleswitches,cs_debuginfo);
+{$else GDB}
+                  Message(option_no_debug_support);
+                  Message(option_no_debug_support_recompile_fpc);
+{$endif GDB}
                 end;
                 end;
+{$ifdef GDB}
                if not RelocSectionSetExplicitly then
                if not RelocSectionSetExplicitly then
                  RelocSection:=false;
                  RelocSection:=false;
                j:=1;
                j:=1;
@@ -792,9 +797,6 @@ begin
                    end;
                    end;
                    inc(j);
                    inc(j);
                  end;
                  end;
-{$else GDB}
-                 Message(option_no_debug_support);
-                 Message(option_no_debug_support_recompile_fpc);
 {$endif GDB}
 {$endif GDB}
              end;
              end;
 
 
@@ -2087,7 +2089,10 @@ finalization
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.142  2004-09-16 16:31:53  peter
+  Revision 1.143  2004-09-21 17:25:12  peter
+    * paraloc branch merged
+
+  Revision 1.142  2004/09/16 16:31:53  peter
     * Use FExpand on paths passed to compiler
     * Use FExpand on paths passed to compiler
 
 
   Revision 1.141  2004/09/10 21:00:23  jonas
   Revision 1.141  2004/09/10 21:00:23  jonas
@@ -2097,6 +2102,9 @@ end.
   Revision 1.140  2004/09/08 11:23:31  michael
   Revision 1.140  2004/09/08 11:23:31  michael
   + Check if outputdir exists,  Fix exitcode when displaying help pages
   + Check if outputdir exists,  Fix exitcode when displaying help pages
 
 
+  Revision 1.139.4.1  2004/09/19 20:53:33  peter
+    * fixed compile without gdb
+
   Revision 1.139  2004/08/27 21:59:26  peter
   Revision 1.139  2004/08/27 21:59:26  peter
   browser disabled
   browser disabled
   uf_local_symtable ppu flag when a localsymtable is stored
   uf_local_symtable ppu flag when a localsymtable is stored

+ 205 - 0
compiler/parabase.pas

@@ -0,0 +1,205 @@
+{
+    $Id$
+    Copyright (c) 2002 by Florian Klaempfl
+
+    Generic calling convention handling
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ ****************************************************************************
+}
+unit parabase;
+
+{$i fpcdefs.inc}
+
+  interface
+
+    uses
+       cclasses,globtype,
+       cpubase,cgbase;
+
+    type
+       { tparamlocation describes where a parameter for a procedure is stored.
+         References are given from the caller's point of view. The usual
+         TLocation isn't used, because contains a lot of unnessary fields.
+       }
+       PCGParaLocation = ^TCGParaLocation;
+       TCGParaLocation = record
+         Next : PCGParaLocation;
+         Size : TCGSize; { size of this location }
+         Loc  : TCGLoc;
+         case TCGLoc of
+           LOC_REFERENCE : (reference : tparareference);
+           LOC_FPUREGISTER,
+           LOC_CFPUREGISTER,
+           LOC_MMREGISTER,
+           LOC_CMMREGISTER,
+           LOC_REGISTER,
+           LOC_CREGISTER : (register : tregister);
+       end;
+
+       TCGPara = object
+          Alignment : ShortInt;
+          Size      : TCGSize;  { Size of the parameter included in all locations }
+          Location  : PCGParalocation;
+          constructor init;
+          destructor  done;
+          procedure   reset;
+          procedure   check_simple_location;
+          function    add_location:pcgparalocation;
+          procedure   get_location(var newloc:tlocation);
+       end;
+
+       tvarargsinfo = (
+         va_uses_float_reg
+       );
+
+       tvarargspara = class(tlinkedlist)
+          varargsinfo : set of tvarargsinfo;
+{$ifdef x86_64}
+          { x86_64 requires %al to contain the no. SSE regs passed }
+          mmregsused  : longint;
+{$endif x86_64}
+       end;
+
+
+
+implementation
+
+    uses
+      systems,verbose;
+
+
+{****************************************************************************
+                                TCGPara
+****************************************************************************}
+
+    constructor tcgpara.init;
+      begin
+        alignment:=0;
+        size:=OS_NO;
+        location:=nil;
+      end;
+
+
+    destructor tcgpara.done;
+      begin
+        reset;
+      end;
+
+
+    procedure tcgpara.reset;
+      var
+        hlocation : pcgparalocation;
+      begin
+        while assigned(location) do
+          begin
+            hlocation:=location^.next;
+            dispose(location);
+            location:=hlocation;
+          end;
+        alignment:=0;
+        size:=OS_NO;
+      end;
+
+
+    function tcgpara.add_location:pcgparalocation;
+      var
+        prevlocation,
+        hlocation : pcgparalocation;
+      begin
+        prevlocation:=nil;
+        hlocation:=location;
+        while assigned(hlocation) do
+          begin
+            prevlocation:=hlocation;
+            hlocation:=hlocation^.next;
+          end;
+        new(hlocation);
+        Fillchar(hlocation^,sizeof(tcgparalocation),0);
+        if assigned(prevlocation) then
+          prevlocation^.next:=hlocation
+        else
+          location:=hlocation;
+        result:=hlocation;
+      end;
+
+
+    procedure tcgpara.check_simple_location;
+      begin
+        if not assigned(location) then
+          internalerror(200408161);
+        if assigned(location^.next) then
+          internalerror(200408162);
+      end;
+
+
+    procedure tcgpara.get_location(var newloc:tlocation);
+      begin
+        if not assigned(location) then
+          internalerror(200408205);
+        fillchar(newloc,sizeof(newloc),0);
+        newloc.loc:=location^.loc;
+        newloc.size:=size;
+        case location^.loc of
+          LOC_REGISTER :
+            begin
+{$ifndef cpu64bit}
+              if size in [OS_64,OS_S64] then
+                begin
+                  if not assigned(location^.next) then
+                    internalerror(200408206);
+                  if (location^.next^.loc<>LOC_REGISTER) then
+                    internalerror(200408207);
+                  if (target_info.endian = ENDIAN_BIG) then
+                    begin
+                      newloc.registerhigh:=location^.register;
+                      newloc.registerlow:=location^.next^.register;
+                    end
+                  else
+                    begin
+                      newloc.registerlow:=location^.register;
+                      newloc.registerhigh:=location^.next^.register;
+                    end;
+                end
+              else
+{$endif}
+                newloc.register:=location^.register;
+            end;
+          LOC_FPUREGISTER,
+          LOC_MMREGISTER :
+            newloc.register:=location^.register;
+          LOC_REFERENCE :
+            begin
+              newloc.reference.base:=location^.reference.index;
+              newloc.reference.offset:=location^.reference.offset;
+            end;
+        end;
+      end;
+
+end.
+
+{
+   $Log$
+   Revision 1.2  2004-09-21 17:25:12  peter
+     * paraloc branch merged
+
+   Revision 1.1.2.2  2004/09/14 19:09:37  jonas
+     * fixed typo in IE check
+
+   Revision 1.1.2.1  2004/09/02 15:47:58  peter
+     * missing file
+
+}
+

+ 124 - 197
compiler/paramgr.pas

@@ -31,22 +31,11 @@ unit paramgr;
     uses
     uses
        cclasses,globtype,
        cclasses,globtype,
        cpubase,cgbase,
        cpubase,cgbase,
+       parabase,
        aasmtai,
        aasmtai,
        symconst,symtype,symdef;
        symconst,symtype,symdef;
 
 
     type
     type
-       tvarargsinfo = (
-         va_uses_float_reg
-       );
-
-       tvarargspara = class(tlinkedlist)
-          varargsinfo : set of tvarargsinfo;
-{$ifdef x86_64}
-          { x86_64 requires %al to contain the no. SSE regs passed }
-          mmregsused  : longint;
-{$endif x86_64}
-       end;
-
        {# This class defines some methods to take care of routine
        {# This class defines some methods to take care of routine
           parameters. It should be overriden for each new processor
           parameters. It should be overriden for each new processor
        }
        }
@@ -87,21 +76,22 @@ unit paramgr;
           function get_volatile_registers_fpu(calloption : tproccalloption):tcpuregisterset;virtual;
           function get_volatile_registers_fpu(calloption : tproccalloption):tcpuregisterset;virtual;
           function get_volatile_registers_flags(calloption : tproccalloption):tcpuregisterset;virtual;
           function get_volatile_registers_flags(calloption : tproccalloption):tcpuregisterset;virtual;
           function get_volatile_registers_mm(calloption : tproccalloption):tcpuregisterset;virtual;
           function get_volatile_registers_mm(calloption : tproccalloption):tcpuregisterset;virtual;
-          function getintparaloc(calloption : tproccalloption; nr : longint) : tparalocation;virtual;abstract;
+
+          procedure getintparaloc(calloption : tproccalloption; nr : longint;var cgpara:TCGPara);virtual;abstract;
 
 
           {# allocate a parameter location created with create_paraloc_info
           {# allocate a parameter location created with create_paraloc_info
 
 
             @param(list Current assembler list)
             @param(list Current assembler list)
             @param(loc Parameter location)
             @param(loc Parameter location)
           }
           }
-          procedure allocparaloc(list: taasmoutput; const loc: tparalocation); virtual;
+          procedure allocparaloc(list: taasmoutput; const cgpara: TCGPara); virtual;
 
 
-          {# free a parameter location allocated with allocparaloc
+          {# free a parameter location allocated with alloccgpara
 
 
             @param(list Current assembler list)
             @param(list Current assembler list)
             @param(loc Parameter location)
             @param(loc Parameter location)
           }
           }
-          procedure freeparaloc(list: taasmoutput; const loc: tparalocation); virtual;
+          procedure freeparaloc(list: taasmoutput; const cgpara: TCGPara); virtual;
 
 
           { This is used to populate the location information on all parameters
           { This is used to populate the location information on all parameters
             for the routine as seen in either the caller or the callee. It returns
             for the routine as seen in either the caller or the callee. It returns
@@ -121,11 +111,8 @@ unit paramgr;
           }
           }
           function  create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargspara):longint;virtual;abstract;
           function  create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargspara):longint;virtual;abstract;
 
 
-          { Return the location of the low and high part of a 64bit parameter }
-          procedure splitparaloc64(const locpara:tparalocation;var loclopara,lochipara:tparalocation);virtual;
-
-          procedure alloctempregs(list: taasmoutput;var locpara:tparalocation);virtual;
-          procedure alloctempparaloc(list: taasmoutput;calloption : tproccalloption;paraitem : tparaitem;var locpara:tparalocation);virtual;
+          procedure createtempparaloc(list: taasmoutput;calloption : tproccalloption;paraitem : tparaitem;var cgpara:TCGPara);virtual;
+          procedure duplicateparaloc(list: taasmoutput;calloption : tproccalloption;paraitem : tparaitem;var cgpara:TCGPara);
 
 
           function parseparaloc(paraitem : tparaitem;const s : string) : boolean;virtual;abstract;
           function parseparaloc(paraitem : tparaitem;const s : string) : boolean;virtual;abstract;
        end;
        end;
@@ -138,8 +125,8 @@ unit paramgr;
 implementation
 implementation
 
 
     uses
     uses
-       cpuinfo,systems,
-       cgutils,cgobj,tgobj,
+       systems,
+       cgobj,tgobj,
        defutil,verbose;
        defutil,verbose;
 
 
     { true if uses a parameter as return value }
     { true if uses a parameter as return value }
@@ -301,201 +288,135 @@ implementation
       end;
       end;
 
 
 
 
-    procedure tparamanager.allocparaloc(list: taasmoutput; const loc: tparalocation);
+    procedure tparamanager.allocparaloc(list: taasmoutput; const cgpara: TCGPara);
+      var
+        paraloc : pcgparalocation;
       begin
       begin
-        case loc.loc of
-          LOC_REGISTER,
-          LOC_CREGISTER:
-            begin
-              if getsupreg(loc.register)<first_int_imreg then
-                cg.getexplicitregister(list,loc.register);
-            end;
-          LOC_FPUREGISTER,
-          LOC_CFPUREGISTER:
-            begin
-              if getsupreg(loc.register)<first_fpu_imreg then
-                cg.getexplicitregister(list,loc.register);
-            end;
-          LOC_MMREGISTER,
-          LOC_CMMREGISTER :
-            begin
-              if getsupreg(loc.register)<first_mm_imreg then
-                cg.getexplicitregister(list,loc.register);
-            end;
-          LOC_REFERENCE,
-          LOC_CREFERENCE :
-            { do nothing by default, most of the time it's the framepointer }
-          else
-            internalerror(200306091);
-        end;
-        case loc.lochigh of
-          LOC_INVALID :
-            ;
-          LOC_REGISTER,
-          LOC_CREGISTER,
-          LOC_FPUREGISTER,
-          LOC_CFPUREGISTER,
-          LOC_MMREGISTER,
-          LOC_CMMREGISTER :
-            begin
-              { NR_NO means we don't need to allocate the parameter.
-                This is used for inlining parameters which allocates
-                the parameters in gen_alloc_parast (PFV) }
-              if loc.registerhigh<>NR_NO then
-                cg.getexplicitregister(list,loc.registerhigh);
+        paraloc:=cgpara.location;
+        while assigned(paraloc) do
+          begin
+            case paraloc^.loc of
+              LOC_REGISTER,
+              LOC_CREGISTER:
+                begin
+                  if getsupreg(paraloc^.register)<first_int_imreg then
+                    cg.getexplicitregister(list,paraloc^.register);
+                end;
+              LOC_FPUREGISTER,
+              LOC_CFPUREGISTER:
+                begin
+                  if getsupreg(paraloc^.register)<first_fpu_imreg then
+                    cg.getexplicitregister(list,paraloc^.register);
+                end;
+              LOC_MMREGISTER,
+              LOC_CMMREGISTER :
+                begin
+                  if getsupreg(paraloc^.register)<first_mm_imreg then
+                    cg.getexplicitregister(list,paraloc^.register);
+                end;
             end;
             end;
-          else
-            internalerror(200306092);
-        end;
+            paraloc:=paraloc^.next;
+          end;
       end;
       end;
 
 
 
 
-    procedure tparamanager.freeparaloc(list: taasmoutput; const loc: tparalocation);
+    procedure tparamanager.freeparaloc(list: taasmoutput; const cgpara: TCGPara);
       var
       var
+        paraloc : Pcgparalocation;
+{$ifdef cputargethasfixedstack}
         href : treference;
         href : treference;
+{$endif cputargethasfixedstack}
       begin
       begin
-        case loc.loc of
-          LOC_REGISTER, LOC_CREGISTER:
-            begin
-{$ifndef cpu64bit}
-              if (loc.size in [OS_64,OS_S64,OS_F64]) then
+        paraloc:=cgpara.location;
+        while assigned(paraloc) do
+          begin
+            case paraloc^.loc of
+              LOC_REGISTER,
+              LOC_CREGISTER,
+              LOC_FPUREGISTER,
+              LOC_CFPUREGISTER,
+              LOC_MMREGISTER,
+              LOC_CMMREGISTER :
+                cg.ungetregister(list,paraloc^.register);
+              LOC_REFERENCE,
+              LOC_CREFERENCE :
                 begin
                 begin
-                  cg.ungetregister(list,loc.registerhigh);
-                  cg.ungetregister(list,loc.registerlow);
-                end
-              else
-{$endif cpu64bit}
-                cg.ungetregister(list,loc.register);
-            end;
-          LOC_MMREGISTER, LOC_CMMREGISTER,
-          LOC_FPUREGISTER, LOC_CFPUREGISTER:
-            cg.ungetregister(list,loc.register);
-          LOC_REFERENCE,LOC_CREFERENCE:
-            begin
 {$ifdef cputargethasfixedstack}
 {$ifdef cputargethasfixedstack}
-              reference_reset_base(href,loc.reference.index,loc.reference.offset);
-              tg.ungettemp(list,href);
+                  { don't use reference_reset_base, because that will depend on cgobj }
+                  fillchar(href,sizeof(href),0);
+                  href.base:=paraloc^.reference.index;
+                  href.offset:=paraloc^.reference.offset;
+                  tg.ungettemp(list,href);
 {$endif cputargethasfixedstack}
 {$endif cputargethasfixedstack}
+                end;
             end;
             end;
-          else
-            internalerror(200306093);
-        end;
-        case loc.lochigh of
-          LOC_INVALID :
-            ;
-          LOC_REGISTER,
-          LOC_CREGISTER,
-          LOC_FPUREGISTER,
-          LOC_CFPUREGISTER,
-          LOC_MMREGISTER,
-          LOC_CMMREGISTER :
-            cg.ungetregister(list,loc.register);
-          else
-            internalerror(200306094);
-        end;
-      end;
-
-
-    procedure tparamanager.splitparaloc64(const locpara:tparalocation;var loclopara,lochipara:tparalocation);
-      begin
-        lochipara:=locpara;
-        loclopara:=locpara;
-        case locpara.size of
-          OS_S128 :
-            begin
-              lochipara.size:=OS_S64;
-              loclopara.size:=OS_64;
-            end;
-          OS_128 :
-            begin
-              lochipara.size:=OS_64;
-              loclopara.size:=OS_64;
-            end;
-          OS_S64 :
-            begin
-              lochipara.size:=OS_S32;
-              loclopara.size:=OS_32;
-            end;
-          OS_64 :
-            begin
-              lochipara.size:=OS_32;
-              loclopara.size:=OS_32;
-            end;
-          else
-            internalerror(200307023);
-        end;
-        loclopara.lochigh:=LOC_INVALID;
-        lochipara.lochigh:=LOC_INVALID;
-        case locpara.loc of
-           LOC_REGISTER,
-           LOC_CREGISTER,
-           LOC_FPUREGISTER,
-           LOC_CFPUREGISTER,
-           LOC_MMREGISTER,
-           LOC_CMMREGISTER :
-             begin
-               if locpara.lochigh=LOC_INVALID then
-                 internalerror(200402061);
-               loclopara.register:=locpara.registerlow;
-               lochipara.register:=locpara.registerhigh;
-             end;
-           LOC_REFERENCE:
-             begin
-               if target_info.endian=endian_big then
-                 inc(loclopara.reference.offset,tcgsize2size[loclopara.size])
-               else
-                 inc(lochipara.reference.offset,tcgsize2size[loclopara.size]);
-             end;
-           else
-             internalerror(200307024);
-        end;
+            paraloc:=paraloc^.next;
+          end;
       end;
       end;
 
 
 
 
-    procedure tparamanager.alloctempregs(list: taasmoutput;var locpara:tparalocation);
+    procedure tparamanager.createtempparaloc(list: taasmoutput;calloption : tproccalloption;paraitem : tparaitem;var cgpara:TCGPara);
       var
       var
-        cgsize : tcgsize;
+        href : treference;
+        len  : aint;
+        paraloc,
+        newparaloc : pcgparalocation;
       begin
       begin
-        if locpara.lochigh<>LOC_INVALID then
-          cgsize:=OS_INT
-        else
-          cgsize:=locpara.size;
-        case locpara.loc of
-          LOC_REGISTER:
-            locpara.register:=cg.getintregister(list,cgsize);
-          LOC_FPUREGISTER:
-            locpara.register:=cg.getfpuregister(list,cgsize);
-          LOC_MMREGISTER:
-            locpara.register:=cg.getmmregister(list,cgsize);
-          else
-            internalerror(200308123);
-        end;
-        case locpara.lochigh of
-          LOC_INVALID:
-            ;
-          LOC_REGISTER:
-            locpara.registerhigh:=cg.getintregister(list,cgsize);
-          LOC_FPUREGISTER:
-            locpara.registerhigh:=cg.getfpuregister(list,cgsize);
-          LOC_MMREGISTER:
-            locpara.registerhigh:=cg.getmmregister(list,cgsize);
-          else
-            internalerror(200308124);
-        end;
+        cgpara.reset;
+        cgpara.size:=paraitem.paraloc[callerside].size;
+        cgpara.alignment:=paraitem.paraloc[callerside].alignment;
+        paraloc:=paraitem.paraloc[callerside].location;
+        while assigned(paraloc) do
+          begin
+            if paraloc^.size=OS_NO then
+              len:=push_size(paraitem.paratyp,paraitem.paratype.def,calloption)
+            else
+              len:=tcgsize2size[paraloc^.size];
+            newparaloc:=cgpara.add_location;
+            newparaloc^.size:=paraloc^.size;
+{$warning maybe release this optimization for all targets?}
+{$ifdef sparc}
+            { Does it fit a register? }
+            if len<=sizeof(aint) then
+              newparaloc^.loc:=LOC_REGISTER
+            else
+{$endif sparc}
+              newparaloc^.loc:=paraloc^.loc;
+            case newparaloc^.loc of
+              LOC_REGISTER :
+                newparaloc^.register:=cg.getintregister(list,paraloc^.size);
+              LOC_FPUREGISTER :
+                newparaloc^.register:=cg.getfpuregister(list,paraloc^.size);
+              LOC_MMREGISTER :
+                newparaloc^.register:=cg.getmmregister(list,paraloc^.size);
+              LOC_REFERENCE :
+                begin
+                  tg.gettemp(list,len,tt_persistent,href);
+                  newparaloc^.reference.index:=href.base;
+                  newparaloc^.reference.offset:=href.offset;
+                end;
+            end;
+            paraloc:=paraloc^.next;
+          end;
       end;
       end;
 
 
 
 
-    procedure tparamanager.alloctempparaloc(list: taasmoutput;calloption : tproccalloption;paraitem : tparaitem;var locpara:tparalocation);
+    procedure tparamanager.duplicateparaloc(list: taasmoutput;calloption : tproccalloption;paraitem : tparaitem;var cgpara:TCGPara);
       var
       var
-        href : treference;
-        l    : aint;
+        paraloc,
+        newparaloc : pcgparalocation;
       begin
       begin
-        l:=push_size(paraitem.paratyp,paraitem.paratype.def,calloption);
-        tg.gettemp(list,l,tt_persistent,href);
-        locpara.loc:=LOC_REFERENCE;
-        locpara.lochigh:=LOC_INVALID;
-        locpara.reference.index:=href.base;
-        locpara.reference.offset:=href.offset;
+        cgpara.reset;
+        cgpara.size:=paraitem.paraloc[callerside].size;
+        cgpara.alignment:=paraitem.paraloc[callerside].alignment;
+        paraloc:=paraitem.paraloc[callerside].location;
+        while assigned(paraloc) do
+          begin
+            newparaloc:=cgpara.add_location;
+            move(paraloc^,newparaloc^,sizeof(newparaloc^));
+            newparaloc^.next:=nil;
+            paraloc:=paraloc^.next;
+          end;
       end;
       end;
 
 
 
 
@@ -515,7 +436,13 @@ end.
 
 
 {
 {
    $Log$
    $Log$
-   Revision 1.77  2004-07-09 23:41:04  jonas
+   Revision 1.78  2004-09-21 17:25:12  peter
+     * paraloc branch merged
+
+   Revision 1.77.4.1  2004/08/31 20:43:06  peter
+     * paraloc patch
+
+   Revision 1.77  2004/07/09 23:41:04  jonas
      * support register parameters for inlined procedures + some inline
      * support register parameters for inlined procedures + some inline
        cleanups
        cleanups
 
 

+ 55 - 41
compiler/powerpc/cgcpu.pas

@@ -30,7 +30,8 @@ unit cgcpu;
        globtype,symtype,
        globtype,symtype,
        cgbase,cgobj,
        cgbase,cgobj,
        aasmbase,aasmcpu,aasmtai,
        aasmbase,aasmcpu,aasmtai,
-       cpubase,cpuinfo,node,cg64f32,rgcpu;
+       cpubase,cpuinfo,node,cg64f32,rgcpu,
+       parabase;
 
 
     type
     type
       tcgppc = class(tcg)
       tcgppc = class(tcg)
@@ -44,9 +45,9 @@ unit cgcpu;
         { left to right), this allows to move the parameter to    }
         { left to right), this allows to move the parameter to    }
         { register, if the cpu supports register calling          }
         { register, if the cpu supports register calling          }
         { conventions                                             }
         { conventions                                             }
-        procedure a_param_const(list : taasmoutput;size : tcgsize;a : aint;const locpara : tparalocation);override;
-        procedure a_param_ref(list : taasmoutput;size : tcgsize;const r : treference;const locpara : tparalocation);override;
-        procedure a_paramaddr_ref(list : taasmoutput;const r : treference;const locpara : tparalocation);override;
+        procedure a_param_const(list : taasmoutput;size : tcgsize;a : aint;const paraloc : tcgpara);override;
+        procedure a_param_ref(list : taasmoutput;size : tcgsize;const r : treference;const paraloc : tcgpara);override;
+        procedure a_paramaddr_ref(list : taasmoutput;const r : treference;const paraloc : tcgpara);override;
 
 
 
 
         procedure a_call_name(list : taasmoutput;const s : string);override;
         procedure a_call_name(list : taasmoutput;const s : string);override;
@@ -97,7 +98,7 @@ unit cgcpu;
         procedure g_save_standard_registers(list:Taasmoutput);override;
         procedure g_save_standard_registers(list:Taasmoutput);override;
         procedure g_restore_standard_registers(list:Taasmoutput);override;
         procedure g_restore_standard_registers(list:Taasmoutput);override;
         procedure g_save_all_registers(list : taasmoutput);override;
         procedure g_save_all_registers(list : taasmoutput);override;
-        procedure g_restore_all_registers(list : taasmoutput;const funcretparaloc:tparalocation);override;
+        procedure g_restore_all_registers(list : taasmoutput;const funcretparaloc:tcgpara);override;
 
 
         procedure a_jmp_cond(list : taasmoutput;cond : TOpCmp;l: tasmlabel);
         procedure a_jmp_cond(list : taasmoutput;cond : TOpCmp;l: tasmlabel);
 
 
@@ -234,18 +235,19 @@ const
       end;
       end;
 
 
 
 
-    procedure tcgppc.a_param_const(list : taasmoutput;size : tcgsize;a : aint;const locpara : tparalocation);
+    procedure tcgppc.a_param_const(list : taasmoutput;size : tcgsize;a : aint;const paraloc : tcgpara);
       var
       var
         ref: treference;
         ref: treference;
       begin
       begin
-        case locpara.loc of
+        paraloc.check_simple_location;
+        case paraloc.location^.loc of
           LOC_REGISTER,LOC_CREGISTER:
           LOC_REGISTER,LOC_CREGISTER:
-            a_load_const_reg(list,size,a,locpara.register);
+            a_load_const_reg(list,size,a,paraloc.location^.register);
           LOC_REFERENCE:
           LOC_REFERENCE:
             begin
             begin
                reference_reset(ref);
                reference_reset(ref);
-               ref.base:=locpara.reference.index;
-               ref.offset:=locpara.reference.offset;
+               ref.base:=paraloc.location^.reference.index;
+               ref.offset:=paraloc.location^.reference.offset;
                a_load_const_ref(list,size,a,ref);
                a_load_const_ref(list,size,a,ref);
             end;
             end;
           else
           else
@@ -254,21 +256,22 @@ const
       end;
       end;
 
 
 
 
-    procedure tcgppc.a_param_ref(list : taasmoutput;size : tcgsize;const r : treference;const locpara : tparalocation);
+    procedure tcgppc.a_param_ref(list : taasmoutput;size : tcgsize;const r : treference;const paraloc : tcgpara);
 
 
       var
       var
         ref: treference;
         ref: treference;
         tmpreg: tregister;
         tmpreg: tregister;
 
 
       begin
       begin
-        case locpara.loc of
+        paraloc.check_simple_location;
+        case paraloc.location^.loc of
           LOC_REGISTER,LOC_CREGISTER:
           LOC_REGISTER,LOC_CREGISTER:
-            a_load_ref_reg(list,size,size,r,locpara.register);
+            a_load_ref_reg(list,size,size,r,paraloc.location^.register);
           LOC_REFERENCE:
           LOC_REFERENCE:
             begin
             begin
                reference_reset(ref);
                reference_reset(ref);
-               ref.base:=locpara.reference.index;
-               ref.offset:=locpara.reference.offset;
+               ref.base:=paraloc.location^.reference.index;
+               ref.offset:=paraloc.location^.reference.offset;
                tmpreg := rg[R_INTREGISTER].getregister(list,R_SUBWHOLE);
                tmpreg := rg[R_INTREGISTER].getregister(list,R_SUBWHOLE);
                a_load_ref_reg(list,size,size,r,tmpreg);
                a_load_ref_reg(list,size,size,r,tmpreg);
                a_load_reg_ref(list,size,size,tmpreg,ref);
                a_load_reg_ref(list,size,size,tmpreg,ref);
@@ -277,7 +280,7 @@ const
           LOC_FPUREGISTER,LOC_CFPUREGISTER:
           LOC_FPUREGISTER,LOC_CFPUREGISTER:
             case size of
             case size of
                OS_F32, OS_F64:
                OS_F32, OS_F64:
-                 a_loadfpu_ref_reg(list,size,r,locpara.register);
+                 a_loadfpu_ref_reg(list,size,r,paraloc.location^.register);
                else
                else
                  internalerror(2002072801);
                  internalerror(2002072801);
             end;
             end;
@@ -287,28 +290,29 @@ const
       end;
       end;
 
 
 
 
-    procedure tcgppc.a_paramaddr_ref(list : taasmoutput;const r : treference;const locpara : tparalocation);
+    procedure tcgppc.a_paramaddr_ref(list : taasmoutput;const r : treference;const paraloc : tcgpara);
       var
       var
         ref: treference;
         ref: treference;
         tmpreg: tregister;
         tmpreg: tregister;
 
 
       begin
       begin
-         case locpara.loc of
-            LOC_REGISTER,LOC_CREGISTER:
-              a_loadaddr_ref_reg(list,r,locpara.register);
-            LOC_REFERENCE:
-              begin
-                reference_reset(ref);
-                ref.base := locpara.reference.index;
-                ref.offset := locpara.reference.offset;
-                tmpreg := rg[R_INTREGISTER].getregister(list,R_SUBWHOLE);
-                a_loadaddr_ref_reg(list,r,tmpreg);
-                a_load_reg_ref(list,OS_ADDR,OS_ADDR,tmpreg,ref);
-                rg[R_INTREGISTER].ungetregister(list,tmpreg);
-              end;
-            else
-              internalerror(2002080701);
-         end;
+        paraloc.check_simple_location;
+        case paraloc.location^.loc of
+           LOC_REGISTER,LOC_CREGISTER:
+             a_loadaddr_ref_reg(list,r,paraloc.location^.register);
+           LOC_REFERENCE:
+             begin
+               reference_reset(ref);
+               ref.base := paraloc.location^.reference.index;
+               ref.offset := paraloc.location^.reference.offset;
+               tmpreg := rg[R_INTREGISTER].getregister(list,R_SUBWHOLE);
+               a_loadaddr_ref_reg(list,r,tmpreg);
+               a_load_reg_ref(list,OS_ADDR,OS_ADDR,tmpreg,ref);
+               rg[R_INTREGISTER].ungetregister(list,tmpreg);
+             end;
+           else
+             internalerror(2002080701);
+        end;
       end;
       end;
 
 
 
 
@@ -887,7 +891,7 @@ const
          {$warning FIX ME}
          {$warning FIX ME}
        end;
        end;
 
 
-     procedure tcgppc.g_restore_all_registers(list : taasmoutput;const funcretparaloc:tparalocation);
+     procedure tcgppc.g_restore_all_registers(list : taasmoutput;const funcretparaloc:tcgpara);
        begin
        begin
          {$warning FIX ME}
          {$warning FIX ME}
        end;
        end;
@@ -1208,13 +1212,15 @@ const
                 hp:=tparaitem(current_procinfo.procdef.para.first);
                 hp:=tparaitem(current_procinfo.procdef.para.first);
                 while assigned(hp) do
                 while assigned(hp) do
                   begin
                   begin
-                    if (hp.paraloc[calleeside].loc in [LOC_REFERENCE,LOC_CREFERENCE]) then
+                    if (hp.paraloc[calleeside].location^.loc in [LOC_REFERENCE,LOC_CREFERENCE]) then
                       begin
                       begin
+                        if assigned(hp.paraloc[callerside].location^.next) then
+                          internalerror(2004091210);
                         case tvarsym(hp.parasym).localloc.loc of
                         case tvarsym(hp.parasym).localloc.loc of
                           LOC_REFERENCE:
                           LOC_REFERENCE:
                             begin
                             begin
-                              reference_reset_base(href,tvarsym(hp.parasym).localloc.reference.index,tvarsym(hp.parasym).localloc.reference.offset);
-                              reference_reset_base(href2,NR_R12,hp.paraloc[callerside].reference.offset);
+                              reference_reset_base(href,tvarsym(hp.parasym).localloc.reference.base,tvarsym(hp.parasym).localloc.reference.offset);
+                              reference_reset_base(href2,NR_R12,hp.paraloc[callerside].location^.reference.offset);
                               { we can't use functions here which allocate registers (FK)
                               { we can't use functions here which allocate registers (FK)
                                cg.a_load_ref_ref(list,hp.paraloc[calleeside].size,hp.paraloc[calleeside].size,href2,href);
                                cg.a_load_ref_ref(list,hp.paraloc[calleeside].size,hp.paraloc[calleeside].size,href2,href);
                               }
                               }
@@ -1243,12 +1249,12 @@ const
                             end;
                             end;
                           LOC_CREGISTER:
                           LOC_CREGISTER:
                             begin
                             begin
-                              reference_reset_base(href2,NR_R12,hp.paraloc[callerside].reference.offset);
+                              reference_reset_base(href2,NR_R12,hp.paraloc[callerside].location^.reference.offset);
                               cg.a_load_ref_reg(list,hp.paraloc[calleeside].size,hp.paraloc[calleeside].size,href2,tvarsym(hp.parasym).localloc.register);
                               cg.a_load_ref_reg(list,hp.paraloc[calleeside].size,hp.paraloc[calleeside].size,href2,tvarsym(hp.parasym).localloc.register);
                             end;
                             end;
                           LOC_CFPUREGISTER:
                           LOC_CFPUREGISTER:
                             begin
                             begin
-                              reference_reset_base(href2,NR_R12,hp.paraloc[callerside].reference.offset);
+                              reference_reset_base(href2,NR_R12,hp.paraloc[callerside].location^.reference.offset);
                               cg.a_loadfpu_ref_reg(list,hp.paraloc[calleeside].size,href2,tvarsym(hp.parasym).localloc.register);
                               cg.a_loadfpu_ref_reg(list,hp.paraloc[calleeside].size,href2,tvarsym(hp.parasym).localloc.register);
                             end;
                             end;
                           else
                           else
@@ -2429,7 +2435,16 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.176  2004-07-17 14:48:20  jonas
+  Revision 1.177  2004-09-21 17:25:12  peter
+    * paraloc branch merged
+
+  Revision 1.176.4.2  2004/09/18 20:21:08  jonas
+    * fixed ppc, but still needs fix in tgobj
+
+  Revision 1.176.4.1  2004/09/10 11:10:08  florian
+    * first part of ppc fixes
+
+  Revision 1.176  2004/07/17 14:48:20  jonas
     * fixed op_const_reg_reg for (OP_ADD,0,reg1,reg2)
     * fixed op_const_reg_reg for (OP_ADD,0,reg1,reg2)
 
 
   Revision 1.175  2004/07/09 21:45:24  jonas
   Revision 1.175  2004/07/09 21:45:24  jonas
@@ -2463,5 +2478,4 @@ end.
 
 
   Revision 1.168  2004/03/06 21:37:45  florian
   Revision 1.168  2004/03/06 21:37:45  florian
     * fixed ppc compilation
     * fixed ppc compilation
-
 }
 }

+ 196 - 156
compiler/powerpc/cpupara.pas

@@ -19,8 +19,6 @@
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  ****************************************************************************
  ****************************************************************************
 }
 }
-{ PowerPC specific calling conventions are handled by this unit
-}
 unit cpupara;
 unit cpupara;
 
 
 {$i fpcdefs.inc}
 {$i fpcdefs.inc}
@@ -32,14 +30,16 @@ unit cpupara;
        cclasses,
        cclasses,
        aasmtai,
        aasmtai,
        cpubase,cpuinfo,
        cpubase,cpuinfo,
-       symconst,symbase,symtype,symdef,paramgr,cgbase;
+       symconst,symbase,symtype,symdef,
+       paramgr,parabase,cgbase;
 
 
     type
     type
        tppcparamanager = class(tparamanager)
        tppcparamanager = class(tparamanager)
           function get_volatile_registers_int(calloption : tproccalloption):tcpuregisterset;override;
           function get_volatile_registers_int(calloption : tproccalloption):tcpuregisterset;override;
           function get_volatile_registers_fpu(calloption : tproccalloption):tcpuregisterset;override;
           function get_volatile_registers_fpu(calloption : tproccalloption):tcpuregisterset;override;
           function push_addr_param(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean;override;
           function push_addr_param(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean;override;
-          function getintparaloc(calloption : tproccalloption; nr : longint) : tparalocation;override;
+
+          procedure getintparaloc(calloption : tproccalloption; nr : longint;var cgpara:TCGPara);override;
           function create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;override;
           function create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;override;
           function create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargspara):longint;override;
           function create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargspara):longint;override;
 
 
@@ -80,28 +80,35 @@ unit cpupara;
       end;
       end;
 
 
 
 
-    function tppcparamanager.getintparaloc(calloption : tproccalloption; nr : longint) : tparalocation;
-
+    procedure tppcparamanager.getintparaloc(calloption : tproccalloption; nr : longint;var cgpara:TCGPara);
+      var
+        paraloc : pcgparalocation;
       begin
       begin
-         fillchar(result,sizeof(tparalocation),0);
-         result.lochigh:=LOC_INVALID;
-         if nr<1 then
-           internalerror(2002070801)
-         else if nr<=8 then
-           begin
-              result.loc:=LOC_REGISTER;
-              result.register:=newreg(R_INTREGISTER,RS_R2+nr,R_SUBWHOLE);
-           end
-         else
-           begin
-              result.loc:=LOC_REFERENCE;
-              result.reference.index:=NR_STACK_POINTER_REG;
-              result.reference.offset:=(nr-8)*4;
-           end;
-         result.size := OS_INT;
+        cgpara.reset;
+        cgpara.size:=OS_INT;
+        cgpara.alignment:=get_para_align(calloption);
+        paraloc:=cgpara.add_location;
+        with paraloc^ do
+         begin
+           size:=OS_INT;
+           if (nr<=8) then
+             begin
+               if nr=0 then
+                 internalerror(200309271);
+               loc:=LOC_REGISTER;
+               register:=newreg(R_INTREGISTER,RS_R2+nr,R_SUBWHOLE);
+             end
+           else
+             begin
+               loc:=LOC_REFERENCE;
+               reference.index:=NR_STACK_POINTER_REG;
+               reference.offset:=sizeof(aint)*(nr-8);
+             end;
+          end;
       end;
       end;
 
 
 
 
+
     function getparaloc(p : tdef) : tcgloc;
     function getparaloc(p : tdef) : tcgloc;
 
 
       begin
       begin
@@ -110,48 +117,48 @@ unit cpupara;
          }
          }
          case p.deftype of
          case p.deftype of
             orddef:
             orddef:
-              getparaloc:=LOC_REGISTER;
+              result:=LOC_REGISTER;
             floatdef:
             floatdef:
-              getparaloc:=LOC_FPUREGISTER;
+              result:=LOC_FPUREGISTER;
             enumdef:
             enumdef:
-              getparaloc:=LOC_REGISTER;
+              result:=LOC_REGISTER;
             pointerdef:
             pointerdef:
-              getparaloc:=LOC_REGISTER;
+              result:=LOC_REGISTER;
             formaldef:
             formaldef:
-              getparaloc:=LOC_REGISTER;
+              result:=LOC_REGISTER;
             classrefdef:
             classrefdef:
-              getparaloc:=LOC_REGISTER;
+              result:=LOC_REGISTER;
             recorddef:
             recorddef:
-              getparaloc:=LOC_REFERENCE;
+              result:=LOC_REFERENCE;
             objectdef:
             objectdef:
               if is_object(p) then
               if is_object(p) then
-                getparaloc:=LOC_REFERENCE
+                result:=LOC_REFERENCE
               else
               else
-                getparaloc:=LOC_REGISTER;
+                result:=LOC_REGISTER;
             stringdef:
             stringdef:
               if is_shortstring(p) or is_longstring(p) then
               if is_shortstring(p) or is_longstring(p) then
-                getparaloc:=LOC_REFERENCE
+                result:=LOC_REFERENCE
               else
               else
-                getparaloc:=LOC_REGISTER;
+                result:=LOC_REGISTER;
             procvardef:
             procvardef:
               if (po_methodpointer in tprocvardef(p).procoptions) then
               if (po_methodpointer in tprocvardef(p).procoptions) then
-                getparaloc:=LOC_REFERENCE
+                result:=LOC_REFERENCE
               else
               else
-                getparaloc:=LOC_REGISTER;
+                result:=LOC_REGISTER;
             filedef:
             filedef:
-              getparaloc:=LOC_REGISTER;
+              result:=LOC_REGISTER;
             arraydef:
             arraydef:
-              getparaloc:=LOC_REFERENCE;
+              result:=LOC_REFERENCE;
             setdef:
             setdef:
               if is_smallset(p) then
               if is_smallset(p) then
-                getparaloc:=LOC_REGISTER
+                result:=LOC_REGISTER
               else
               else
-                getparaloc:=LOC_REFERENCE;
+                result:=LOC_REFERENCE;
             variantdef:
             variantdef:
-              getparaloc:=LOC_REFERENCE;
+              result:=LOC_REFERENCE;
             { avoid problems with errornous definitions }
             { avoid problems with errornous definitions }
             errordef:
             errordef:
-              getparaloc:=LOC_REGISTER;
+              result:=LOC_REGISTER;
             else
             else
               internalerror(2002071001);
               internalerror(2002071001);
          end;
          end;
@@ -204,55 +211,74 @@ unit cpupara;
 
 
     procedure tppcparamanager.create_funcret_paraloc_info(p : tabstractprocdef; side: tcallercallee);
     procedure tppcparamanager.create_funcret_paraloc_info(p : tabstractprocdef; side: tcallercallee);
       var
       var
-        paraloc : tparalocation;
+        hiparaloc,
+        paraloc : pcgparalocation;
+        retcgsize  : tcgsize;
       begin
       begin
-        fillchar(paraloc,sizeof(tparalocation),0);
-        paraloc.size:=def_cgsize(p.rettype.def);
-        paraloc.Alignment:= std_param_align;
-        { Constructors return self }
+        { Constructors return self instead of a boolean }
         if (p.proctypeoption=potype_constructor) then
         if (p.proctypeoption=potype_constructor) then
-          begin
-            paraloc.size:=OS_ADDR;
-            paraloc.loc:=LOC_REGISTER;
-            paraloc.register:=NR_FUNCTION_RESULT_REG;
-          end
+          retcgsize:=OS_ADDR
         else
         else
-         { Return in FPU register? }
-         if p.rettype.def.deftype=floatdef then
+          retcgsize:=def_cgsize(p.rettype.def);
+        p.funcret_paraloc[side].reset;
+        p.funcret_paraloc[side].Alignment:=std_param_align;
+        p.funcret_paraloc[side].size:=retcgsize;
+        { void has no location }
+        if is_void(p.rettype.def) then
+          exit;
+        paraloc:=p.funcret_paraloc[side].add_location;
+        { Return in FPU register? }
+        if p.rettype.def.deftype=floatdef then
           begin
           begin
-            paraloc.loc:=LOC_FPUREGISTER;
-            paraloc.register:=NR_FPU_RESULT_REG;
+            paraloc^.loc:=LOC_FPUREGISTER;
+            paraloc^.register:=NR_FPU_RESULT_REG;
+            paraloc^.size:=retcgsize;
           end
           end
         else
         else
          { Return in register? }
          { Return in register? }
          if not ret_in_param(p.rettype.def,p.proccalloption) then
          if not ret_in_param(p.rettype.def,p.proccalloption) then
           begin
           begin
-            paraloc.loc:=LOC_REGISTER;
 {$ifndef cpu64bit}
 {$ifndef cpu64bit}
-            if paraloc.size in [OS_64,OS_S64] then
+            if retcgsize in [OS_64,OS_S64] then
              begin
              begin
-               paraloc.lochigh:=LOC_REGISTER;
-               paraloc.register64.reglo:=NR_FUNCTION_RESULT64_LOW_REG;
-               paraloc.register64.reghi:=NR_FUNCTION_RESULT64_HIGH_REG
+               { low 32bits }
+               paraloc^.loc:=LOC_REGISTER;
+               paraloc^.size:=OS_32;
+               if side=callerside then
+                 paraloc^.register:=NR_FUNCTION_RESULT64_HIGH_REG
+               else
+                 paraloc^.register:=NR_FUNCTION_RETURN64_HIGH_REG;
+               { high 32bits }
+               hiparaloc:=p.funcret_paraloc[side].add_location;
+               hiparaloc^.loc:=LOC_REGISTER;
+               hiparaloc^.size:=OS_32;
+               if side=callerside then
+                 hiparaloc^.register:=NR_FUNCTION_RESULT64_LOW_REG
+               else
+                 hiparaloc^.register:=NR_FUNCTION_RETURN64_LOW_REG;
              end
              end
             else
             else
 {$endif cpu64bit}
 {$endif cpu64bit}
              begin
              begin
-               paraloc.register:=NR_FUNCTION_RESULT_REG
+               paraloc^.loc:=LOC_REGISTER;
+               paraloc^.size:=retcgsize;
+               if side=callerside then
+                 paraloc^.register:=newreg(R_INTREGISTER,RS_FUNCTION_RESULT_REG,cgsize2subreg(retcgsize))
+               else
+                 paraloc^.register:=newreg(R_INTREGISTER,RS_FUNCTION_RETURN_REG,cgsize2subreg(retcgsize));
              end;
              end;
           end
           end
         else
         else
           begin
           begin
-            paraloc.loc:=LOC_REFERENCE;
+            paraloc^.loc:=LOC_REFERENCE;
+            paraloc^.size:=retcgsize;
           end;
           end;
-        p.funcret_paraloc[side]:=paraloc;
       end;
       end;
 
 
 
 
     function tppcparamanager.create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;
     function tppcparamanager.create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;
 
 
       var
       var
-        paraloc : tparalocation;
         cur_stack_offset: aword;
         cur_stack_offset: aword;
         curintreg, curfloatreg, curmmreg: tsuperregister;
         curintreg, curfloatreg, curmmreg: tsuperregister;
       begin
       begin
@@ -271,9 +297,10 @@ unit cpupara;
          stack_offset: aword;
          stack_offset: aword;
          nextintreg,nextfloatreg,nextmmreg, maxfpureg : tsuperregister;
          nextintreg,nextfloatreg,nextmmreg, maxfpureg : tsuperregister;
          paradef : tdef;
          paradef : tdef;
-         paraloc : tparalocation;
+         paraloc,paraloc2 : pcgparalocation;
          hp : tparaitem;
          hp : tparaitem;
          loc : tcgloc;
          loc : tcgloc;
+         paracgsize: tcgsize;
          is_64bit: boolean;
          is_64bit: boolean;
 
 
       procedure assignintreg;
       procedure assignintreg;
@@ -281,17 +308,17 @@ unit cpupara;
         begin
         begin
            if nextintreg<=ord(NR_R10) then
            if nextintreg<=ord(NR_R10) then
              begin
              begin
-                paraloc.loc:=LOC_REGISTER;
-                paraloc.register:=newreg(R_INTREGISTER,nextintreg,R_SUBNONE);
+                paraloc^.loc:=LOC_REGISTER;
+                paraloc^.register:=newreg(R_INTREGISTER,nextintreg,R_SUBNONE);
                 inc(nextintreg);
                 inc(nextintreg);
                 if target_info.abi=abi_powerpc_aix then
                 if target_info.abi=abi_powerpc_aix then
                   inc(stack_offset,4);
                   inc(stack_offset,4);
              end
              end
            else
            else
               begin
               begin
-                 paraloc.loc:=LOC_REFERENCE;
-                 paraloc.reference.index:=NR_STACK_POINTER_REG;
-                 paraloc.reference.offset:=stack_offset;
+                 paraloc^.loc:=LOC_REFERENCE;
+                 paraloc^.reference.index:=NR_STACK_POINTER_REG;
+                 paraloc^.reference.offset:=stack_offset;
                  inc(stack_offset,4);
                  inc(stack_offset,4);
              end;
              end;
         end;
         end;
@@ -313,64 +340,77 @@ unit cpupara;
          hp:=firstpara;
          hp:=firstpara;
          while assigned(hp) do
          while assigned(hp) do
            begin
            begin
+              hp.paraloc[side].reset;
               { currently only support C-style array of const }
               { currently only support C-style array of const }
               if (p.proccalloption in [pocall_cdecl,pocall_cppdecl]) and
               if (p.proccalloption in [pocall_cdecl,pocall_cppdecl]) and
                  is_array_of_const(hp.paratype.def) then
                  is_array_of_const(hp.paratype.def) then
                 begin
                 begin
+                  paraloc:=hp.paraloc[side].add_location;
                   { hack: the paraloc must be valid, but is not actually used }
                   { hack: the paraloc must be valid, but is not actually used }
-                  hp.paraloc[side].loc := LOC_REGISTER;
-                  hp.paraloc[side].lochigh := LOC_INVALID;
-                  hp.paraloc[side].register := NR_R0;
-                  hp.paraloc[side].size := OS_ADDR;
+                  paraloc^.loc := LOC_REGISTER;
+                  paraloc^.register := NR_R0;
+                  paraloc^.size := OS_ADDR;
                   break;
                   break;
                 end;
                 end;
 
 
               if (hp.paratyp in [vs_var,vs_out]) then
               if (hp.paratyp in [vs_var,vs_out]) then
                 begin
                 begin
-                  paradef := voidpointertype.def;
-                  loc := LOC_REGISTER;
+                  paradef:=voidpointertype.def;
+                  loc:=LOC_REGISTER;
+                  paracgsize := OS_ADDR;
                 end
                 end
               else
               else
                 begin
                 begin
                   paradef := hp.paratype.def;
                   paradef := hp.paratype.def;
                   loc:=getparaloc(paradef);
                   loc:=getparaloc(paradef);
+                  paracgsize:=def_cgsize(paradef);
+                  { for things like formaldef }
+                  if paracgsize=OS_NO then
+                    paracgsize:=OS_ADDR;
                 end;
                 end;
-              { make sure all alignment bytes are 0 as well }
-              fillchar(paraloc,sizeof(paraloc),0);
-              paraloc.alignment:= std_param_align;
-              paraloc.lochigh:=LOC_INVALID;
+              hp.paraloc[side].alignment:=std_param_align;
+              hp.paraloc[side].size:=paracgsize;
+              { First location }
+              paraloc:=hp.paraloc[side].add_location;
+              paraloc^.size:=paracgsize;
               case loc of
               case loc of
                  LOC_REGISTER:
                  LOC_REGISTER:
                    begin
                    begin
-                      paraloc.size := def_cgsize(paradef);
-                      { for things like formaldef }
-                      if paraloc.size = OS_NO then
-                        paraloc.size := OS_ADDR;
-                      is_64bit := paraloc.size in [OS_64,OS_S64];
+                      is_64bit:=paraloc^.size in [OS_64,OS_S64];
                       if nextintreg<=(RS_R10-ord(is_64bit))  then
                       if nextintreg<=(RS_R10-ord(is_64bit))  then
                         begin
                         begin
-                           paraloc.loc:=LOC_REGISTER;
+                           paraloc^.loc:=LOC_REGISTER;
+{$ifndef cpu64bit}
                            if is_64bit then
                            if is_64bit then
                              begin
                              begin
                                if odd(nextintreg-RS_R3) and (target_info.abi=abi_powerpc_sysv) Then
                                if odd(nextintreg-RS_R3) and (target_info.abi=abi_powerpc_sysv) Then
                                  inc(nextintreg);
                                  inc(nextintreg);
-                               paraloc.registerhigh:=newreg(R_INTREGISTER,nextintreg,R_SUBNONE);
-                               paraloc.lochigh:=LOC_REGISTER;
+                               paraloc^.size:=OS_32;
+                               paraloc^.register:=newreg(R_INTREGISTER,nextintreg,R_SUBNONE);
+                               inc(nextintreg);
+                               paraloc2:=hp.paraloc[side].add_location;
+                               paraloc2^.loc:=LOC_REGISTER;
+                               paraloc2^.size:=OS_32;
+                               paraloc2^.register:=newreg(R_INTREGISTER,nextintreg,R_SUBNONE);
+                               inc(nextintreg);
+                               if target_info.abi=abi_powerpc_aix then
+                                 inc(stack_offset,8);
+                             end
+                           else
+{$endif cpu64bit}
+                             begin
+                               paraloc^.register:=newreg(R_INTREGISTER,nextintreg,R_SUBNONE);
                                inc(nextintreg);
                                inc(nextintreg);
                                if target_info.abi=abi_powerpc_aix then
                                if target_info.abi=abi_powerpc_aix then
-                                 inc(stack_offset,4);
-                             end;
-                           paraloc.registerlow:=newreg(R_INTREGISTER,nextintreg,R_SUBNONE);
-                           inc(nextintreg);
-                           if target_info.abi=abi_powerpc_aix then
-                             inc(stack_offset,4);
+                                 inc(stack_offset,sizeof(aword));
+                              end;
                         end
                         end
                       else
                       else
                          begin
                          begin
                             nextintreg:=RS_R11;
                             nextintreg:=RS_R11;
-                            paraloc.loc:=LOC_REFERENCE;
-                            paraloc.reference.index:=NR_STACK_POINTER_REG;
-                            paraloc.reference.offset:=stack_offset;
+                            paraloc^.loc:=LOC_REFERENCE;
+                            paraloc^.reference.index:=NR_STACK_POINTER_REG;
+                            paraloc^.reference.offset:=stack_offset;
                             if not is_64bit then
                             if not is_64bit then
                               inc(stack_offset,4)
                               inc(stack_offset,4)
                             else
                             else
@@ -379,22 +419,21 @@ unit cpupara;
                    end;
                    end;
                  LOC_FPUREGISTER:
                  LOC_FPUREGISTER:
                    begin
                    begin
-                      paraloc.size:=def_cgsize(paradef);
                       if nextfloatreg<=maxfpureg then
                       if nextfloatreg<=maxfpureg then
                         begin
                         begin
-                           paraloc.loc:=LOC_FPUREGISTER;
-                           paraloc.register:=newreg(R_FPUREGISTER,nextfloatreg,R_SUBWHOLE);
+                           paraloc^.loc:=LOC_FPUREGISTER;
+                           paraloc^.register:=newreg(R_FPUREGISTER,nextfloatreg,R_SUBWHOLE);
                            inc(nextfloatreg);
                            inc(nextfloatreg);
                         end
                         end
                       else
                       else
                          begin
                          begin
-                            paraloc.loc:=LOC_REFERENCE;
-                            paraloc.reference.index:=NR_STACK_POINTER_REG;
-                            paraloc.reference.offset:=stack_offset;
+                            paraloc^.loc:=LOC_REFERENCE;
+                            paraloc^.reference.index:=NR_STACK_POINTER_REG;
+                            paraloc^.reference.offset:=stack_offset;
                         end;
                         end;
                       if target_info.abi=abi_powerpc_aix then
                       if target_info.abi=abi_powerpc_aix then
                         begin
                         begin
-                          if paraloc.size = OS_F32 then
+                          if paraloc^.size = OS_F32 then
                             begin
                             begin
                               inc(stack_offset,4);
                               inc(stack_offset,4);
                               if (nextintreg < RS_R11) then
                               if (nextintreg < RS_R11) then
@@ -412,36 +451,22 @@ unit cpupara;
                    end;
                    end;
                  LOC_REFERENCE:
                  LOC_REFERENCE:
                    begin
                    begin
-                      paraloc.size:=OS_ADDR;
+                      paraloc^.size:=OS_ADDR;
                       if push_addr_param(hp.paratyp,paradef,p.proccalloption) or
                       if push_addr_param(hp.paratyp,paradef,p.proccalloption) or
                         is_open_array(paradef) or
                         is_open_array(paradef) or
                         is_array_of_const(paradef) then
                         is_array_of_const(paradef) then
                         assignintreg
                         assignintreg
                       else
                       else
                         begin
                         begin
-                           paraloc.loc:=LOC_REFERENCE;
-                           paraloc.reference.index:=NR_STACK_POINTER_REG;
-                           paraloc.reference.offset:=stack_offset;
+                           paraloc^.loc:=LOC_REFERENCE;
+                           paraloc^.reference.index:=NR_STACK_POINTER_REG;
+                           paraloc^.reference.offset:=stack_offset;
                            inc(stack_offset,hp.paratype.def.size);
                            inc(stack_offset,hp.paratype.def.size);
                         end;
                         end;
                    end;
                    end;
                  else
                  else
                    internalerror(2002071002);
                    internalerror(2002071002);
               end;
               end;
-{
-              this is filled in in ncgutil
-
-              if side = calleeside then
-                begin
-                  if (paraloc.loc = LOC_REFERENCE) then
-                    begin
-                      if (current_procinfo.procdef <> p) then
-                        internalerror(2003112201);
-                      inc(paraloc.reference.offset,current_procinfo.calc_stackframe_size);
-                    end;
-                end;
-}
-              hp.paraloc[side]:=paraloc;
               hp:=tparaitem(hp.next);
               hp:=tparaitem(hp.next);
            end;
            end;
          curintreg:=nextintreg;
          curintreg:=nextintreg;
@@ -458,33 +483,32 @@ unit cpupara;
         parasize, l: longint;
         parasize, l: longint;
         curintreg, firstfloatreg, curfloatreg, curmmreg: tsuperregister;
         curintreg, firstfloatreg, curfloatreg, curmmreg: tsuperregister;
         hp: tparaitem;
         hp: tparaitem;
-        paraloc: tparalocation;
+        paraloc: pcgparalocation;
       begin
       begin
         init_values(curintreg,curfloatreg,curmmreg,cur_stack_offset);
         init_values(curintreg,curfloatreg,curmmreg,cur_stack_offset);
         firstfloatreg:=curfloatreg;
         firstfloatreg:=curfloatreg;
 
 
-        result := create_paraloc_info_intern(p,callerside,tparaitem(p.para.first),curintreg,curfloatreg,curmmreg,cur_stack_offset);
+        result:=create_paraloc_info_intern(p,callerside,tparaitem(p.para.first),curintreg,curfloatreg,curmmreg,cur_stack_offset);
         if (p.proccalloption in [pocall_cdecl,pocall_cppdecl]) then
         if (p.proccalloption in [pocall_cdecl,pocall_cppdecl]) then
           { just continue loading the parameters in the registers }
           { just continue loading the parameters in the registers }
-          result := create_paraloc_info_intern(p,callerside,tparaitem(varargspara.first),curintreg,curfloatreg,curmmreg,cur_stack_offset)
+          result:=create_paraloc_info_intern(p,callerside,tparaitem(varargspara.first),curintreg,curfloatreg,curmmreg,cur_stack_offset)
         else
         else
           begin
           begin
-            hp := tparaitem(varargspara.first);
-            parasize := cur_stack_offset;
+            hp:=tparaitem(varargspara.first);
+            parasize:=cur_stack_offset;
             while assigned(hp) do
             while assigned(hp) do
               begin
               begin
-                paraloc.size:=def_cgsize(hp.paratype.def);
-                paraloc.lochigh:=LOC_INVALID;
-                paraloc.loc:=LOC_REFERENCE;
-                paraloc.alignment:=4;
-                paraloc.reference.index:=NR_STACK_POINTER_REG;
+                hp.paraloc[callerside].alignment:=4;
+                paraloc:=hp.paraloc[callerside].add_location;
+                paraloc^.loc:=LOC_REFERENCE;
+                paraloc^.size:=def_cgsize(hp.paratype.def);
+                paraloc^.reference.index:=NR_STACK_POINTER_REG;
                 l:=push_size(hp.paratyp,hp.paratype.def,p.proccalloption);
                 l:=push_size(hp.paratyp,hp.paratype.def,p.proccalloption);
-                paraloc.reference.offset:=parasize;
+                paraloc^.reference.offset:=parasize;
                 parasize:=parasize+l;
                 parasize:=parasize+l;
-                hp.paraloc[callerside]:=paraloc;
                 hp:=tparaitem(hp.next);
                 hp:=tparaitem(hp.next);
               end;
               end;
-            result := parasize;
+            result:=parasize;
           end;
           end;
         if curfloatreg<>firstfloatreg then
         if curfloatreg<>firstfloatreg then
           include(varargspara.varargsinfo,va_uses_float_reg);
           include(varargspara.varargsinfo,va_uses_float_reg);
@@ -492,56 +516,60 @@ unit cpupara;
 
 
 
 
     function tppcparamanager.parseparaloc(p : tparaitem;const s : string) : boolean;
     function tppcparamanager.parseparaloc(p : tparaitem;const s : string) : boolean;
+      var
+        paraloc : pcgparalocation;
       begin
       begin
         result:=false;
         result:=false;
         case target_info.system of
         case target_info.system of
           system_powerpc_morphos:
           system_powerpc_morphos:
             begin
             begin
-              p.paraloc[callerside].loc:=LOC_REFERENCE;
-              p.paraloc[callerside].lochigh:=LOC_INVALID;
-              p.paraloc[callerside].size:=def_cgsize(p.paratype.def);
               p.paraloc[callerside].alignment:=4;
               p.paraloc[callerside].alignment:=4;
-              p.paraloc[callerside].reference.index:=NR_R2;
+              paraloc:=p.paraloc[callerside].add_location;
+              paraloc^.loc:=LOC_REFERENCE;
+              paraloc^.size:=def_cgsize(p.paratype.def);
+              paraloc^.reference.index:=NR_R2;
               { pattern is always uppercase'd }
               { pattern is always uppercase'd }
               if s='D0' then
               if s='D0' then
-                p.paraloc[callerside].reference.offset:=0
+                paraloc^.reference.offset:=0
               else if s='D1' then
               else if s='D1' then
-                p.paraloc[callerside].reference.offset:=4
+                paraloc^.reference.offset:=4
               else if s='D2' then
               else if s='D2' then
-                p.paraloc[callerside].reference.offset:=8
+                paraloc^.reference.offset:=8
               else if s='D3' then
               else if s='D3' then
-                p.paraloc[callerside].reference.offset:=12
+                paraloc^.reference.offset:=12
               else if s='D4' then
               else if s='D4' then
-                p.paraloc[callerside].reference.offset:=16
+                paraloc^.reference.offset:=16
               else if s='D5' then
               else if s='D5' then
-                p.paraloc[callerside].reference.offset:=20
+                paraloc^.reference.offset:=20
               else if s='D6' then
               else if s='D6' then
-                p.paraloc[callerside].reference.offset:=24
+                paraloc^.reference.offset:=24
               else if s='D7' then
               else if s='D7' then
-                p.paraloc[callerside].reference.offset:=28
+                paraloc^.reference.offset:=28
               else if s='A0' then
               else if s='A0' then
-                p.paraloc[callerside].reference.offset:=32
+                paraloc^.reference.offset:=32
               else if s='A1' then
               else if s='A1' then
-                p.paraloc[callerside].reference.offset:=36
+                paraloc^.reference.offset:=36
               else if s='A2' then
               else if s='A2' then
-                p.paraloc[callerside].reference.offset:=40
+                paraloc^.reference.offset:=40
               else if s='A3' then
               else if s='A3' then
-                p.paraloc[callerside].reference.offset:=44
+                paraloc^.reference.offset:=44
               else if s='A4' then
               else if s='A4' then
-                p.paraloc[callerside].reference.offset:=48
+                paraloc^.reference.offset:=48
               else if s='A5' then
               else if s='A5' then
-                p.paraloc[callerside].reference.offset:=52
+                paraloc^.reference.offset:=52
               { 'A6' (offset 56) is used by mossyscall as libbase, so API
               { 'A6' (offset 56) is used by mossyscall as libbase, so API
                 never passes parameters in it,
                 never passes parameters in it,
                 Indeed, but this allows to declare libbase either explicitly
                 Indeed, but this allows to declare libbase either explicitly
                 or let the compiler insert it }
                 or let the compiler insert it }
               else if s='A6' then
               else if s='A6' then
-                p.paraloc[callerside].reference.offset:=56
+                paraloc^.reference.offset:=56
               { 'A7' is the stack pointer on 68k, can't be overwritten
               { 'A7' is the stack pointer on 68k, can't be overwritten
                 by API calls, so it has no offset }
                 by API calls, so it has no offset }
               else
               else
                 exit;
                 exit;
-              p.paraloc[calleeside]:=p.paraloc[callerside];
+
+              { copy to callee side }
+              p.paraloc[calleeside].add_location^:=paraloc^;
             end;
             end;
           else
           else
             internalerror(200404182);
             internalerror(200404182);
@@ -555,7 +583,19 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.67  2004-07-19 19:15:50  florian
+  Revision 1.68  2004-09-21 17:25:13  peter
+    * paraloc branch merged
+
+  Revision 1.67.4.3  2004/09/18 20:21:08  jonas
+    * fixed ppc, but still needs fix in tgobj
+
+  Revision 1.67.4.2  2004/09/10 11:10:08  florian
+    * first part of ppc fixes
+
+  Revision 1.67.4.1  2004/08/31 20:43:06  peter
+    * paraloc patch
+
+  Revision 1.67  2004/07/19 19:15:50  florian
     * fixed funcret_paraloc writing in units
     * fixed funcret_paraloc writing in units
 
 
   Revision 1.66  2004/07/17 13:51:57  florian
   Revision 1.66  2004/07/17 13:51:57  florian

+ 15 - 9
compiler/powerpc/nppccal.pas

@@ -41,7 +41,7 @@ implementation
     uses
     uses
       globtype,systems,
       globtype,systems,
       cutils,verbose,globals,
       cutils,verbose,globals,
-      symconst,symbase,symsym,symtable,defutil,paramgr,
+      symconst,symbase,symsym,symtable,defutil,paramgr,parabase,
 {$ifdef GDB}
 {$ifdef GDB}
   {$ifdef delphi}
   {$ifdef delphi}
       sysutils,
       sysutils,
@@ -67,9 +67,9 @@ implementation
               exprasmlist.concat(taicpu.op_const_const_const(A_CRXOR,6,6,6));
               exprasmlist.concat(taicpu.op_const_const_const(A_CRXOR,6,6,6));
           end;
           end;
       end;
       end;
-        
+
     procedure tppccallnode.do_syscall;
     procedure tppccallnode.do_syscall;
-      var 
+      var
         tmpref: treference;
         tmpref: treference;
       begin
       begin
         case target_info.system of
         case target_info.system of
@@ -77,22 +77,22 @@ implementation
             begin
             begin
               cg.getexplicitregister(exprasmlist,NR_R0);
               cg.getexplicitregister(exprasmlist,NR_R0);
               cg.getexplicitregister(exprasmlist,NR_R3);
               cg.getexplicitregister(exprasmlist,NR_R3);
-                                       
+
               { store call offset into R3 }
               { store call offset into R3 }
               exprasmlist.concat(taicpu.op_reg_const(A_LI,NR_R3,-tprocdef(procdefinition).extnumber));
               exprasmlist.concat(taicpu.op_reg_const(A_LI,NR_R3,-tprocdef(procdefinition).extnumber));
-              
+
               { prepare LR, and call function }
               { prepare LR, and call function }
-              reference_reset_base(tmpref,NR_R2,100); { 100 ($64) is EmulDirectCallOS offset } 
+              reference_reset_base(tmpref,NR_R2,100); { 100 ($64) is EmulDirectCallOS offset }
               exprasmlist.concat(taicpu.op_reg_ref(A_LWZ,NR_R0,tmpref));
               exprasmlist.concat(taicpu.op_reg_ref(A_LWZ,NR_R0,tmpref));
               exprasmlist.concat(taicpu.op_reg(A_MTLR,NR_R0));
               exprasmlist.concat(taicpu.op_reg(A_MTLR,NR_R0));
-              exprasmlist.concat(taicpu.op_none(A_BLRL));            
+              exprasmlist.concat(taicpu.op_none(A_BLRL));
 
 
               cg.ungetregister(exprasmlist,NR_R0);
               cg.ungetregister(exprasmlist,NR_R0);
               cg.ungetregister(exprasmlist,NR_R3);
               cg.ungetregister(exprasmlist,NR_R3);
             end;
             end;
           else
           else
             internalerror(2004042901);
             internalerror(2004042901);
-        end;      
+        end;
       end;
       end;
 
 
 begin
 begin
@@ -100,7 +100,13 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.27  2004-06-20 08:55:32  florian
+  Revision 1.28  2004-09-21 17:25:13  peter
+    * paraloc branch merged
+
+  Revision 1.27.4.1  2004/09/18 20:21:08  jonas
+    * fixed ppc, but still needs fix in tgobj
+
+  Revision 1.27  2004/06/20 08:55:32  florian
     * logs truncated
     * logs truncated
 
 
   Revision 1.26  2004/04/29 22:18:37  karoly
   Revision 1.26  2004/04/29 22:18:37  karoly

+ 9 - 1
compiler/ppu.pas

@@ -525,6 +525,8 @@ begin
   if entryidx<entry.size then
   if entryidx<entry.size then
    skipdata(entry.size-entryidx);
    skipdata(entry.size-entryidx);
   readdata(entry,sizeof(tppuentry));
   readdata(entry,sizeof(tppuentry));
+  if change_endian then
+   entry.size:=swaplong(entry.size);
   entrystart:=bufstart+bufidx;
   entrystart:=bufstart+bufidx;
   entryidx:=0;
   entryidx:=0;
   if not(entry.id in [mainentryid,subentryid]) then
   if not(entry.id in [mainentryid,subentryid]) then
@@ -1054,7 +1056,13 @@ end;
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.56  2004-08-27 21:59:26  peter
+  Revision 1.57  2004-09-21 17:25:12  peter
+    * paraloc branch merged
+
+  Revision 1.56.4.1  2004/09/12 14:01:23  peter
+    * entry.size need endian update
+
+  Revision 1.56  2004/08/27 21:59:26  peter
   browser disabled
   browser disabled
   uf_local_symtable ppu flag when a localsymtable is stored
   uf_local_symtable ppu flag when a localsymtable is stored
 
 

+ 7 - 2
compiler/pstatmnt.pas

@@ -1,5 +1,4 @@
 {
 {
-    $Id$
     $Id$
     $Id$
     Copyright (c) 1998-2002 by Florian Klaempfl
     Copyright (c) 1998-2002 by Florian Klaempfl
 
 
@@ -1184,12 +1183,18 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.138  2004-09-21 16:00:50  peter
+  Revision 1.139  2004-09-21 17:25:12  peter
+    * paraloc branch merged
+
+  Revision 1.138  2004/09/21 16:00:50  peter
     * no difference for withnode when debuginfo is generated
     * no difference for withnode when debuginfo is generated
 
 
   Revision 1.137  2004/09/13 20:28:27  peter
   Revision 1.137  2004/09/13 20:28:27  peter
     * for loop variable assignment is not allowed anymore
     * for loop variable assignment is not allowed anymore
 
 
+  Revision 1.136.4.1  2004/09/21 16:01:54  peter
+    * withnode debug disabled
+
   Revision 1.136  2004/06/20 08:55:30  florian
   Revision 1.136  2004/06/20 08:55:30  florian
     * logs truncated
     * logs truncated
 
 

+ 11 - 3
compiler/psub.pas

@@ -720,14 +720,14 @@ implementation
             aktlocalswitches:=entryswitches;
             aktlocalswitches:=entryswitches;
             gen_entry_code(templist);
             gen_entry_code(templist);
             aktproccode.insertlistafter(entry_asmnode.currenttai,templist);
             aktproccode.insertlistafter(entry_asmnode.currenttai,templist);
-            gen_initialize_code(templist,false);
+            gen_initialize_code(templist);
             aktproccode.insertlistafter(init_asmnode.currenttai,templist);
             aktproccode.insertlistafter(init_asmnode.currenttai,templist);
 
 
             { now generate finalize and exit code with the correct position
             { now generate finalize and exit code with the correct position
               and switches }
               and switches }
             aktfilepos:=exitpos;
             aktfilepos:=exitpos;
             aktlocalswitches:=exitswitches;
             aktlocalswitches:=exitswitches;
-            gen_finalize_code(templist,false);
+            gen_finalize_code(templist);
             { the finalcode must be concated if there was no position available,
             { the finalcode must be concated if there was no position available,
               using insertlistafter will result in an insert at the start
               using insertlistafter will result in an insert at the start
               when currentai=nil }
               when currentai=nil }
@@ -1393,13 +1393,21 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.205  2004-09-13 20:34:28  peter
+  Revision 1.206  2004-09-21 17:25:12  peter
+    * paraloc branch merged
+
+  Revision 1.205  2004/09/13 20:34:28  peter
     * keep localst in memory, it is also needed for finalizing
     * keep localst in memory, it is also needed for finalizing
       typedconst
       typedconst
 
 
   Revision 1.204  2004/09/04 21:18:47  armin
   Revision 1.204  2004/09/04 21:18:47  armin
   * target netwlibc added (libc is preferred for newer netware versions)
   * target netwlibc added (libc is preferred for newer netware versions)
 
 
+  Revision 1.203.4.1  2004/09/17 17:19:26  peter
+    * fixed 64 bit unaryminus for sparc
+    * fixed 64 bit inlining
+    * signness of not operation
+
   Revision 1.203  2004/08/14 14:50:42  florian
   Revision 1.203  2004/08/14 14:50:42  florian
     * fixed several sparc alignment issues
     * fixed several sparc alignment issues
     + Jonas' inline node patch; non functional yet
     + Jonas' inline node patch; non functional yet

+ 29 - 5
compiler/rgobj.pas

@@ -608,12 +608,22 @@ unit rgobj;
     procedure trgobj.add_edges_used(u:Tsuperregister);
     procedure trgobj.add_edges_used(u:Tsuperregister);
 
 
     var i:word;
     var i:word;
+        v:tsuperregister;
 
 
     begin
     begin
       with live_registers do
       with live_registers do
         if length>0 then
         if length>0 then
           for i:=0 to length-1 do
           for i:=0 to length-1 do
-            add_edge(u,buf^[i]);
+            begin
+              v:=buf^[i];
+              add_edge(u,v);
+              { add also conflicts with all coalesced registers }
+              while ri_coalesced in reginfo[v].flags do
+                begin
+                  v:=reginfo[v].alias;
+                  add_edge(u,v);
+                end;
+            end;
     end;
     end;
 
 
 {$ifdef EXTDEBUG}
 {$ifdef EXTDEBUG}
@@ -1255,7 +1265,7 @@ unit rgobj;
         i,j,k : word;
         i,j,k : word;
         n,a,c : Tsuperregister;
         n,a,c : Tsuperregister;
         colourednodes : Tsuperregisterset;
         colourednodes : Tsuperregisterset;
-		adj_colours:set of 0..255;
+                adj_colours:set of 0..255;
         found : boolean;
         found : boolean;
 
 
     begin
     begin
@@ -1705,8 +1715,13 @@ unit rgobj;
               supregset_include(regs_to_spill_set,t);
               supregset_include(regs_to_spill_set,t);
               {Clear all interferences of the spilled register.}
               {Clear all interferences of the spilled register.}
               clear_interferences(t);
               clear_interferences(t);
-              {Get a temp for the spilled register}
-              tg.gettemp(templist,tcgsize2size[reg_cgsize(newreg(regtype,t,R_SUBWHOLE))],tt_noreuse,spill_temps^[t]);
+              {Get a temp for the spilled register, the size must at least equal a complete register,
+               take also care of the fact that subreg can be larger than a single register like doubles
+               that occupy 2 registers }
+              tg.gettemp(templist,
+                         max(tcgsize2size[reg_cgsize(newreg(regtype,t,R_SUBWHOLE))],
+                             tcgsize2size[reg_cgsize(newreg(regtype,t,reginfo[t].subreg))]),
+                         tt_noreuse,spill_temps^[t]);
             end;
             end;
         list.insertlistafter(headertai,templist);
         list.insertlistafter(headertai,templist);
         templist.free;
         templist.free;
@@ -1986,7 +2001,16 @@ unit rgobj;
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.134  2004-08-24 21:02:32  florian
+  Revision 1.135  2004-09-21 17:25:12  peter
+    * paraloc branch merged
+
+  Revision 1.134.4.2  2004/09/21 17:03:26  peter
+    * Include aliases of coalesce registers when adding conflicts
+
+  Revision 1.134.4.1  2004/09/12 13:36:40  peter
+    * fixed alignment issues
+
+  Revision 1.134  2004/08/24 21:02:32  florian
     * fixed longbool(<int64>) on sparc
     * fixed longbool(<int64>) on sparc
 
 
   Revision 1.133  2004/07/09 21:38:30  daniel
   Revision 1.133  2004/07/09 21:38:30  daniel

+ 259 - 114
compiler/sparc/cgcpu.pas

@@ -27,7 +27,7 @@ unit cgcpu;
 interface
 interface
 
 
     uses
     uses
-       globtype,
+       globtype,parabase,
        cgbase,cgobj,cg64f32,
        cgbase,cgobj,cg64f32,
        aasmbase,aasmtai,aasmcpu,
        aasmbase,aasmtai,aasmcpu,
        cpubase,cpuinfo,
        cpubase,cpuinfo,
@@ -43,16 +43,17 @@ interface
         procedure done_register_allocators;override;
         procedure done_register_allocators;override;
         function  getfpuregister(list:Taasmoutput;size:Tcgsize):Tregister;override;
         function  getfpuregister(list:Taasmoutput;size:Tcgsize):Tregister;override;
         { sparc special, needed by cg64 }
         { sparc special, needed by cg64 }
+        procedure make_simple_ref(list:taasmoutput;var ref: treference);
         procedure handle_load_store(list:taasmoutput;isstore:boolean;op: tasmop;reg:tregister;ref: treference);
         procedure handle_load_store(list:taasmoutput;isstore:boolean;op: tasmop;reg:tregister;ref: treference);
         procedure handle_reg_const_reg(list:taasmoutput;op:Tasmop;src:tregister;a:aint;dst:tregister);
         procedure handle_reg_const_reg(list:taasmoutput;op:Tasmop;src:tregister;a:aint;dst:tregister);
         { parameter }
         { parameter }
-        procedure a_param_const(list:TAasmOutput;size:tcgsize;a:aint;const LocPara:TParaLocation);override;
-        procedure a_param_ref(list:TAasmOutput;sz:tcgsize;const r:TReference;const LocPara:TParaLocation);override;
-        procedure a_paramaddr_ref(list:TAasmOutput;const r:TReference;const LocPara:TParaLocation);override;
-        procedure a_paramfpu_reg(list : taasmoutput;size : tcgsize;const r : tregister;const locpara : tparalocation);override;
-        procedure a_paramfpu_ref(list : taasmoutput;size : tcgsize;const ref : treference;const locpara : tparalocation);override;
-        procedure a_loadany_param_ref(list : taasmoutput;const locpara : tparalocation;const ref:treference;shuffle : pmmshuffle);override;
-        procedure a_loadany_param_reg(list : taasmoutput;const locpara : tparalocation;const reg:tregister;shuffle : pmmshuffle);override;
+        procedure a_param_const(list:TAasmOutput;size:tcgsize;a:aint;const paraloc:TCGPara);override;
+        procedure a_param_ref(list:TAasmOutput;sz:tcgsize;const r:TReference;const paraloc:TCGPara);override;
+        procedure a_paramaddr_ref(list:TAasmOutput;const r:TReference;const paraloc:TCGPara);override;
+        procedure a_paramfpu_reg(list : taasmoutput;size : tcgsize;const r : tregister;const paraloc : TCGPara);override;
+        procedure a_paramfpu_ref(list : taasmoutput;size : tcgsize;const ref : treference;const paraloc : TCGPara);override;
+//        procedure a_loadany_param_ref(list : taasmoutput;const paraloc : TCGPara;const ref:treference;shuffle : pmmshuffle);override;
+        procedure a_loadany_param_reg(list : taasmoutput;const paraloc : TCGPara;const reg:tregister;shuffle : pmmshuffle);override;
         procedure a_call_name(list:TAasmOutput;const s:string);override;
         procedure a_call_name(list:TAasmOutput;const s:string);override;
         procedure a_call_reg(list:TAasmOutput;Reg:TRegister);override;
         procedure a_call_reg(list:TAasmOutput;Reg:TRegister);override;
         { General purpose instructions }
         { General purpose instructions }
@@ -81,7 +82,7 @@ interface
         procedure g_overflowCheck(List:TAasmOutput;const Loc:TLocation;def:TDef);override;
         procedure g_overflowCheck(List:TAasmOutput;const Loc:TLocation;def:TDef);override;
         procedure g_proc_entry(list : taasmoutput;localsize : longint;nostackframe:boolean);override;
         procedure g_proc_entry(list : taasmoutput;localsize : longint;nostackframe:boolean);override;
         procedure g_proc_exit(list : taasmoutput;parasize:longint;nostackframe:boolean);override;
         procedure g_proc_exit(list : taasmoutput;parasize:longint;nostackframe:boolean);override;
-        procedure g_restore_all_registers(list:TAasmOutput;const funcretparaloc:tparalocation);override;
+        procedure g_restore_all_registers(list:TAasmOutput;const funcretparaloc:TCGPara);override;
         procedure g_restore_standard_registers(list:taasmoutput);override;
         procedure g_restore_standard_registers(list:taasmoutput);override;
         procedure g_save_all_registers(list : taasmoutput);override;
         procedure g_save_all_registers(list : taasmoutput);override;
         procedure g_save_standard_registers(list : taasmoutput);override;
         procedure g_save_standard_registers(list : taasmoutput);override;
@@ -92,6 +93,9 @@ interface
       private
       private
         procedure get_64bit_ops(op:TOpCG;var op1,op2:TAsmOp);
         procedure get_64bit_ops(op:TOpCG;var op1,op2:TAsmOp);
       public
       public
+        procedure a_load64_reg_ref(list : taasmoutput;reg : tregister64;const ref : treference);override;
+        procedure a_load64_ref_reg(list : taasmoutput;const ref : treference;reg : tregister64);override;
+        procedure a_param64_ref(list : taasmoutput;const r : treference;const paraloc : tcgpara);override;
         procedure a_op64_reg_reg(list:TAasmOutput;op:TOpCG;regsrc,regdst:TRegister64);override;
         procedure a_op64_reg_reg(list:TAasmOutput;op:TOpCG;regsrc,regdst:TRegister64);override;
         procedure a_op64_const_reg(list:TAasmOutput;op:TOpCG;value:int64;regdst:TRegister64);override;
         procedure a_op64_const_reg(list:TAasmOutput;op:TOpCG;value:int64;regdst:TRegister64);override;
         procedure a_op64_const_reg_reg(list: taasmoutput;op:TOpCG;value : int64;regsrc,regdst : tregister64);override;
         procedure a_op64_const_reg_reg(list: taasmoutput;op:TOpCG;value : int64;regsrc,regdst : tregister64);override;
@@ -132,7 +136,7 @@ implementation
       end;
       end;
 
 
 
 
-    procedure tcgsparc.handle_load_store(list:taasmoutput;isstore:boolean;op: tasmop;reg:tregister;ref: treference);
+    procedure tcgsparc.make_simple_ref(list:taasmoutput;var ref: treference);
       var
       var
         tmpreg : tregister;
         tmpreg : tregister;
         tmpref : treference;
         tmpref : treference;
@@ -191,12 +195,16 @@ implementation
                 ref.index:=NR_NO;
                 ref.index:=NR_NO;
               end;
               end;
           end;
           end;
+      end;
+
+
+    procedure tcgsparc.handle_load_store(list:taasmoutput;isstore:boolean;op: tasmop;reg:tregister;ref: treference);
+      begin
+        make_simple_ref(list,ref);
         if isstore then
         if isstore then
           list.concat(taicpu.op_reg_ref(op,reg,ref))
           list.concat(taicpu.op_reg_ref(op,reg,ref))
         else
         else
           list.concat(taicpu.op_ref_reg(op,ref,reg));
           list.concat(taicpu.op_ref_reg(op,ref,reg));
-        if (tmpreg<>NR_NO) then
-          UnGetRegister(list,tmpreg);
       end;
       end;
 
 
 
 
@@ -254,20 +262,23 @@ implementation
       end;
       end;
 
 
 
 
-    procedure TCgSparc.a_param_const(list:TAasmOutput;size:tcgsize;a:aint;const LocPara:TParaLocation);
+    procedure TCgSparc.a_param_const(list:TAasmOutput;size:tcgsize;a:aint;const paraloc:TCGPara);
       var
       var
         Ref:TReference;
         Ref:TReference;
       begin
       begin
-        case locpara.loc of
+        paraloc.check_simple_location;
+        case paraloc.location^.loc of
           LOC_REGISTER,LOC_CREGISTER:
           LOC_REGISTER,LOC_CREGISTER:
-            a_load_const_reg(list,size,a,locpara.register);
+            a_load_const_reg(list,size,a,paraloc.location^.register);
           LOC_REFERENCE:
           LOC_REFERENCE:
             begin
             begin
               { Code conventions need the parameters being allocated in %o6+92 }
               { Code conventions need the parameters being allocated in %o6+92 }
-              with LocPara.Reference do
-                if(Index=NR_SP)and(Offset<Target_info.first_parm_offset) then
-                InternalError(2002081104);
-              reference_reset_base(ref,locpara.reference.index,locpara.reference.offset);
+              with paraloc.location^.Reference do
+                begin
+                  if (Index=NR_SP) and (Offset<Target_info.first_parm_offset) then
+                    InternalError(2002081104);
+                  reference_reset_base(ref,index,offset);
+                end;
               a_load_const_ref(list,size,a,ref);
               a_load_const_ref(list,size,a,ref);
             end;
             end;
           else
           else
@@ -276,137 +287,170 @@ implementation
       end;
       end;
 
 
 
 
-    procedure TCgSparc.a_param_ref(list:TAasmOutput;sz:TCgSize;const r:TReference;const LocPara:TParaLocation);
+    procedure TCgSparc.a_param_ref(list:TAasmOutput;sz:TCgSize;const r:TReference;const paraloc:TCGPara);
       var
       var
         ref: treference;
         ref: treference;
         tmpreg:TRegister;
         tmpreg:TRegister;
       begin
       begin
-        with LocPara do
-          case loc of
-            LOC_REGISTER,LOC_CREGISTER :
-              a_load_ref_reg(list,sz,sz,r,Register);
-            LOC_REFERENCE:
-              begin
-                { Code conventions need the parameters being allocated in %o6+92 }
-                with LocPara.Reference do
-                  if(Index=NR_SP)and(Offset<Target_info.first_parm_offset) then
-                  InternalError(2002081104);
-                reference_reset_base(ref,locpara.reference.index,locpara.reference.offset);
-                tmpreg:=GetIntRegister(list,OS_INT);
-                a_load_ref_reg(list,sz,sz,r,tmpreg);
-                a_load_reg_ref(list,sz,sz,tmpreg,ref);
-                UnGetRegister(list,tmpreg);
-              end;
-            else
-              internalerror(2002081103);
+        paraloc.check_simple_location;
+        with paraloc.location^ do
+          begin
+            case loc of
+              LOC_REGISTER,LOC_CREGISTER :
+                a_load_ref_reg(list,sz,sz,r,Register);
+              LOC_REFERENCE:
+                begin
+                  { Code conventions need the parameters being allocated in %o6+92 }
+                  with Reference do
+                    begin
+                      if (Index=NR_SP) and (Offset<Target_info.first_parm_offset) then
+                        InternalError(2002081104);
+                      reference_reset_base(ref,index,offset);
+                    end;
+                  tmpreg:=GetIntRegister(list,OS_INT);
+                  a_load_ref_reg(list,sz,sz,r,tmpreg);
+                  a_load_reg_ref(list,sz,sz,tmpreg,ref);
+                  UnGetRegister(list,tmpreg);
+                end;
+              else
+                internalerror(2002081103);
+            end;
           end;
           end;
       end;
       end;
 
 
 
 
-    procedure TCgSparc.a_paramaddr_ref(list:TAasmOutput;const r:TReference;const LocPara:TParaLocation);
+    procedure TCgSparc.a_paramaddr_ref(list:TAasmOutput;const r:TReference;const paraloc:TCGPara);
       var
       var
         Ref:TReference;
         Ref:TReference;
         TmpReg:TRegister;
         TmpReg:TRegister;
       begin
       begin
-        case locpara.loc of
-          LOC_REGISTER,LOC_CREGISTER:
-            a_loadaddr_ref_reg(list,r,locpara.register);
-          LOC_REFERENCE:
-            begin
-              reference_reset(ref);
-              ref.base := locpara.reference.index;
-              ref.offset := locpara.reference.offset;
-              tmpreg:=GetAddressRegister(list);
-              a_loadaddr_ref_reg(list,r,tmpreg);
-              a_load_reg_ref(list,OS_ADDR,OS_ADDR,tmpreg,ref);
-              UnGetRegister(list,tmpreg);
+        paraloc.check_simple_location;
+        with paraloc.location^ do
+          begin
+            case loc of
+              LOC_REGISTER,LOC_CREGISTER:
+                a_loadaddr_ref_reg(list,r,register);
+              LOC_REFERENCE:
+                begin
+                  reference_reset(ref);
+                  ref.base := reference.index;
+                  ref.offset := reference.offset;
+                  tmpreg:=GetAddressRegister(list);
+                  a_loadaddr_ref_reg(list,r,tmpreg);
+                  a_load_reg_ref(list,OS_ADDR,OS_ADDR,tmpreg,ref);
+                  UnGetRegister(list,tmpreg);
+                end;
+              else
+                internalerror(2002080701);
             end;
             end;
-          else
-            internalerror(2002080701);
-        end;
+          end;
       end;
       end;
 
 
 
 
-    procedure tcgsparc.a_paramfpu_reg(list : taasmoutput;size : tcgsize;const r : tregister;const locpara : tparalocation);
+    procedure tcgsparc.a_paramfpu_ref(list : taasmoutput;size : tcgsize;const ref : treference;const paraloc : TCGPara);
+      var
+         href,href2 : treference;
+         hloc : pcgparalocation;
+      begin
+        href:=ref;
+        hloc:=paraloc.location;
+        while assigned(hloc) do
+          begin
+            case hloc^.loc of
+              LOC_REGISTER :
+                a_load_ref_reg(list,hloc^.size,hloc^.size,href,hloc^.register);
+              LOC_REFERENCE :
+                begin
+                  reference_reset_base(href2,hloc^.reference.index,hloc^.reference.offset);
+                  a_load_ref_ref(list,hloc^.size,hloc^.size,href,href2);
+                end;
+              else
+                internalerror(200408241);
+           end;
+           inc(href.offset,tcgsize2size[hloc^.size]);
+           hloc:=hloc^.next;
+         end;
+      end;
+
+
+    procedure tcgsparc.a_paramfpu_reg(list : taasmoutput;size : tcgsize;const r : tregister;const paraloc : TCGPara);
       var
       var
         href : treference;
         href : treference;
       begin
       begin
         tg.GetTemp(list,TCGSize2Size[size],tt_normal,href);
         tg.GetTemp(list,TCGSize2Size[size],tt_normal,href);
         a_loadfpu_reg_ref(list,size,r,href);
         a_loadfpu_reg_ref(list,size,r,href);
-        a_paramfpu_ref(list,size,href,locpara);
+        a_paramfpu_ref(list,size,href,paraloc);
         tg.Ungettemp(list,href);
         tg.Ungettemp(list,href);
       end;
       end;
 
 
 
 
-    procedure tcgsparc.a_paramfpu_ref(list : taasmoutput;size : tcgsize;const ref : treference;const locpara : tparalocation);
+      (*
+    procedure tcgsparc.a_paramfpu_ref(list : taasmoutput;size : tcgsize;const ref : treference;const paraloc : TCGPara);
       var
       var
-        templocpara : tparalocation;
+        tempparaloc : TCGPara;
       begin
       begin
         { floats are pushed in the int registers }
         { floats are pushed in the int registers }
-        templocpara:=locpara;
-        case locpara.size of
+        tempparaloc:=paraloc;
+        case paraloc.size of
           OS_F32,OS_32 :
           OS_F32,OS_32 :
             begin
             begin
-              templocpara.size:=OS_32;
-              a_param_ref(list,OS_32,ref,templocpara);
+              tempparaloc.size:=OS_32;
+              a_param_ref(list,OS_32,ref,tempparaloc);
             end;
             end;
           OS_F64,OS_64 :
           OS_F64,OS_64 :
             begin
             begin
-              templocpara.size:=OS_64;
-              cg64.a_param64_ref(list,ref,templocpara);
+              tempparaloc.size:=OS_64;
+              cg64.a_param64_ref(list,ref,tempparaloc);
             end;
             end;
           else
           else
             internalerror(200307021);
             internalerror(200307021);
         end;
         end;
       end;
       end;
 
 
-
-    procedure tcgsparc.a_loadany_param_ref(list : taasmoutput;const locpara : tparalocation;const ref:treference;shuffle : pmmshuffle);
+    procedure tcgsparc.a_loadany_param_ref(list : taasmoutput;const paraloc : TCGPara;const ref:treference;shuffle : pmmshuffle);
       var
       var
         href,
         href,
         tempref : treference;
         tempref : treference;
-        templocpara : tparalocation;
+        tempparaloc : TCGPara;
       begin
       begin
         { Load floats like ints }
         { Load floats like ints }
-        templocpara:=locpara;
-        case locpara.size of
+        tempparaloc:=paraloc;
+        case paraloc.size of
           OS_F32 :
           OS_F32 :
-            templocpara.size:=OS_32;
+            tempparaloc.size:=OS_32;
           OS_F64 :
           OS_F64 :
-            templocpara.size:=OS_64;
+            tempparaloc.size:=OS_64;
         end;
         end;
         { Word 0 is in register, word 1 is in reference }
         { Word 0 is in register, word 1 is in reference }
-        if (templocpara.loc=LOC_REFERENCE) and (templocpara.low_in_reg) then
+        if (tempparaloc.loc=LOC_REFERENCE) and (tempparaloc.low_in_reg) then
           begin
           begin
             tempref:=ref;
             tempref:=ref;
-            cg.a_load_reg_ref(list,OS_INT,OS_INT,templocpara.register,tempref);
+            cg.a_load_reg_ref(list,OS_INT,OS_INT,tempparaloc.register,tempref);
             inc(tempref.offset,4);
             inc(tempref.offset,4);
-            reference_reset_base(href,templocpara.reference.index,templocpara.reference.offset);
+            reference_reset_base(href,tempparaloc.reference.index,tempparaloc.reference.offset);
             cg.a_load_ref_ref(list,OS_INT,OS_INT,href,tempref);
             cg.a_load_ref_ref(list,OS_INT,OS_INT,href,tempref);
           end
           end
         else
         else
-          inherited a_loadany_param_ref(list,templocpara,ref,shuffle);
+          inherited a_loadany_param_ref(list,tempparaloc,ref,shuffle);
       end;
       end;
+*)
 
 
 
 
-    procedure tcgsparc.a_loadany_param_reg(list : taasmoutput;const locpara : tparalocation;const reg:tregister;shuffle : pmmshuffle);
+    procedure tcgsparc.a_loadany_param_reg(list : taasmoutput;const paraloc : TCGPara;const reg:tregister;shuffle : pmmshuffle);
       var
       var
         href : treference;
         href : treference;
       begin
       begin
-        { Word 0 is in register, word 1 is in reference, not
-          possible to load it in 1 register }
-        if (locpara.loc=LOC_REFERENCE) and (locpara.low_in_reg) then
-          internalerror(200307011);
+        paraloc.check_simple_location;
         { Float load use a temp reference }
         { Float load use a temp reference }
-        if locpara.size in [OS_F32,OS_F64] then
+        if getregtype(reg)=R_FPUREGISTER then
           begin
           begin
-            tg.GetTemp(list,TCGSize2Size[locpara.size],tt_normal,href);
-            a_loadany_param_ref(list,locpara,href,shuffle);
-            a_loadfpu_ref_reg(list,locpara.size,href,reg);
+            tg.GetTemp(list,TCGSize2Size[paraloc.size],tt_normal,href);
+            a_loadany_param_ref(list,paraloc,href,shuffle);
+            a_loadfpu_ref_reg(list,paraloc.size,href,reg);
             tg.Ungettemp(list,href);
             tg.Ungettemp(list,href);
           end
           end
         else
         else
-          inherited a_loadany_param_reg(list,locpara,reg,shuffle);
+          inherited a_loadany_param_reg(list,paraloc,reg,shuffle);
       end;
       end;
 
 
 
 
@@ -458,9 +502,11 @@ implementation
 
 
     procedure TCgSparc.a_load_reg_ref(list:TAasmOutput;FromSize,ToSize:TCGSize;reg:tregister;const Ref:TReference);
     procedure TCgSparc.a_load_reg_ref(list:TAasmOutput;FromSize,ToSize:TCGSize;reg:tregister;const Ref:TReference);
       var
       var
-        op:tasmop;
+        op : tasmop;
       begin
       begin
-        case ToSize of
+        if (TCGSize2Size[fromsize] >= TCGSize2Size[tosize]) then
+          fromsize := tosize;
+        case fromsize of
           { signed integer registers }
           { signed integer registers }
           OS_8,
           OS_8,
           OS_S8:
           OS_S8:
@@ -480,10 +526,11 @@ implementation
 
 
     procedure TCgSparc.a_load_ref_reg(list:TAasmOutput;FromSize,ToSize:TCgSize;const ref:TReference;reg:tregister);
     procedure TCgSparc.a_load_ref_reg(list:TAasmOutput;FromSize,ToSize:TCgSize;const ref:TReference;reg:tregister);
       var
       var
-        op:tasmop;
+        op : tasmop;
       begin
       begin
-        case Fromsize of
-          { signed integer registers }
+        if (TCGSize2Size[fromsize] >= TCGSize2Size[tosize]) then
+          fromsize := tosize;
+        case fromsize of
           OS_S8:
           OS_S8:
             Op:=A_LDSB;{Load Signed Byte}
             Op:=A_LDSB;{Load Signed Byte}
           OS_8:
           OS_8:
@@ -506,6 +553,8 @@ implementation
 
 
 
 
     procedure TCgSparc.a_load_reg_reg(list:TAasmOutput;fromsize,tosize:tcgsize;reg1,reg2:tregister);
     procedure TCgSparc.a_load_reg_reg(list:TAasmOutput;fromsize,tosize:tcgsize;reg1,reg2:tregister);
+      var
+        instr : taicpu;
       begin
       begin
         if (tcgsize2size[tosize]<tcgsize2size[fromsize]) or
         if (tcgsize2size[tosize]<tcgsize2size[fromsize]) or
            (
            (
@@ -514,16 +563,32 @@ implementation
             not(fromsize in [OS_32,OS_S32])
             not(fromsize in [OS_32,OS_S32])
            ) then
            ) then
           begin
           begin
-{$warning TODO Sign extension}
             case tosize of
             case tosize of
-              OS_8,OS_S8:
+              OS_8 :
                 a_op_const_reg_reg(list,OP_AND,tosize,$ff,reg1,reg2);
                 a_op_const_reg_reg(list,OP_AND,tosize,$ff,reg1,reg2);
-              OS_16,OS_S16:
+              OS_16 :
                 a_op_const_reg_reg(list,OP_AND,tosize,$ffff,reg1,reg2);
                 a_op_const_reg_reg(list,OP_AND,tosize,$ffff,reg1,reg2);
-              OS_32,OS_S32:
+              OS_32,
+              OS_S32 :
                 begin
                 begin
                   if reg1<>reg2 then
                   if reg1<>reg2 then
-                    list.Concat(taicpu.op_reg_reg(A_MOV,reg1,reg2));
+                    begin
+                      instr:=taicpu.op_reg_reg(A_MOV,reg1,reg2);
+                      list.Concat(instr);
+                      { Notify the register allocator that we have written a move instruction so
+                        it can try to eliminate it. }
+                      add_move_instruction(instr);
+                    end;
+                end;
+              OS_S8 :
+                begin
+                  list.concat(taicpu.op_reg_const_reg(A_SLL,reg1,24,reg2));
+                  list.concat(taicpu.op_reg_const_reg(A_SRA,reg2,24,reg2));
+                end;
+              OS_S16 :
+                begin
+                  list.concat(taicpu.op_reg_const_reg(A_SLL,reg1,16,reg2));
+                  list.concat(taicpu.op_reg_const_reg(A_SRA,reg2,16,reg2));
                 end;
                 end;
               else
               else
                 internalerror(2002090901);
                 internalerror(2002090901);
@@ -533,7 +598,13 @@ implementation
           begin
           begin
             { same size, only a register mov required }
             { same size, only a register mov required }
             if reg1<>reg2 then
             if reg1<>reg2 then
-              list.Concat(taicpu.op_reg_reg(A_MOV,reg1,reg2));
+              begin
+                instr:=taicpu.op_reg_reg(A_MOV,reg1,reg2);
+                list.Concat(instr);
+                { Notify the register allocator that we have written a move instruction so
+                  it can try to eliminate it. }
+                add_move_instruction(instr);
+              end;
           end;
           end;
       end;
       end;
 
 
@@ -550,10 +621,7 @@ implementation
            (ref.offset<simm13lo) or
            (ref.offset<simm13lo) or
            (ref.offset>simm13hi) then
            (ref.offset>simm13hi) then
           begin
           begin
-            if (ref.base<>r) and (ref.index<>r) then
-              hreg:=r
-            else
-              hreg:=GetAddressRegister(list);
+            hreg:=GetAddressRegister(list);
             reference_reset(tmpref);
             reference_reset(tmpref);
             tmpref.symbol := ref.symbol;
             tmpref.symbol := ref.symbol;
             tmpref.offset := ref.offset;
             tmpref.offset := ref.offset;
@@ -575,7 +643,7 @@ implementation
             else
             else
               begin
               begin
                 if hreg<>r then
                 if hreg<>r then
-                  list.Concat(taicpu.op_reg_reg(A_MOV,hreg,r));
+                  a_load_reg_reg(list,OS_ADDR,OS_ADDR,hreg,r);
               end;
               end;
             if hreg<>r then
             if hreg<>r then
               UnGetRegister(list,hreg);
               UnGetRegister(list,hreg);
@@ -588,14 +656,9 @@ implementation
                 begin
                 begin
                   if ref.index<>NR_NO then
                   if ref.index<>NR_NO then
                     begin
                     begin
-                      if (ref.base<>r) and (ref.index<>r) then
-                        hreg:=r
-                      else
-                        hreg:=GetAddressRegister(list);
+                      hreg:=GetAddressRegister(list);
                       list.concat(taicpu.op_reg_const_reg(A_ADD,ref.base,ref.offset,hreg));
                       list.concat(taicpu.op_reg_const_reg(A_ADD,ref.base,ref.offset,hreg));
                       list.concat(taicpu.op_reg_reg_reg(A_ADD,hreg,ref.index,r));
                       list.concat(taicpu.op_reg_reg_reg(A_ADD,hreg,ref.index,r));
-                      if hreg<>r then
-                        UnGetRegister(list,hreg);
                     end
                     end
                   else
                   else
                     list.concat(taicpu.op_reg_const_reg(A_ADD,ref.base,ref.offset,r));
                     list.concat(taicpu.op_reg_const_reg(A_ADD,ref.base,ref.offset,r));
@@ -621,9 +684,17 @@ implementation
       const
       const
          FpuMovInstr : Array[OS_F32..OS_F64] of TAsmOp =
          FpuMovInstr : Array[OS_F32..OS_F64] of TAsmOp =
            (A_FMOVS,A_FMOVD);
            (A_FMOVS,A_FMOVD);
+      var
+        instr : taicpu;
       begin
       begin
         if reg1<>reg2 then
         if reg1<>reg2 then
-          list.concat(taicpu.op_reg_reg(fpumovinstr[size],reg1,reg2));
+          begin
+            instr:=taicpu.op_reg_reg(fpumovinstr[size],reg1,reg2);
+            list.Concat(instr);
+            { Notify the register allocator that we have written a move instruction so
+              it can try to eliminate it. }
+            add_move_instruction(instr);
+          end;
       end;
       end;
 
 
 
 
@@ -677,11 +748,24 @@ implementation
 
 
 
 
     procedure TCgSparc.a_op_reg_reg(list:TAasmOutput;Op:TOpCG;size:TCGSize;src, dst:TRegister);
     procedure TCgSparc.a_op_reg_reg(list:TAasmOutput;Op:TOpCG;size:TCGSize;src, dst:TRegister);
+      var
+        a : aint;
       begin
       begin
         Case Op of
         Case Op of
-          OP_NEG,
-          OP_NOT:
+          OP_NEG :
             list.concat(taicpu.op_reg_reg(TOpCG2AsmOp[op],src,dst));
             list.concat(taicpu.op_reg_reg(TOpCG2AsmOp[op],src,dst));
+          OP_NOT :
+            begin
+              case size of
+                OS_8 :
+                  a:=aint($ffffff00);
+                OS_16 :
+                  a:=aint($ffff0000);
+                else
+                  a:=0;
+              end;
+              handle_reg_const_reg(list,A_XNOR,src,a,dst);
+            end;
           else
           else
             list.concat(taicpu.op_reg_reg_reg(TOpCG2AsmOp[op],dst,src,dst));
             list.concat(taicpu.op_reg_reg_reg(TOpCG2AsmOp[op],dst,src,dst));
         end;
         end;
@@ -838,7 +922,7 @@ implementation
       end;
       end;
 
 
 
 
-    procedure TCgSparc.g_restore_all_registers(list:TaasmOutput;const funcretparaloc:tparalocation);
+    procedure TCgSparc.g_restore_all_registers(list:TaasmOutput;const funcretparaloc:TCGPara);
       begin
       begin
         { The sparc port uses the sparc standard calling convetions so this function has no used }
         { The sparc port uses the sparc standard calling convetions so this function has no used }
       end;
       end;
@@ -999,6 +1083,46 @@ implementation
                                TCG64Sparc
                                TCG64Sparc
 ****************************************************************************}
 ****************************************************************************}
 
 
+
+    procedure tcg64sparc.a_load64_reg_ref(list : taasmoutput;reg : tregister64;const ref : treference);
+      var
+        tmpref: treference;
+      begin
+        { Override this function to prevent loading the reference twice }
+        tmpref:=ref;
+        tcgsparc(cg).make_simple_ref(list,tmpref);
+        cg.a_load_reg_ref(list,OS_32,OS_32,reg.reghi,tmpref);
+        inc(tmpref.offset,4);
+        cg.a_load_reg_ref(list,OS_32,OS_32,reg.reglo,tmpref);
+      end;
+
+
+    procedure tcg64sparc.a_load64_ref_reg(list : taasmoutput;const ref : treference;reg : tregister64);
+      var
+        tmpref: treference;
+      begin
+        { Override this function to prevent loading the reference twice }
+        tmpref:=ref;
+        tcgsparc(cg).make_simple_ref(list,tmpref);
+        cg.a_load_ref_reg(list,OS_32,OS_32,tmpref,reg.reghi);
+        inc(tmpref.offset,4);
+        cg.a_load_ref_reg(list,OS_32,OS_32,tmpref,reg.reglo);
+      end;
+
+
+    procedure tcg64sparc.a_param64_ref(list : taasmoutput;const r : treference;const paraloc : tcgpara);
+      var
+        hreg64 : tregister64;
+      begin
+        { Override this function to prevent loading the reference twice.
+          Use here some extra registers, but those are optimized away by the RA }
+        hreg64.reglo:=cg.GetIntRegister(list,OS_32);
+        hreg64.reghi:=cg.GetIntRegister(list,OS_32);
+        a_load64_ref_reg(list,r,hreg64);
+        a_param64_reg(list,hreg64,paraloc);
+      end;
+
+
     procedure TCg64Sparc.get_64bit_ops(op:TOpCG;var op1,op2:TAsmOp);
     procedure TCg64Sparc.get_64bit_ops(op:TOpCG;var op1,op2:TAsmOp);
       begin
       begin
         case op of
         case op of
@@ -1040,9 +1164,9 @@ implementation
         case op of
         case op of
           OP_NEG :
           OP_NEG :
             begin
             begin
-              list.concat(taicpu.op_reg_reg_reg(A_XNOR,NR_G0,regsrc.reghi,regdst.reghi));
+              { Use the simple code: y=0-z }
               list.concat(taicpu.op_reg_reg_reg(A_SUBcc,NR_G0,regsrc.reglo,regdst.reglo));
               list.concat(taicpu.op_reg_reg_reg(A_SUBcc,NR_G0,regsrc.reglo,regdst.reglo));
-              list.concat(taicpu.op_reg_const_reg(A_ADDX,regdst.reglo,-1,regdst.reglo));
+              list.concat(taicpu.op_reg_reg_reg(A_SUBX,NR_G0,regsrc.reghi,regdst.reghi));
               exit;
               exit;
             end;
             end;
           OP_NOT :
           OP_NOT :
@@ -1109,7 +1233,28 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.86  2004-08-25 20:40:04  florian
+  Revision 1.87  2004-09-21 17:25:13  peter
+    * paraloc branch merged
+
+  Revision 1.86.4.5  2004/09/20 20:43:15  peter
+    * implement reg_ref/ref_reg for 64bit to prevent loading the
+      address symbol twice
+
+  Revision 1.86.4.4  2004/09/17 17:19:26  peter
+    * fixed 64 bit unaryminus for sparc
+    * fixed 64 bit inlining
+    * signness of not operation
+
+  Revision 1.86.4.3  2004/09/12 21:31:03  peter
+    * sign extension added
+
+  Revision 1.86.4.2  2004/09/12 13:36:40  peter
+    * fixed alignment issues
+
+  Revision 1.86.4.1  2004/08/31 20:43:06  peter
+    * paraloc patch
+
+  Revision 1.86  2004/08/25 20:40:04  florian
     * fixed absolute on sparc
     * fixed absolute on sparc
 
 
   Revision 1.85  2004/08/24 21:02:32  florian
   Revision 1.85  2004/08/24 21:02:32  florian

+ 15 - 70
compiler/sparc/cpubase.pas

@@ -20,8 +20,6 @@
 
 
  ****************************************************************************
  ****************************************************************************
 }
 }
-{ This Unit contains the base types for the PowerPC
-}
 unit cpubase;
 unit cpubase;
 
 
 {$i fpcdefs.inc}
 {$i fpcdefs.inc}
@@ -164,8 +162,6 @@ uses
 *****************************************************************************}
 *****************************************************************************}
 
 
     type
     type
-      TRefOptions=(ref_none,ref_parafixup,ref_localfixup,ref_selffixup);
-
       { reference record }
       { reference record }
       preference = ^treference;
       preference = ^treference;
       treference = record
       treference = record
@@ -174,91 +170,33 @@ uses
          { index register, R_NO if none }
          { index register, R_NO if none }
          index       : tregister;
          index       : tregister;
          { offset, 0 if none }
          { offset, 0 if none }
-         offset      : longint;
+         offset      : aint;
          { symbol this reference refers to, nil if none }
          { symbol this reference refers to, nil if none }
          symbol      : tasmsymbol;
          symbol      : tasmsymbol;
          { symbol the symbol of this reference is relative to, nil if none }
          { symbol the symbol of this reference is relative to, nil if none }
-         relsymbol      : tasmsymbol;
+         relsymbol   : tasmsymbol;
          { reference type addr or symbol itself }
          { reference type addr or symbol itself }
-         refaddr : trefaddr;
-         { used in conjunction with the previous field }
-         options     : trefoptions;
-         { alignment this reference is guaranteed to have }
-         alignment   : byte;
+         refaddr     : trefaddr;
       end;
       end;
 
 
       { reference record }
       { reference record }
       pparareference = ^tparareference;
       pparareference = ^tparareference;
       tparareference = packed record
       tparareference = packed record
          index       : tregister;
          index       : tregister;
-         offset      : longint;
+         offset      : aint;
       end;
       end;
 
 
 {*****************************************************************************
 {*****************************************************************************
                                 Operand Sizes
                                 Operand Sizes
 *****************************************************************************}
 *****************************************************************************}
 
 
-{$ifdef dummy}
-{*****************************************************************************
-                             Argument Classification
-*****************************************************************************}
-type
-  TArgClass = (
-     { the following classes should be defined by all processor implemnations }
-     AC_NOCLASS,
-     AC_MEMORY,
-     AC_INTEGER,
-     AC_FPU,
-     { the following argument classes are i386 specific }
-     AC_FPUUP,
-     AC_SSE,
-     AC_SSEUP);
-{$endif dummy}
 
 
 {*****************************************************************************
 {*****************************************************************************
                                Generic Location
                                Generic Location
 *****************************************************************************}
 *****************************************************************************}
 
 
     type
     type
-      { tparamlocation describes where a parameter for a procedure is stored.
-        References are given from the caller's point of view. The usual
-        TLocation isn't used, because contains a lot of unnessary fields.
-      }
-      tparalocation = record
-         Size : TCGSize;
-         { The location type where the parameter is passed, usually
-           LOC_REFERENCE,LOC_REGISTER or LOC_FPUREGISTER
-         }
-         Loc  : TCGLoc;
-         LocHigh : TCGLoc;
-         {Word alignment on stack 4 --> 32 bit}
-         Alignment:Byte;
-         case TCGLoc of
-            LOC_REFERENCE : (reference : tparareference; low_in_reg: boolean; lowreg : tregister);
-            LOC_FPUREGISTER, LOC_CFPUREGISTER, LOC_MMREGISTER, LOC_CMMREGISTER,
-              LOC_REGISTER,LOC_CREGISTER : (
-              case longint of
-                1 : (register,registerhigh : tregister);
-                { overlay a registerlow }
-                2 : (registerlow : tregister);
-                { overlay a 64 Bit register type }
-                3 : (reg64 : tregister64);
-                4 : (register64 : tregister64);
-            );
-      end;
-
-      treglocation = packed record
-        case longint of
-          1 : (register,registerhigh : tregister);
-          { overlay a registerlow }
-          2 : (registerlow : tregister);
-          { overlay a 64 Bit register type }
-          3 : (reg64 : tregister64);
-          4 : (register64 : tregister64);
-       end;
-
-
-      tlocation = record
+      TLocation = record
          size : TCGSize;
          size : TCGSize;
          loc : tcgloc;
          loc : tcgloc;
          case tcgloc of
          case tcgloc of
@@ -272,8 +210,9 @@ type
 {$endif FPC_BIG_ENDIAN}
 {$endif FPC_BIG_ENDIAN}
                 2 : (value64 : int64);
                 2 : (value64 : int64);
               );
               );
-            LOC_FPUREGISTER, LOC_CFPUREGISTER, LOC_MMREGISTER, LOC_CMMREGISTER,
-              LOC_REGISTER,LOC_CREGISTER : (
+            LOC_FPUREGISTER,LOC_CFPUREGISTER,
+            LOC_MMREGISTER,LOC_CMMREGISTER,
+            LOC_REGISTER,LOC_CREGISTER : (
                 case longint of
                 case longint of
                   1 : (registerlow,registerhigh : tregister);
                   1 : (registerlow,registerhigh : tregister);
                   2 : (register : tregister);
                   2 : (register : tregister);
@@ -570,7 +509,13 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.71  2004-08-24 21:02:33  florian
+  Revision 1.72  2004-09-21 17:25:13  peter
+    * paraloc branch merged
+
+  Revision 1.71.4.1  2004/08/31 20:43:06  peter
+    * paraloc patch
+
+  Revision 1.71  2004/08/24 21:02:33  florian
     * fixed longbool(<int64>) on sparc
     * fixed longbool(<int64>) on sparc
 
 
   Revision 1.70  2004/08/15 13:30:18  florian
   Revision 1.70  2004/08/15 13:30:18  florian

+ 18 - 7
compiler/sparc/cpuinfo.pas

@@ -1,8 +1,8 @@
-{******************************************************************************
+{
     $Id$
     $Id$
-    Copyright (c) 1998-2000 by Florian Klaempfl
+    Copyright (c) 1998-2002 by Florian Klaempfl
 
 
-    Basic Processor information
+    Basic Processor information for the SPARC
 
 
     This program is free software; you can redistribute it and/or modify
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     it under the terms of the GNU General Public License as published by
@@ -18,13 +18,17 @@
     along with this program; if not, write to the Free Software
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
 
- ****************************************************************************}
+ ****************************************************************************
+}
 unit cpuinfo;
 unit cpuinfo;
-{$INCLUDE fpcdefs.inc}
+
+{$i fpcdefs.inc}
 
 
 interface
 interface
+
 uses
 uses
   globtype;
   globtype;
+
 type
 type
   bestreal = double;
   bestreal = double;
   ts32real = single;
   ts32real = single;
@@ -51,7 +55,7 @@ const
 { size of the buffer used for setjump/longjmp
 { size of the buffer used for setjump/longjmp
   the size of this buffer is deduced from the
   the size of this buffer is deduced from the
   jmp_buf structure in setjumph.inc file }
   jmp_buf structure in setjumph.inc file }
-  JMP_BUF_SIZE = 12;
+  JMP_BUF_SIZE = 12+16;
 
 
   { calling conventions supported by the code generator }
   { calling conventions supported by the code generator }
   supported_calling_conventions : tproccalloptions = [
   supported_calling_conventions : tproccalloptions = [
@@ -73,12 +77,19 @@ const
      'SOFT',
      'SOFT',
      'HARD'
      'HARD'
    );
    );
+
 implementation
 implementation
 
 
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.18  2004-06-20 08:55:32  florian
+  Revision 1.19  2004-09-21 17:25:13  peter
+    * paraloc branch merged
+
+  Revision 1.18.4.1  2004/09/12 12:04:41  peter
+    * sigset_t is now also in jmp_buf
+
+  Revision 1.18  2004/06/20 08:55:32  florian
     * logs truncated
     * logs truncated
 
 
   Revision 1.17  2004/06/16 20:07:10  florian
   Revision 1.17  2004/06/16 20:07:10  florian

+ 126 - 140
compiler/sparc/cpupara.pas

@@ -29,7 +29,7 @@ interface
       cclasses,
       cclasses,
       aasmtai,
       aasmtai,
       cpubase,cpuinfo,
       cpubase,cpuinfo,
-      symconst,symbase,symtype,symdef,paramgr,cgbase;
+      symconst,symbase,symtype,symdef,paramgr,parabase,cgbase;
 
 
     type
     type
       TSparcParaManager=class(TParaManager)
       TSparcParaManager=class(TParaManager)
@@ -40,12 +40,9 @@ interface
         {Returns a structure giving the information on the storage of the parameter
         {Returns a structure giving the information on the storage of the parameter
         (which must be an integer parameter)
         (which must be an integer parameter)
         @param(nr Parameter number of routine, starting from 1)}
         @param(nr Parameter number of routine, starting from 1)}
-        function  getintparaloc(calloption : tproccalloption; nr : longint) : tparalocation;override;
-        procedure allocparaloc(list: taasmoutput; const loc: tparalocation);override;
-        procedure freeparaloc(list: taasmoutput; const loc: tparalocation);override;
+        procedure getintparaloc(calloption : tproccalloption; nr : longint;var cgpara : TCGPara);override;
         function  create_paraloc_info(p : TAbstractProcDef; side: tcallercallee):longint;override;
         function  create_paraloc_info(p : TAbstractProcDef; side: tcallercallee):longint;override;
-        function create_varargs_paraloc_info(p : TAbstractProcDef; varargspara:tvarargspara):longint;override;
-        procedure splitparaloc64(const locpara:tparalocation;var loclopara,lochipara:tparalocation);override;
+        function  create_varargs_paraloc_info(p : TAbstractProcDef; varargspara:tvarargspara):longint;override;
       private
       private
         procedure create_funcret_paraloc_info(p : tabstractprocdef; side: tcallercallee);
         procedure create_funcret_paraloc_info(p : tabstractprocdef; side: tcallercallee);
         procedure create_paraloc_info_intern(p : tabstractprocdef; side: tcallercallee; firstpara: tparaitem;
         procedure create_paraloc_info_intern(p : tabstractprocdef; side: tcallercallee; firstpara: tparaitem;
@@ -55,7 +52,7 @@ interface
 implementation
 implementation
 
 
     uses
     uses
-      verbose,systems,
+      cutils,verbose,systems,
       defutil,cgobj;
       defutil,cgobj;
 
 
     type
     type
@@ -78,30 +75,34 @@ implementation
       end;
       end;
 
 
 
 
-    function TSparcParaManager.GetIntParaLoc(calloption : tproccalloption; nr : longint) : tparalocation;
+    procedure TSparcParaManager.GetIntParaLoc(calloption : tproccalloption; nr : longint;var cgpara : tcgpara);
+      var
+        paraloc : pcgparalocation;
       begin
       begin
         if nr<1 then
         if nr<1 then
           InternalError(2002100806);
           InternalError(2002100806);
-        FillChar(GetIntParaLoc,SizeOf(TParaLocation),0);
-        result.lochigh:=LOC_INVALID;
-        Dec(nr);
-        with GetIntParaLoc do
-         begin
-           { The six first parameters are passed into registers }
-           if nr<6 then
-            begin
-              loc:=LOC_REGISTER;
-              register:=newreg(R_INTREGISTER,(RS_O0+nr),R_SUBWHOLE);
-            end
-           else
-           { The other parameters are passed on the stack }
-            begin
-              loc:=LOC_REFERENCE;
-              reference.index:=NR_STACK_POINTER_REG;
-              reference.offset:=92+(nr-6)*4;
-            end;
-           size:=OS_INT;
-         end;
+        cgpara.reset;
+        cgpara.size:=OS_INT;
+        cgpara.alignment:=std_param_align;
+        paraloc:=cgpara.add_location;
+        with paraloc^ do
+          begin
+            { The six first parameters are passed into registers }
+            dec(nr);
+            if nr<6 then
+              begin
+                loc:=LOC_REGISTER;
+                register:=newreg(R_INTREGISTER,(RS_O0+nr),R_SUBWHOLE);
+              end
+            else
+              begin
+                { The other parameters are passed on the stack }
+                loc:=LOC_REFERENCE;
+                reference.index:=NR_STACK_POINTER_REG;
+                reference.offset:=92+(nr-6)*4;
+              end;
+            size:=OS_INT;
+          end;
       end;
       end;
 
 
 
 
@@ -141,70 +142,78 @@ implementation
 
 
     procedure tsparcparamanager.create_funcret_paraloc_info(p : tabstractprocdef; side: tcallercallee);
     procedure tsparcparamanager.create_funcret_paraloc_info(p : tabstractprocdef; side: tcallercallee);
       var
       var
-        paraloc : tparalocation;
+        paraloc : pcgparalocation;
+        retcgsize  : tcgsize;
       begin
       begin
-        fillchar(paraloc,sizeof(tparalocation),0);
-        paraloc.size:=def_cgsize(p.rettype.def);
-        paraloc.Alignment:= std_param_align;
-        { Constructors return self }
+        { Constructors return self instead of a boolean }
         if (p.proctypeoption=potype_constructor) then
         if (p.proctypeoption=potype_constructor) then
-          begin
-            paraloc.size:=OS_ADDR;
-            paraloc.loc:=LOC_REGISTER;
-            if side=callerside then
-              paraloc.register:=NR_FUNCTION_RESULT_REG
-            else
-              paraloc.register:=NR_FUNCTION_RETURN_REG;
-          end
+          retcgsize:=OS_ADDR
         else
         else
-         { Return in FPU register? }
-         if p.rettype.def.deftype=floatdef then
+          retcgsize:=def_cgsize(p.rettype.def);
+        p.funcret_paraloc[side].reset;
+        p.funcret_paraloc[side].Alignment:=std_param_align;
+        p.funcret_paraloc[side].size:=retcgsize;
+        { void has no location }
+        if is_void(p.rettype.def) then
+          exit;
+        paraloc:=p.funcret_paraloc[side].add_location;
+        { Return in FPU register? }
+        if p.rettype.def.deftype=floatdef then
           begin
           begin
-            paraloc.loc:=LOC_FPUREGISTER;
-            paraloc.register:=NR_FPU_RESULT_REG;
+            paraloc^.loc:=LOC_FPUREGISTER;
+            paraloc^.register:=NR_FPU_RESULT_REG;
+            paraloc^.size:=retcgsize;
           end
           end
         else
         else
          { Return in register? }
          { Return in register? }
          if not ret_in_param(p.rettype.def,p.proccalloption) then
          if not ret_in_param(p.rettype.def,p.proccalloption) then
           begin
           begin
-            paraloc.loc:=LOC_REGISTER;
 {$ifndef cpu64bit}
 {$ifndef cpu64bit}
-            if paraloc.size in [OS_64,OS_S64] then
+            if retcgsize in [OS_64,OS_S64] then
              begin
              begin
-               paraloc.lochigh:=LOC_REGISTER;
-               if side=callerside then
-                 paraloc.register64.reglo:=NR_FUNCTION_RESULT64_LOW_REG
+               { high }
+               paraloc^.loc:=LOC_REGISTER;
+               paraloc^.size:=OS_32;
+               if (side=callerside)  or (p.proccalloption=pocall_inline)then
+                 paraloc^.register:=NR_FUNCTION_RESULT64_HIGH_REG
                else
                else
-                 paraloc.register64.reglo:=NR_FUNCTION_RETURN64_LOW_REG;
-               if side=callerside then
-                 paraloc.register64.reghi:=NR_FUNCTION_RESULT64_HIGH_REG
+                 paraloc^.register:=NR_FUNCTION_RETURN64_HIGH_REG;
+               { low }
+               paraloc:=p.funcret_paraloc[side].add_location;
+               paraloc^.loc:=LOC_REGISTER;
+               paraloc^.size:=OS_32;
+               if (side=callerside) or (p.proccalloption=pocall_inline) then
+                 paraloc^.register:=NR_FUNCTION_RESULT64_LOW_REG
                else
                else
-                 paraloc.register64.reghi:=NR_FUNCTION_RETURN64_HIGH_REG;
+                 paraloc^.register:=NR_FUNCTION_RETURN64_LOW_REG;
              end
              end
             else
             else
 {$endif cpu64bit}
 {$endif cpu64bit}
              begin
              begin
-               if side=callerside then
-                 paraloc.register:=NR_FUNCTION_RESULT_REG
+               paraloc^.loc:=LOC_REGISTER;
+               paraloc^.size:=retcgsize;
+               if (side=callerside)  or (p.proccalloption=pocall_inline)then
+                 paraloc^.register:=newreg(R_INTREGISTER,RS_FUNCTION_RESULT_REG,cgsize2subreg(retcgsize))
                else
                else
-                 paraloc.register:=NR_FUNCTION_RETURN_REG;
+                 paraloc^.register:=newreg(R_INTREGISTER,RS_FUNCTION_RETURN_REG,cgsize2subreg(retcgsize));
              end;
              end;
           end
           end
         else
         else
           begin
           begin
-            paraloc.loc:=LOC_REFERENCE;
+            paraloc^.loc:=LOC_REFERENCE;
+            paraloc^.size:=retcgsize;
           end;
           end;
-        p.funcret_paraloc[side]:=paraloc;
       end;
       end;
 
 
 
 
     procedure tsparcparamanager.create_paraloc_info_intern(p : tabstractprocdef; side: tcallercallee;firstpara:tparaitem;
     procedure tsparcparamanager.create_paraloc_info_intern(p : tabstractprocdef; side: tcallercallee;firstpara:tparaitem;
                                                            var intparareg,parasize:longint);
                                                            var intparareg,parasize:longint);
       var
       var
-        paraloc : tparalocation;
-        hp : tparaitem;
-        is_64bit: boolean;
+        paraloc      : pcgparalocation;
+        hp           : tparaitem;
+        paracgsize   : tcgsize;
         hparasupregs : pparasupregs;
         hparasupregs : pparasupregs;
+        paralen      : longint;
       begin
       begin
         if side=callerside then
         if side=callerside then
           hparasupregs:=@paraoutsupregs
           hparasupregs:=@paraoutsupregs
@@ -213,52 +222,52 @@ implementation
         hp:=firstpara;
         hp:=firstpara;
         while assigned(hp) do
         while assigned(hp) do
           begin
           begin
-            fillchar(paraloc,sizeof(paraloc),0);
-            paraloc.Alignment:= std_param_align;
-            if push_addr_param(hp.paratyp,hp.paratype.def,p.proccalloption) or (hp.paratyp in [vs_var,vs_out]) then
-              paraloc.size:=OS_ADDR
+            if push_addr_param(hp.paratyp,hp.paratype.def,p.proccalloption) then
+              paracgsize:=OS_ADDR
             else
             else
               begin
               begin
-                paraloc.size:=def_cgSize(hp.paratype.def);
-                if paraloc.size=OS_NO then
-                  paraloc.size:=OS_ADDR;
+                paracgsize:=def_cgSize(hp.paratype.def);
+                if paracgsize=OS_NO then
+                  paracgsize:=OS_ADDR;
               end;
               end;
-            is_64bit:=(paraloc.size in [OS_64,OS_S64,OS_F64]);
-            if (intparareg<=high(tparasupregs)-ord(is_64bit)) then
-              begin
-                paraloc.loc:=LOC_REGISTER;
-                { big endian }
-                if is_64bit then
-                  begin
-                    paraloc.registerhigh:=newreg(R_INTREGISTER,hparasupregs^[intparareg],R_SUBWHOLE);
-                    paraloc.lochigh:=LOC_REGISTER;
-                    inc(intparareg);
-                  end;
-                paraloc.registerlow:=newreg(R_INTREGISTER,hparasupregs^[intparareg],R_SUBWHOLE);
-                inc(intparareg);
-              end
-            else
+            { Floats are passed in int registers }
+            case paracgsize of
+              OS_F32 :
+                paracgsize:=OS_32;
+              OS_F64 :
+                paracgsize:=OS_64;
+            end;
+            hp.paraloc[side].reset;
+            hp.paraloc[side].size:=paracgsize;
+            hp.paraloc[side].Alignment:=std_param_align;
+            paralen:=tcgsize2size[paracgsize];
+            while (paralen>0) do
               begin
               begin
-                paraloc.loc:=LOC_REFERENCE;
-                { Low part need to be in O5 if still available }
+                paraloc:=hp.paraloc[side].add_location;
+                { We can allocate at maximum 32 bits per register }
+                if paracgsize in [OS_64,OS_S64] then
+                  paraloc^.size:=OS_32
+                else
+                  paraloc^.size:=paracgsize;
                 if (intparareg<=high(tparasupregs)) then
                 if (intparareg<=high(tparasupregs)) then
                   begin
                   begin
-                    paraloc.low_in_reg:=true;
-                    paraloc.lowreg:=newreg(R_INTREGISTER,hparasupregs^[intparareg],R_SUBWHOLE);
+                    paraloc^.loc:=LOC_REGISTER;
+                    paraloc^.register:=newreg(R_INTREGISTER,hparasupregs^[intparareg],R_SUBWHOLE);
                     inc(intparareg);
                     inc(intparareg);
-                  end;
-                if side=callerside then
-                  paraloc.reference.index:=NR_STACK_POINTER_REG
-                else
-                  paraloc.reference.index:=NR_FRAME_POINTER_REG;
-                paraloc.reference.offset:=target_info.first_parm_offset+parasize;
-                if is_64bit and
-                   (not paraloc.low_in_reg) then
-                  inc(parasize,8)
+                  end
                 else
                 else
-                  inc(parasize,4);
+                  begin
+                    paraloc^.loc:=LOC_REFERENCE;
+                    if side=callerside then
+                      paraloc^.reference.index:=NR_STACK_POINTER_REG
+                    else
+                      paraloc^.reference.index:=NR_FRAME_POINTER_REG;
+                    paraloc^.reference.offset:=target_info.first_parm_offset+parasize;
+                    { Parameters are aligned at 4 bytes }
+                    inc(parasize,align(tcgsize2size[paraloc^.size],sizeof(aint)));
+                  end;
+                dec(paralen,tcgsize2size[paraloc^.size]);
               end;
               end;
-            hp.paraloc[side]:=paraloc;
             hp:=TParaItem(hp.Next);
             hp:=TParaItem(hp.Next);
           end;
           end;
       end;
       end;
@@ -295,52 +304,29 @@ implementation
       end;
       end;
 
 
 
 
-    procedure tsparcparamanager.allocparaloc(list: taasmoutput; const loc: tparalocation);
-      begin
-        if (loc.loc=LOC_REFERENCE) and
-           (loc.low_in_reg) then
-          cg.GetExplicitRegister(list,loc.lowreg);
-        inherited allocparaloc(list,loc);
-      end;
-
-
-    procedure tsparcparamanager.freeparaloc(list: taasmoutput; const loc: tparalocation);
-      begin
-        if (loc.loc=LOC_REFERENCE) and
-           (loc.low_in_reg) then
-          cg.UnGetRegister(list,loc.lowreg);
-        inherited freeparaloc(list,loc);
-      end;
-
-    procedure tsparcparamanager.splitparaloc64(const locpara:tparalocation;var loclopara,lochipara:tparalocation);
-      begin
-        { Word 0 is in register, word 1 is in reference }
-        if (locpara.loc=LOC_REFERENCE) and locpara.low_in_reg then
-          begin
-            { high }
-            lochipara:=locpara;
-            if locpara.size=OS_S64 then
-              lochipara.size:=OS_S32
-            else
-              lochipara.size:=OS_32;
-            lochipara.low_in_reg:=false;
-            { low }
-            loclopara:=locpara;
-            loclopara.size:=OS_32;
-            loclopara.loc:=LOC_REGISTER;
-            loclopara.register:=locpara.lowreg;
-          end
-        else
-          inherited splitparaloc64(locpara,loclopara,lochipara);
-      end;
-
-
 begin
 begin
    ParaManager:=TSparcParaManager.create;
    ParaManager:=TSparcParaManager.create;
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.40  2004-06-20 08:55:32  florian
+  Revision 1.41  2004-09-21 17:25:13  peter
+    * paraloc branch merged
+
+  Revision 1.40.4.4  2004/09/19 18:08:15  peter
+    * fixed order of 64 bit funcret registers
+
+  Revision 1.40.4.3  2004/09/17 17:19:26  peter
+    * fixed 64 bit unaryminus for sparc
+    * fixed 64 bit inlining
+    * signness of not operation
+
+  Revision 1.40.4.2  2004/09/12 13:36:40  peter
+    * fixed alignment issues
+
+  Revision 1.40.4.1  2004/08/31 20:43:06  peter
+    * paraloc patch
+
+  Revision 1.40  2004/06/20 08:55:32  florian
     * logs truncated
     * logs truncated
 
 
   Revision 1.39  2004/06/16 20:07:10  florian
   Revision 1.39  2004/06/16 20:07:10  florian

+ 8 - 2
compiler/sparc/itcpugas.pas

@@ -85,7 +85,7 @@ implementation
           R_SUBFD:
           R_SUBFD:
             setsubreg(r,R_SUBFS);
             setsubreg(r,R_SUBFS);
           R_SUBL,R_SUBW,R_SUBD,R_SUBQ:
           R_SUBL,R_SUBW,R_SUBD,R_SUBQ:
-            setsubreg(r,R_SUBNONE);
+            setsubreg(r,R_SUBD);
         end;
         end;
         p:=findreg_by_number(r);
         p:=findreg_by_number(r);
         if p<>0 then
         if p<>0 then
@@ -97,7 +97,13 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.4  2004-08-24 21:02:33  florian
+  Revision 1.5  2004-09-21 17:25:13  peter
+    * paraloc branch merged
+
+  Revision 1.4.4.1  2004/09/20 20:42:37  peter
+    * use R_SUBD for all int registers instead of R_SUBNONE
+
+  Revision 1.4  2004/08/24 21:02:33  florian
     * fixed longbool(<int64>) on sparc
     * fixed longbool(<int64>) on sparc
 
 
   Revision 1.3  2004/06/20 08:55:32  florian
   Revision 1.3  2004/06/20 08:55:32  florian

+ 77 - 46
compiler/sparc/ncpuadd.pas

@@ -49,7 +49,7 @@ interface
       systems,
       systems,
       cutils,verbose,
       cutils,verbose,
       paramgr,
       paramgr,
-      aasmbase,aasmtai,aasmcpu,defutil,
+      aasmtai,aasmcpu,defutil,
       cgbase,cgcpu,
       cgbase,cgcpu,
       cpupara,
       cpupara,
       ncon,nset,nadd,
       ncon,nset,nadd,
@@ -281,8 +281,70 @@ interface
 
 
     procedure tsparcaddnode.second_cmp64bit;
     procedure tsparcaddnode.second_cmp64bit;
       var
       var
-        unsigned : boolean;
-        l : tasmlabel;
+        unsigned   : boolean;
+
+      procedure firstjmp64bitcmp;
+        var
+           oldnodetype : tnodetype;
+        begin
+           { the jump the sequence is a little bit hairy }
+           case nodetype of
+              ltn,gtn:
+                begin
+                   cg.a_jmp_flags(exprasmlist,getresflags(unsigned),truelabel);
+                   { cheat a little bit for the negative test }
+                   toggleflag(nf_swaped);
+                   cg.a_jmp_flags(exprasmlist,getresflags(unsigned),falselabel);
+                   toggleflag(nf_swaped);
+                end;
+              lten,gten:
+                begin
+                   oldnodetype:=nodetype;
+                   if nodetype=lten then
+                     nodetype:=ltn
+                   else
+                     nodetype:=gtn;
+                   cg.a_jmp_flags(exprasmlist,getresflags(unsigned),truelabel);
+                   { cheat for the negative test }
+                   if nodetype=ltn then
+                     nodetype:=gtn
+                   else
+                     nodetype:=ltn;
+                   cg.a_jmp_flags(exprasmlist,getresflags(unsigned),falselabel);
+                   nodetype:=oldnodetype;
+                end;
+              equaln:
+                cg.a_jmp_flags(exprasmlist,F_NE,falselabel);
+              unequaln:
+                cg.a_jmp_flags(exprasmlist,F_NE,truelabel);
+           end;
+        end;
+
+      procedure secondjmp64bitcmp;
+
+        begin
+           { the jump the sequence is a little bit hairy }
+           case nodetype of
+              ltn,gtn,lten,gten:
+                begin
+                   { the comparisaion of the low dword have to be }
+                   {  always unsigned!                            }
+                   cg.a_jmp_flags(exprasmlist,getresflags(true),truelabel);
+                   cg.a_jmp_always(exprasmlist,falselabel);
+                end;
+              equaln:
+                begin
+                   cg.a_jmp_flags(exprasmlist,F_NE,falselabel);
+                   cg.a_jmp_always(exprasmlist,truelabel);
+                end;
+              unequaln:
+                begin
+                   cg.a_jmp_flags(exprasmlist,F_NE,truelabel);
+                   cg.a_jmp_always(exprasmlist,falselabel);
+                end;
+           end;
+        end;
+
       begin
       begin
         pass_left_right;
         pass_left_right;
         force_reg_left_right(false,false);
         force_reg_left_right(false,false);
@@ -290,49 +352,12 @@ interface
         unsigned:=not(is_signed(left.resulttype.def)) or
         unsigned:=not(is_signed(left.resulttype.def)) or
                   not(is_signed(right.resulttype.def));
                   not(is_signed(right.resulttype.def));
 
 
-        location_reset(location,LOC_FLAGS,OS_NO);
-        location.resflags:=getresflags(unsigned);
+        location_reset(location,LOC_JUMP,OS_NO);
 
 
-        { operation requiring proper N, Z and C flags ? }
-        if unsigned or (nodetype in [equaln,unequaln]) then
-          begin
-            objectlibrary.getlabel(l);
-            exprasmlist.concat(taicpu.op_reg_reg(A_CMP,left.location.register64.reghi,right.location.register64.reghi));
-            tcgsparc(cg).a_jmp_cond(exprasmlist,OC_NE,l);
-            exprasmlist.concat(taicpu.op_reg_reg(A_CMP,left.location.register64.reglo,right.location.register64.reglo));
-            cg.a_label(exprasmlist,l);
-          end
-        { operation requiring proper N, V and C flags ? }
-        else if nodetype in [gten,ltn] then
-          begin
-            exprasmlist.concat(taicpu.op_reg_reg_reg(A_SUBCC,left.location.register64.reglo,right.location.register64.reglo,NR_G0));
-            exprasmlist.concat(taicpu.op_reg_reg_reg(A_SUBXCC,left.location.register64.reghi,right.location.register64.reghi,NR_G0));
-          end
-        else
-        { operation requiring proper N, Z and V flags ? }
-          begin
-            { this isn't possible so swap operands and use the "reverse" operation }
-            exprasmlist.concat(taicpu.op_reg_reg_reg(A_SUBCC,right.location.register64.reglo,left.location.register64.reglo,NR_G0));
-            exprasmlist.concat(taicpu.op_reg_reg_reg(A_SUBXCC,right.location.register64.reghi,left.location.register64.reghi,NR_G0));
-            if nf_swaped in flags then
-              begin
-                if location.resflags=F_L then
-                  location.resflags:=F_G
-                else if location.resflags=F_GE then
-                  location.resflags:=F_LE
-                else
-                  internalerror(200401221);
-              end
-            else
-              begin
-                if location.resflags=F_G then
-                  location.resflags:=F_L
-                else if location.resflags=F_LE then
-                  location.resflags:=F_GE
-                else
-                  internalerror(200401221);
-              end;
-          end;
+        exprasmlist.concat(taicpu.op_reg_reg(A_CMP,left.location.register64.reghi,right.location.register64.reghi));
+        firstjmp64bitcmp;
+        exprasmlist.concat(taicpu.op_reg_reg(A_CMP,left.location.register64.reglo,right.location.register64.reglo));
+        secondjmp64bitcmp;
 
 
         release_reg_left_right;
         release_reg_left_right;
       end;
       end;
@@ -364,7 +389,13 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.25  2004-06-20 08:55:32  florian
+  Revision 1.26  2004-09-21 17:25:13  peter
+    * paraloc branch merged
+
+  Revision 1.25.4.1  2004/09/19 18:08:30  peter
+    * int64 compare fixed
+
+  Revision 1.25  2004/06/20 08:55:32  florian
     * logs truncated
     * logs truncated
 
 
   Revision 1.24  2004/06/16 20:07:10  florian
   Revision 1.24  2004/06/16 20:07:10  florian

+ 34 - 34
compiler/sparc/rspcon.inc

@@ -1,39 +1,39 @@
 { don't edit, this file is generated from spreg.dat }
 { don't edit, this file is generated from spreg.dat }
 NR_NO = tregister($00000000);
 NR_NO = tregister($00000000);
-NR_G0 = tregister($01000000);
-NR_G1 = tregister($01000001);
-NR_G2 = tregister($01000002);
-NR_G3 = tregister($01000003);
-NR_G4 = tregister($01000004);
-NR_G5 = tregister($01000005);
-NR_G6 = tregister($01000006);
-NR_G7 = tregister($01000007);
-NR_O0 = tregister($01000008);
-NR_O1 = tregister($01000009);
-NR_O2 = tregister($0100000a);
-NR_O3 = tregister($0100000b);
-NR_O4 = tregister($0100000c);
-NR_O5 = tregister($0100000d);
-NR_O6 = tregister($0100000e);
-NR_O7 = tregister($0100000f);
-NR_L0 = tregister($01000010);
-NR_L1 = tregister($01000011);
-NR_L2 = tregister($01000012);
-NR_L3 = tregister($01000013);
-NR_L4 = tregister($01000014);
-NR_L5 = tregister($01000015);
-NR_L6 = tregister($01000016);
-NR_L7 = tregister($01000017);
-NR_I0 = tregister($01000018);
-NR_I1 = tregister($01000019);
-NR_I2 = tregister($0100001a);
-NR_I3 = tregister($0100001b);
-NR_I4 = tregister($0100001c);
-NR_I5 = tregister($0100001d);
-NR_I6 = tregister($0100001e);
-NR_I7 = tregister($0100001f);
-NR_FP = tregister($0100001e);
-NR_SP = tregister($0100000e);
+NR_G0 = tregister($01040000);
+NR_G1 = tregister($01040001);
+NR_G2 = tregister($01040002);
+NR_G3 = tregister($01040003);
+NR_G4 = tregister($01040004);
+NR_G5 = tregister($01040005);
+NR_G6 = tregister($01040006);
+NR_G7 = tregister($01040007);
+NR_O0 = tregister($01040008);
+NR_O1 = tregister($01040009);
+NR_O2 = tregister($0104000a);
+NR_O3 = tregister($0104000b);
+NR_O4 = tregister($0104000c);
+NR_O5 = tregister($0104000d);
+NR_O6 = tregister($0104000e);
+NR_O7 = tregister($0104000f);
+NR_L0 = tregister($01040010);
+NR_L1 = tregister($01040011);
+NR_L2 = tregister($01040012);
+NR_L3 = tregister($01040013);
+NR_L4 = tregister($01040014);
+NR_L5 = tregister($01040015);
+NR_L6 = tregister($01040016);
+NR_L7 = tregister($01040017);
+NR_I0 = tregister($01040018);
+NR_I1 = tregister($01040019);
+NR_I2 = tregister($0104001a);
+NR_I3 = tregister($0104001b);
+NR_I4 = tregister($0104001c);
+NR_I5 = tregister($0104001d);
+NR_I6 = tregister($0104001e);
+NR_I7 = tregister($0104001f);
+NR_FP = tregister($0104001e);
+NR_SP = tregister($0104000e);
 NR_F0 = tregister($02060000);
 NR_F0 = tregister($02060000);
 NR_F1 = tregister($02060001);
 NR_F1 = tregister($02060001);
 NR_F2 = tregister($02060002);
 NR_F2 = tregister($02060002);

+ 41 - 35
compiler/sparc/spreg.dat

@@ -8,41 +8,41 @@
 ;
 ;
 NO,$00,$00,$00,INVALID,-1,-1
 NO,$00,$00,$00,INVALID,-1,-1
 ; Integer registers
 ; Integer registers
-G0,$01,$00,$00,%g0,1,1
-G1,$01,$00,$01,%g1,2,2
-G2,$01,$00,$02,%g2,3,3
-G3,$01,$00,$03,%g3,4,4
-G4,$01,$00,$04,%g4,5,5
-G5,$01,$00,$05,%g5,6,6
-G6,$01,$00,$06,%g6,7,7
-G7,$01,$00,$07,%g7,8,8
-O0,$01,$00,$08,%o0,9,9
-O1,$01,$00,$09,%o1,10,10
-O2,$01,$00,$0a,%o2,11,11
-O3,$01,$00,$0b,%o3,12,12
-O4,$01,$00,$0c,%o4,13,13
-O5,$01,$00,$0d,%o5,14,14
-O6,$01,$00,$0e,%o6,15,15
-O7,$01,$00,$0f,%o7,16,16
-L0,$01,$00,$10,%l0,17,17
-L1,$01,$00,$11,%l1,18,18
-L2,$01,$00,$12,%l2,19,19
-L3,$01,$00,$13,%l3,20,20
-L4,$01,$00,$14,%l4,21,21
-L5,$01,$00,$15,%l5,22,22
-L6,$01,$00,$16,%l6,23,23
-L7,$01,$00,$17,%l7,24,24
-I0,$01,$00,$18,%i0,25,25
-I1,$01,$00,$19,%i1,26,26
-I2,$01,$00,$1a,%i2,27,27
-I3,$01,$00,$1b,%i3,28,28
-I4,$01,$00,$1c,%i4,29,29
-I5,$01,$00,$1d,%i5,30,30
-I6,$01,$00,$1e,%i6,31,31
-I7,$01,$00,$1f,%i7,32,32
+G0,$01,$04,$00,%g0,1,1
+G1,$01,$04,$01,%g1,2,2
+G2,$01,$04,$02,%g2,3,3
+G3,$01,$04,$03,%g3,4,4
+G4,$01,$04,$04,%g4,5,5
+G5,$01,$04,$05,%g5,6,6
+G6,$01,$04,$06,%g6,7,7
+G7,$01,$04,$07,%g7,8,8
+O0,$01,$04,$08,%o0,9,9
+O1,$01,$04,$09,%o1,10,10
+O2,$01,$04,$0a,%o2,11,11
+O3,$01,$04,$0b,%o3,12,12
+O4,$01,$04,$0c,%o4,13,13
+O5,$01,$04,$0d,%o5,14,14
+O6,$01,$04,$0e,%o6,15,15
+O7,$01,$04,$0f,%o7,16,16
+L0,$01,$04,$10,%l0,17,17
+L1,$01,$04,$11,%l1,18,18
+L2,$01,$04,$12,%l2,19,19
+L3,$01,$04,$13,%l3,20,20
+L4,$01,$04,$14,%l4,21,21
+L5,$01,$04,$15,%l5,22,22
+L6,$01,$04,$16,%l6,23,23
+L7,$01,$04,$17,%l7,24,24
+I0,$01,$04,$18,%i0,25,25
+I1,$01,$04,$19,%i1,26,26
+I2,$01,$04,$1a,%i2,27,27
+I3,$01,$04,$1b,%i3,28,28
+I4,$01,$04,$1c,%i4,29,29
+I5,$01,$04,$1d,%i5,30,30
+I6,$01,$04,$1e,%i6,31,31
+I7,$01,$04,$1f,%i7,32,32
 ; Aliases for stackpointer (%o6) and framepointer (%i6)
 ; Aliases for stackpointer (%o6) and framepointer (%i6)
-FP,$01,$00,$1e,%fp,31,31
-SP,$01,$00,$0e,%sp,15,15
+FP,$01,$04,$1e,%fp,31,31
+SP,$01,$04,$0e,%sp,15,15
 ; Float registers, single use
 ; Float registers, single use
 F0,$02,$06,$00,%f0,32,32
 F0,$02,$06,$00,%f0,32,32
 F1,$02,$06,$01,%f1,32,32
 F1,$02,$06,$01,%f1,32,32
@@ -157,7 +157,13 @@ ASR31,$04,$00,$1f,%asr31,32,32
 
 
 ;
 ;
 ; $Log$
 ; $Log$
-; Revision 1.5  2004-06-16 20:07:11  florian
+; Revision 1.6  2004-09-21 17:25:13  peter
+;   * paraloc branch merged
+;
+; Revision 1.5.4.1  2004/09/20 20:42:38  peter
+;   * use R_SUBD for all int registers instead of R_SUBNONE
+;
+; Revision 1.5  2004/06/16 20:07:11  florian
 ;   * dwarf branch merged
 ;   * dwarf branch merged
 ;
 ;
 ; Revision 1.4.2.1  2004/05/11 19:34:57  peter
 ; Revision 1.4.2.1  2004/05/11 19:34:57  peter

+ 36 - 4
compiler/symdef.pas

@@ -39,7 +39,7 @@ interface
        { aasm }
        { aasm }
        aasmbase,aasmtai,
        aasmbase,aasmtai,
        cpubase,cpuinfo,
        cpubase,cpuinfo,
-       cgbase
+       cgbase,parabase
 {$ifdef Delphi}
 {$ifdef Delphi}
        ,dmisc
        ,dmisc
 {$endif}
 {$endif}
@@ -113,11 +113,13 @@ interface
           defaultvalue : tsym; { tconstsym }
           defaultvalue : tsym; { tconstsym }
           defaultvaluederef : tderef;
           defaultvaluederef : tderef;
           paratyp       : tvarspez; { required for procvar }
           paratyp       : tvarspez; { required for procvar }
-          paraloc       : array[tcallercallee] of tparalocation;
+          paraloc       : array[tcallercallee] of TCGPara;
           is_hidden     : boolean; { is this a hidden (implicit) parameter }
           is_hidden     : boolean; { is this a hidden (implicit) parameter }
 {$ifdef EXTDEBUG}
 {$ifdef EXTDEBUG}
           eqval         : tequaltype;
           eqval         : tequaltype;
 {$endif EXTDEBUG}
 {$endif EXTDEBUG}
+          constructor create;
+          destructor destroy;override;
        end;
        end;
 
 
        tfiletyp = (ft_text,ft_typed,ft_untyped);
        tfiletyp = (ft_text,ft_typed,ft_untyped);
@@ -456,7 +458,7 @@ interface
 {$ifdef i386}
 {$ifdef i386}
           fpu_used        : byte;    { how many stack fpu must be empty }
           fpu_used        : byte;    { how many stack fpu must be empty }
 {$endif i386}
 {$endif i386}
-          funcret_paraloc : array[tcallercallee] of tparalocation;
+          funcret_paraloc : array[tcallercallee] of TCGPara;
           has_paraloc_info : boolean; { paraloc info is available }
           has_paraloc_info : boolean; { paraloc info is available }
           constructor create(level:byte);
           constructor create(level:byte);
           constructor ppuload(ppufile:tcompilerppufile);
           constructor ppuload(ppufile:tcompilerppufile);
@@ -921,6 +923,26 @@ implementation
       end;
       end;
 
 
 
 
+{****************************************************************************
+                           TParaItem
+****************************************************************************}
+
+    constructor tparaitem.create;
+      begin
+        inherited create;
+        paraloc[calleeside].init;
+        paraloc[callerside].init;
+      end;
+
+
+    destructor tparaitem.destroy;
+      begin
+        paraloc[calleeside].done;
+        paraloc[callerside].done;
+        inherited destroy;
+      end;
+
+
 {****************************************************************************
 {****************************************************************************
                      TDEF (base class for definitions)
                      TDEF (base class for definitions)
 ****************************************************************************}
 ****************************************************************************}
@@ -3277,6 +3299,8 @@ implementation
          savesize:=sizeof(aint);
          savesize:=sizeof(aint);
          requiredargarea:=0;
          requiredargarea:=0;
          has_paraloc_info:=false;
          has_paraloc_info:=false;
+         funcret_paraloc[callerside].init;
+         funcret_paraloc[calleeside].init;
       end;
       end;
 
 
 
 
@@ -3302,6 +3326,8 @@ implementation
             memprocparast.stop;
             memprocparast.stop;
 {$endif MEMDEBUG}
 {$endif MEMDEBUG}
           end;
           end;
+         funcret_paraloc[callerside].done;
+         funcret_paraloc[calleeside].done;
          inherited destroy;
          inherited destroy;
       end;
       end;
 
 
@@ -6158,10 +6184,16 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.254  2004-09-14 16:33:17  peter
+  Revision 1.255  2004-09-21 17:25:12  peter
+    * paraloc branch merged
+
+  Revision 1.254  2004/09/14 16:33:17  peter
     * restart sorting of enums when deref is called, this is needed when
     * restart sorting of enums when deref is called, this is needed when
       a unit is reloaded
       a unit is reloaded
 
 
+  Revision 1.253.4.1  2004/08/31 20:43:06  peter
+    * paraloc patch
+
   Revision 1.253  2004/08/27 21:59:26  peter
   Revision 1.253  2004/08/27 21:59:26  peter
   browser disabled
   browser disabled
   uf_local_symtable ppu flag when a localsymtable is stored
   uf_local_symtable ppu flag when a localsymtable is stored

+ 10 - 4
compiler/symsym.pas

@@ -37,7 +37,7 @@ interface
        cclasses,symnot,
        cclasses,symnot,
        { aasm }
        { aasm }
        aasmbase,
        aasmbase,
-       cpuinfo,cpubase,cgbase
+       cpuinfo,cpubase,cgbase,parabase
        ;
        ;
 
 
     type
     type
@@ -150,8 +150,8 @@ interface
           varoptions    : tvaroptions;
           varoptions    : tvaroptions;
           varspez       : tvarspez;  { sets the type of access }
           varspez       : tvarspez;  { sets the type of access }
           varstate      : tvarstate;
           varstate      : tvarstate;
-          localloc      : tparalocation; { register/reference for local var }
-          fieldoffset   : longint; { offset in record/object }
+          localloc      : TLocation; { register/reference for local var }
+          fieldoffset   : longint;   { offset in record/object }
           paraitem      : tparaitem;
           paraitem      : tparaitem;
           notifications : Tlinkedlist;
           notifications : Tlinkedlist;
           constructor create(const n : string;vsp:tvarspez;const tt : ttype);
           constructor create(const n : string;vsp:tvarspez;const tt : ttype);
@@ -2215,7 +2215,13 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.175  2004-08-15 12:06:03  jonas
+  Revision 1.176  2004-09-21 17:25:12  peter
+    * paraloc branch merged
+
+  Revision 1.175.4.1  2004/08/31 20:43:06  peter
+    * paraloc patch
+
+  Revision 1.175  2004/08/15 12:06:03  jonas
     * add cprefix to procedures which are autoamtically marked as external in
     * add cprefix to procedures which are autoamtically marked as external in
       macpas mode
       macpas mode
 
 

+ 8 - 2
compiler/systems/t_linux.pas

@@ -211,7 +211,7 @@ var
 begin
 begin
   with Info do
   with Info do
    begin
    begin
-     ExeCmd[1]:='ld $OPT $DYNLINK $STATIC $STRIP --gc-sections -L. -o $EXE $RES';
+     ExeCmd[1]:='ld $OPT $DYNLINK $STATIC $STRIP -L. -o $EXE $RES';
      DllCmd[1]:='ld $OPT $INIT $FINI $SONAME -shared -L. -o $EXE $RES';
      DllCmd[1]:='ld $OPT $INIT $FINI $SONAME -shared -L. -o $EXE $RES';
      DllCmd[2]:='strip --strip-unneeded $EXE';
      DllCmd[2]:='strip --strip-unneeded $EXE';
 {$ifdef m68k}
 {$ifdef m68k}
@@ -572,7 +572,13 @@ end.
 
 
 {
 {
   $Log$
   $Log$
-  Revision 1.20  2004-07-08 14:42:54  daniel
+  Revision 1.21  2004-09-21 17:25:13  peter
+    * paraloc branch merged
+
+  Revision 1.20.4.1  2004/09/20 15:24:42  peter
+    * remove gc-sections option until it really works
+
+  Revision 1.20  2004/07/08 14:42:54  daniel
     * Uclibc detection
     * Uclibc detection
 
 
   Revision 1.19  2004/06/20 08:55:32  florian
   Revision 1.19  2004/06/20 08:55:32  florian

+ 9 - 6
compiler/tgobj.pas

@@ -103,8 +103,8 @@ unit tgobj;
           procedure ungetiftemp(list: taasmoutput; const ref : treference);
           procedure ungetiftemp(list: taasmoutput; const ref : treference);
 
 
           { Allocate space for a local }
           { Allocate space for a local }
-          procedure getlocal(list: taasmoutput; size : longint;def:tdef;var ref : tparareference);
-          procedure UnGetLocal(list: taasmoutput; const ref : tparareference);
+          procedure getlocal(list: taasmoutput; size : longint;def:tdef;var ref : treference);
+          procedure UnGetLocal(list: taasmoutput; const ref : treference);
        end;
        end;
 
 
      var
      var
@@ -588,7 +588,7 @@ unit tgobj;
       end;
       end;
 
 
 
 
-    procedure ttgobj.getlocal(list: taasmoutput; size : longint;def:tdef;var ref : tparareference);
+    procedure ttgobj.getlocal(list: taasmoutput; size : longint;def:tdef;var ref : treference);
       var
       var
         varalign : longint;
         varalign : longint;
       begin
       begin
@@ -597,12 +597,12 @@ unit tgobj;
         { can't use reference_reset_base, because that will let tgobj depend
         { can't use reference_reset_base, because that will let tgobj depend
           on cgobj (PFV) }
           on cgobj (PFV) }
         fillchar(ref,sizeof(ref),0);
         fillchar(ref,sizeof(ref),0);
-        ref.index:=current_procinfo.framepointer;
+        ref.base:=current_procinfo.framepointer;
         ref.offset:=alloctemp(list,size,varalign,tt_persistent,nil);
         ref.offset:=alloctemp(list,size,varalign,tt_persistent,nil);
       end;
       end;
 
 
 
 
-    procedure ttgobj.UnGetLocal(list: taasmoutput; const ref : tparareference);
+    procedure ttgobj.UnGetLocal(list: taasmoutput; const ref : treference);
       begin
       begin
         FreeTemp(list,ref.offset,[tt_persistent]);
         FreeTemp(list,ref.offset,[tt_persistent]);
       end;
       end;
@@ -611,7 +611,10 @@ unit tgobj;
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.47  2004-09-20 15:40:21  peter
+  Revision 1.48  2004-09-21 17:25:12  peter
+    * paraloc branch merged
+
+  Revision 1.47  2004/09/20 15:40:21  peter
     * make it compile with main branch
     * make it compile with main branch
 
 
   Revision 1.46  2004/09/20 07:32:02  jonas
   Revision 1.46  2004/09/20 07:32:02  jonas

+ 20 - 14
compiler/x86/nx86add.pas

@@ -20,9 +20,6 @@
 
 
  ****************************************************************************
  ****************************************************************************
 }
 }
-{
-Common code generation for add nodes on the i386 and x86
-}
 unit nx86add;
 unit nx86add;
 
 
 {$i fpcdefs.inc}
 {$i fpcdefs.inc}
@@ -66,13 +63,12 @@ unit nx86add;
 
 
     uses
     uses
       globtype,globals,
       globtype,globals,
-      verbose,
-      cutils,
+      verbose,cutils,
       cpuinfo,
       cpuinfo,
       aasmbase,aasmtai,aasmcpu,
       aasmbase,aasmtai,aasmcpu,
       symconst,symdef,
       symconst,symdef,
       cgobj,cgx86,cga,
       cgobj,cgx86,cga,
-      paramgr,
+      paramgr,parabase,
       htypechk,
       htypechk,
       pass_2,ncgutil,
       pass_2,ncgutil,
       ncon,nset,
       ncon,nset,
@@ -739,7 +735,7 @@ unit nx86add;
     procedure tx86addnode.second_addstring;
     procedure tx86addnode.second_addstring;
       var
       var
         paraloc1,
         paraloc1,
-        paraloc2   : tparalocation;
+        paraloc2   : tcgpara;
         hregister1,
         hregister1,
         hregister2 : tregister;
         hregister2 : tregister;
       begin
       begin
@@ -752,12 +748,14 @@ unit nx86add;
                 case nodetype of
                 case nodetype of
                    ltn,lten,gtn,gten,equaln,unequaln :
                    ltn,lten,gtn,gten,equaln,unequaln :
                      begin
                      begin
-                       paraloc1:=paramanager.getintparaloc(pocall_default,1);
-                       paraloc2:=paramanager.getintparaloc(pocall_default,2);
+                       paraloc1.init;
+                       paraloc2.init;
+                       paramanager.getintparaloc(pocall_default,1,paraloc1);
+                       paramanager.getintparaloc(pocall_default,2,paraloc2);
                        { process parameters }
                        { process parameters }
                        secondpass(left);
                        secondpass(left);
                        location_release(exprasmlist,left.location);
                        location_release(exprasmlist,left.location);
-                       if paraloc2.loc=LOC_REGISTER then
+                       if paraloc2.location^.loc=LOC_REGISTER then
                          begin
                          begin
                            hregister2:=cg.getaddressregister(exprasmlist);
                            hregister2:=cg.getaddressregister(exprasmlist);
                            cg.a_loadaddr_ref_reg(exprasmlist,left.location.reference,hregister2);
                            cg.a_loadaddr_ref_reg(exprasmlist,left.location.reference,hregister2);
@@ -769,7 +767,7 @@ unit nx86add;
                          end;
                          end;
                        secondpass(right);
                        secondpass(right);
                        location_release(exprasmlist,right.location);
                        location_release(exprasmlist,right.location);
-                       if paraloc1.loc=LOC_REGISTER then
+                       if paraloc1.location^.loc=LOC_REGISTER then
                          begin
                          begin
                            hregister1:=cg.getaddressregister(exprasmlist);
                            hregister1:=cg.getaddressregister(exprasmlist);
                            cg.a_loadaddr_ref_reg(exprasmlist,right.location.reference,hregister1);
                            cg.a_loadaddr_ref_reg(exprasmlist,right.location.reference,hregister1);
@@ -780,13 +778,13 @@ unit nx86add;
                            cg.a_paramaddr_ref(exprasmlist,right.location.reference,paraloc1);
                            cg.a_paramaddr_ref(exprasmlist,right.location.reference,paraloc1);
                          end;
                          end;
                        { push parameters }
                        { push parameters }
-                       if paraloc1.loc=LOC_REGISTER then
+                       if paraloc1.location^.loc=LOC_REGISTER then
                          begin
                          begin
                            cg.ungetregister(exprasmlist,hregister2);
                            cg.ungetregister(exprasmlist,hregister2);
                            paramanager.allocparaloc(exprasmlist,paraloc2);
                            paramanager.allocparaloc(exprasmlist,paraloc2);
                            cg.a_param_reg(exprasmlist,OS_ADDR,hregister2,paraloc2);
                            cg.a_param_reg(exprasmlist,OS_ADDR,hregister2,paraloc2);
                          end;
                          end;
-                       if paraloc2.loc=LOC_REGISTER then
+                       if paraloc2.location^.loc=LOC_REGISTER then
                          begin
                          begin
                            cg.ungetregister(exprasmlist,hregister1);
                            cg.ungetregister(exprasmlist,hregister1);
                            paramanager.allocparaloc(exprasmlist,paraloc1);
                            paramanager.allocparaloc(exprasmlist,paraloc1);
@@ -799,6 +797,8 @@ unit nx86add;
                        cg.deallocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
                        cg.deallocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
                        location_freetemp(exprasmlist,left.location);
                        location_freetemp(exprasmlist,left.location);
                        location_freetemp(exprasmlist,right.location);
                        location_freetemp(exprasmlist,right.location);
+                       paraloc1.done;
+                       paraloc2.done;
                      end;
                      end;
                 end;
                 end;
                 location_reset(location,LOC_FLAGS,OS_NO);
                 location_reset(location,LOC_FLAGS,OS_NO);
@@ -935,7 +935,13 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.11  2004-06-20 08:55:32  florian
+  Revision 1.12  2004-09-21 17:25:13  peter
+    * paraloc branch merged
+
+  Revision 1.11.4.1  2004/08/31 20:43:06  peter
+    * paraloc patch
+
+  Revision 1.11  2004/06/20 08:55:32  florian
     * logs truncated
     * logs truncated
 
 
   Revision 1.10  2004/06/16 20:07:11  florian
   Revision 1.10  2004/06/16 20:07:11  florian

+ 10 - 6
compiler/x86_64/cgcpu.pas

@@ -20,8 +20,6 @@
 
 
  ****************************************************************************
  ****************************************************************************
 }
 }
-{ This unit implements the code generator for the x86-64.
-}
 unit cgcpu;
 unit cgcpu;
 
 
 {$i fpcdefs.inc}
 {$i fpcdefs.inc}
@@ -31,14 +29,14 @@ unit cgcpu;
     uses
     uses
        cgbase,cgobj,cg64f64,cgx86,
        cgbase,cgobj,cg64f64,cgx86,
        aasmbase,aasmtai,aasmcpu,
        aasmbase,aasmtai,aasmcpu,
-       cpubase,cpuinfo,cpupara,
+       cpubase,cpuinfo,cpupara,parabase,
        node,symconst,rgx86,procinfo;
        node,symconst,rgx86,procinfo;
 
 
     type
     type
       tcgx86_64 = class(tcgx86)
       tcgx86_64 = class(tcgx86)
         procedure init_register_allocators;override;
         procedure init_register_allocators;override;
         procedure g_save_all_registers(list : taasmoutput);override;
         procedure g_save_all_registers(list : taasmoutput);override;
-        procedure g_restore_all_registers(list : taasmoutput;const funcretparaloc:tparalocation);override;
+        procedure g_restore_all_registers(list : taasmoutput;const funcretparaloc:tcgpara);override;
         procedure g_proc_exit(list : taasmoutput;parasize:longint;nostackframe:boolean);override;
         procedure g_proc_exit(list : taasmoutput;parasize:longint;nostackframe:boolean);override;
       end;
       end;
 
 
@@ -72,7 +70,7 @@ unit cgcpu;
       end;
       end;
 
 
 
 
-    procedure tcgx86_64.g_restore_all_registers(list : taasmoutput;const funcretparaloc:tparalocation);
+    procedure tcgx86_64.g_restore_all_registers(list : taasmoutput;const funcretparaloc:tcgpara);
       begin
       begin
         {$warning todo tcgx86_64.g_restore_all_registers}
         {$warning todo tcgx86_64.g_restore_all_registers}
       end;
       end;
@@ -111,7 +109,13 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.15  2004-07-09 23:30:13  jonas
+  Revision 1.16  2004-09-21 17:25:13  peter
+    * paraloc branch merged
+
+  Revision 1.15.4.1  2004/08/31 20:43:06  peter
+    * paraloc patch
+
+  Revision 1.15  2004/07/09 23:30:13  jonas
     *  changed first_sse_imreg to first_mm_imreg
     *  changed first_sse_imreg to first_mm_imreg
 
 
   Revision 1.14  2004/06/20 08:55:32  florian
   Revision 1.14  2004/06/20 08:55:32  florian

+ 171 - 128
compiler/x86_64/cpupara.pas

@@ -20,8 +20,6 @@
 
 
  ****************************************************************************
  ****************************************************************************
 }
 }
-{ Generates the argument location information for x86-64 target.
-}
 unit cpupara;
 unit cpupara;
 
 
 {$i fpcdefs.inc}
 {$i fpcdefs.inc}
@@ -33,7 +31,7 @@ unit cpupara;
       cpubase,cgbase,
       cpubase,cgbase,
       symconst,symbase,symtype,symdef,
       symconst,symbase,symtype,symdef,
       aasmtai,
       aasmtai,
-      paramgr;
+      parabase,paramgr;
 
 
     type
     type
        tx86_64paramanager = class(tparamanager)
        tx86_64paramanager = class(tparamanager)
@@ -42,7 +40,7 @@ unit cpupara;
           procedure create_paraloc_info_intern(p : tabstractprocdef; side: tcallercallee;firstpara:tparaitem;
           procedure create_paraloc_info_intern(p : tabstractprocdef; side: tcallercallee;firstpara:tparaitem;
                                                var intparareg,mmparareg,parasize:longint);
                                                var intparareg,mmparareg,parasize:longint);
        public
        public
-          function getintparaloc(calloption : tproccalloption; nr : longint) : tparalocation;override;
+          procedure getintparaloc(calloption : tproccalloption; nr : longint;var cgpara:TCGPara);override;
           function get_volatile_registers_int(calloption : tproccalloption):tcpuregisterset;override;
           function get_volatile_registers_int(calloption : tproccalloption):tcpuregisterset;override;
           function get_volatile_registers_mm(calloption : tproccalloption):tcpuregisterset;override;
           function get_volatile_registers_mm(calloption : tproccalloption):tcpuregisterset;override;
           function get_volatile_registers_fpu(calloption : tproccalloption):tcpuregisterset;override;
           function get_volatile_registers_fpu(calloption : tproccalloption):tcpuregisterset;override;
@@ -54,44 +52,38 @@ unit cpupara;
 
 
     uses
     uses
        cutils,verbose,
        cutils,verbose,
-       cpuinfo,systems,
-       defutil,
-       tgobj;
+       systems,
+       defutil;
 
 
     const
     const
       paraintsupregs : array[0..5] of tsuperregister = (RS_RDI,RS_RSI,RS_RDX,RS_RCX,RS_R8,RS_R9);
       paraintsupregs : array[0..5] of tsuperregister = (RS_RDI,RS_RSI,RS_RDX,RS_RCX,RS_R8,RS_R9);
       parammsupregs : array[0..7] of tsuperregister = (RS_XMM0,RS_XMM1,RS_XMM2,RS_XMM3,RS_XMM4,RS_XMM5,RS_XMM6,RS_XMM7);
       parammsupregs : array[0..7] of tsuperregister = (RS_XMM0,RS_XMM1,RS_XMM2,RS_XMM3,RS_XMM4,RS_XMM5,RS_XMM6,RS_XMM7);
 
 
-    procedure getvalueparaloc(p : tdef;var paraloc:tparalocation);
+    procedure getvalueparaloc(p : tdef;var loc1,loc2:tcgloc);
       begin
       begin
-        paraloc.size:=def_cgsize(p);
-        paraloc.loc:=LOC_INVALID;
-        paraloc.lochigh:=LOC_INVALID;
+        loc1:=LOC_INVALID;
+        loc2:=LOC_INVALID;
         case p.deftype of
         case p.deftype of
            orddef:
            orddef:
              begin
              begin
-               paraloc.loc:=LOC_REGISTER;
+               loc1:=LOC_REGISTER;
                {$warning TODO 128bit also needs lochigh}
                {$warning TODO 128bit also needs lochigh}
              end;
              end;
            floatdef:
            floatdef:
              begin
              begin
                case tfloatdef(p).typ of
                case tfloatdef(p).typ of
                   s80real:
                   s80real:
-                    paraloc.loc:=LOC_REFERENCE;
+                    loc1:=LOC_REFERENCE;
                   s32real,
                   s32real,
-                  s64real,
-                  s64currency :
-                    paraloc.loc:=LOC_MMREGISTER;
+                  s64real :
+                    loc1:=LOC_MMREGISTER;
+                  s64currency,
                   s64comp :
                   s64comp :
-                    begin
-                      paraloc.loc:=LOC_REGISTER;
-                      { Force Integer size }
-                      paraloc.size:=OS_64;
-                    end;
+                    loc1:=LOC_REGISTER;
                   s128real:
                   s128real:
                     begin
                     begin
-                      paraloc.loc:=LOC_MMREGISTER;
-                      paraloc.lochigh:=LOC_MMREGISTER;
+                      loc1:=LOC_MMREGISTER;
+                      loc2:=LOC_MMREGISTER;
                       {$warning TODO float 128bit needs SSEUP lochigh}
                       {$warning TODO float 128bit needs SSEUP lochigh}
                     end;
                     end;
                end;
                end;
@@ -101,47 +93,47 @@ unit cpupara;
                if p.size<=16 then
                if p.size<=16 then
                  begin
                  begin
                    {$warning TODO location depends on the fields}
                    {$warning TODO location depends on the fields}
-                   paraloc.loc:=LOC_REFERENCE;
+                   loc1:=LOC_REFERENCE;
                  end
                  end
                else
                else
-                 paraloc.loc:=LOC_REFERENCE;
+                 loc1:=LOC_REFERENCE;
              end;
              end;
            objectdef:
            objectdef:
              begin
              begin
                if is_object(p) then
                if is_object(p) then
-                 paraloc.loc:=LOC_REFERENCE
+                 loc1:=LOC_REFERENCE
                else
                else
-                 paraloc.loc:=LOC_REGISTER;
+                 loc1:=LOC_REGISTER;
              end;
              end;
            arraydef:
            arraydef:
-             paraloc.loc:=LOC_REFERENCE;
+             loc1:=LOC_REFERENCE;
            variantdef:
            variantdef:
-             paraloc.loc:=LOC_REFERENCE;
+             loc1:=LOC_REFERENCE;
            stringdef:
            stringdef:
              if is_shortstring(p) or is_longstring(p) then
              if is_shortstring(p) or is_longstring(p) then
-               paraloc.loc:=LOC_REFERENCE
+               loc1:=LOC_REFERENCE
              else
              else
-               paraloc.loc:=LOC_REGISTER;
+               loc1:=LOC_REGISTER;
            setdef:
            setdef:
              if is_smallset(p) then
              if is_smallset(p) then
-               paraloc.loc:=LOC_REGISTER
+               loc1:=LOC_REGISTER
              else
              else
-               paraloc.loc:=LOC_REFERENCE;
+               loc1:=LOC_REFERENCE;
            procvardef:
            procvardef:
              begin
              begin
                { This is a record < 16 bytes }
                { This is a record < 16 bytes }
                if (po_methodpointer in tprocvardef(p).procoptions) then
                if (po_methodpointer in tprocvardef(p).procoptions) then
                  begin
                  begin
-                   paraloc.loc:=LOC_REGISTER;
-                   paraloc.lochigh:=LOC_REGISTER;
+                   loc1:=LOC_REGISTER;
+                   loc2:=LOC_REGISTER;
                  end
                  end
                else
                else
-                 paraloc.loc:=LOC_REGISTER;
+                 loc1:=LOC_REGISTER;
              end;
              end;
            else
            else
              begin
              begin
                { default for pointers,enums,etc }
                { default for pointers,enums,etc }
-               paraloc.loc:=LOC_REGISTER;
+               loc1:=LOC_REGISTER;
              end;
              end;
         end;
         end;
       end;
       end;
@@ -165,73 +157,88 @@ unit cpupara;
       end;
       end;
 
 
 
 
-    function tx86_64paramanager.getintparaloc(calloption : tproccalloption; nr : longint): tparalocation;
+    procedure tx86_64paramanager.getintparaloc(calloption : tproccalloption; nr : longint;var cgpara:TCGPara);
+      var
+        paraloc : pcgparalocation;
       begin
       begin
-         fillchar(result,sizeof(tparalocation),0);
-         result.size:=OS_INT;
-         if nr<1 then
-           internalerror(200304303)
-         else if nr<=high(paraintsupregs)+1 then
-           begin
-              result.loc:=LOC_REGISTER;
-              result.register:=newreg(R_INTREGISTER,paraintsupregs[nr-1],R_SUBWHOLE);
-           end
-         else
-           begin
-              result.loc:=LOC_REFERENCE;
-              result.reference.index:=NR_STACK_POINTER_REG;
-              result.reference.offset:=(nr-6)*8;
-           end;
+        cgpara.reset;
+        cgpara.size:=OS_INT;
+        cgpara.alignment:=get_para_align(calloption);
+        paraloc:=cgpara.add_location;
+        with paraloc^ do
+         begin
+           size:=OS_INT;
+           if nr<1 then
+             internalerror(200304303)
+           else if nr<=high(paraintsupregs)+1 then
+             begin
+                loc:=LOC_REGISTER;
+                register:=newreg(R_INTREGISTER,paraintsupregs[nr-1],R_SUBWHOLE);
+             end
+           else
+             begin
+                loc:=LOC_REFERENCE;
+                reference.index:=NR_STACK_POINTER_REG;
+                reference.offset:=(nr-6)*sizeof(aint);
+             end;
+          end;
       end;
       end;
 
 
 
 
     procedure tx86_64paramanager.create_funcret_paraloc_info(p : tabstractprocdef; side: tcallercallee);
     procedure tx86_64paramanager.create_funcret_paraloc_info(p : tabstractprocdef; side: tcallercallee);
       var
       var
-        paraloc : tparalocation;
+        paraloc : pcgparalocation;
+        retcgsize : tcgsize;
       begin
       begin
-        { Function return }
-        fillchar(paraloc,sizeof(tparalocation),0);
+        { Constructors return self instead of a boolean }
         if (p.proctypeoption=potype_constructor) then
         if (p.proctypeoption=potype_constructor) then
-          paraloc.size:=OS_ADDR
+          retcgsize:=OS_ADDR
         else
         else
-          paraloc.size:=def_cgsize(p.rettype.def);
-        if paraloc.size<>OS_NO then
+          retcgsize:=def_cgsize(p.rettype.def);
+        p.funcret_paraloc[side].reset;
+        p.funcret_paraloc[side].Alignment:=std_param_align;
+        p.funcret_paraloc[side].size:=retcgsize;
+        { void has no location }
+        if is_void(p.rettype.def) then
+          exit;
+        paraloc:=p.funcret_paraloc[side].add_location;
+        { Return in FPU register? }
+        if p.rettype.def.deftype=floatdef then
           begin
           begin
-            { Return in FPU register? }
-            if p.rettype.def.deftype=floatdef then
-              begin
-                case tfloatdef(p.rettype.def).typ of
-                  s32real,s64real:
-                    begin
-                      paraloc.loc:=LOC_MMREGISTER;
-                      paraloc.register:=NR_MM_RESULT_REG;
-                    end;
-                  s64currency,
-                  s64comp,
-                  s80real:
-                    begin
-                      paraloc.loc:=LOC_FPUREGISTER;
-                      paraloc.register:=NR_FPU_RESULT_REG;
-                    end;
-                  else
-                    internalerror(200405034);
+            case tfloatdef(p.rettype.def).typ of
+              s32real,s64real:
+                begin
+                  paraloc^.loc:=LOC_MMREGISTER;
+                  paraloc^.register:=NR_MM_RESULT_REG;
                 end;
                 end;
-              end
-            else
-             { Return in register? }
-             if not ret_in_param(p.rettype.def,p.proccalloption) then
-              begin
-                paraloc.loc:=LOC_REGISTER;
-                paraloc.register:=newreg(R_INTREGISTER,RS_FUNCTION_RETURN_REG,cgsize2subreg(paraloc.size));
-              end
+              s64currency,
+              s64comp,
+              s80real:
+                begin
+                  paraloc^.loc:=LOC_FPUREGISTER;
+                  paraloc^.register:=NR_FPU_RESULT_REG;
+                end;
+              else
+                internalerror(200405034);
+            end;
+            paraloc^.size:=retcgsize;
+          end
+        else
+         { Return in register? }
+         if not ret_in_param(p.rettype.def,p.proccalloption) then
+          begin
+            paraloc^.loc:=LOC_REGISTER;
+            paraloc^.size:=retcgsize;
+            if side=callerside then
+              paraloc^.register:=newreg(R_INTREGISTER,RS_FUNCTION_RESULT_REG,cgsize2subreg(retcgsize))
             else
             else
-              begin
-                paraloc.loc:=LOC_REFERENCE;
-              end;
+              paraloc^.register:=newreg(R_INTREGISTER,RS_FUNCTION_RETURN_REG,cgsize2subreg(retcgsize));
           end
           end
         else
         else
-          paraloc.loc:=LOC_INVALID;
-        p.funcret_paraloc[side]:=paraloc;
+          begin
+            paraloc^.loc:=LOC_REFERENCE;
+            paraloc^.size:=retcgsize;
+          end;
       end;
       end;
 
 
 
 
@@ -239,9 +246,12 @@ unit cpupara;
                                                             var intparareg,mmparareg,parasize:longint);
                                                             var intparareg,mmparareg,parasize:longint);
       var
       var
         hp : tparaitem;
         hp : tparaitem;
-        paraloc : tparalocation;
+        paraloc,
+        paraloc2 : pcgparalocation;
         subreg : tsubregister;
         subreg : tsubregister;
         pushaddr : boolean;
         pushaddr : boolean;
+        paracgsize : tcgsize;
+        loc1,loc2 : tcgloc;
         l,
         l,
         varalign,
         varalign,
         paraalign : longint;
         paraalign : longint;
@@ -254,84 +264,110 @@ unit cpupara;
             pushaddr:=push_addr_param(hp.paratyp,hp.paratype.def,p.proccalloption);
             pushaddr:=push_addr_param(hp.paratyp,hp.paratype.def,p.proccalloption);
             if pushaddr then
             if pushaddr then
               begin
               begin
-                paraloc.size:=OS_ADDR;
-                paraloc.loc:=LOC_REGISTER;
-                paraloc.lochigh:=LOC_INVALID;
+                loc1:=LOC_REGISTER;
+                loc2:=LOC_INVALID;
+                paracgsize:=OS_ADDR;
               end
               end
             else
             else
-              getvalueparaloc(hp.paratype.def,paraloc);
-            paraloc.alignment:=paraalign;
-            { Location low }
-            if (paraloc.loc=LOC_REGISTER) and
+              begin
+                getvalueparaloc(hp.paratype.def,loc1,loc2);
+                paracgsize:=def_cgsize(hp.paratype.def);
+                if paracgsize=OS_C64 then
+                  paracgsize:=OS_64;
+              end;
+            hp.paraloc[side].reset;
+            hp.paraloc[side].size:=paracgsize;
+            hp.paraloc[side].Alignment:=paraalign;
+            { First location }
+            paraloc:=hp.paraloc[side].add_location;
+            paraloc^.size:=paracgsize;
+            if (loc1=LOC_REGISTER) and
                (intparareg<=high(paraintsupregs)) then
                (intparareg<=high(paraintsupregs)) then
               begin
               begin
-                if (paraloc.size=OS_NO) or (paraloc.lochigh<>LOC_INVALID) then
-                  subreg:=R_SUBWHOLE
+                if (paracgsize=OS_NO) or (loc2<>LOC_INVALID) then
+                  begin
+                    paraloc^.size:=OS_INT;
+                    subreg:=R_SUBWHOLE;
+                  end
                 else
                 else
-                  subreg:=cgsize2subreg(paraloc.size);
-                paraloc.register:=newreg(R_INTREGISTER,paraintsupregs[intparareg],subreg);
+                  begin
+                    paraloc^.size:=paracgsize;
+                    subreg:=cgsize2subreg(paracgsize);
+                  end;
+                paraloc^.loc:=LOC_REGISTER;
+                paraloc^.register:=newreg(R_INTREGISTER,paraintsupregs[intparareg],subreg);
                 inc(intparareg);
                 inc(intparareg);
               end
               end
-            else if (paraloc.loc=LOC_MMREGISTER) and
-               (mmparareg<=high(parammsupregs)) then
+            else if (loc1=LOC_MMREGISTER) and
+                    (mmparareg<=high(parammsupregs)) then
               begin
               begin
-                paraloc.register:=newreg(R_MMREGISTER,parammsupregs[mmparareg],R_SUBNONE);
+                paraloc^.loc:=LOC_MMREGISTER;
+                paraloc^.register:=newreg(R_MMREGISTER,parammsupregs[mmparareg],R_SUBNONE);
+                if paracgsize=OS_F128 then
+                  paraloc^.size:=OS_F64
+                else
+                  paraloc^.size:=paracgsize;
                 inc(mmparareg);
                 inc(mmparareg);
               end
               end
             else
             else
               begin
               begin
-                paraloc.loc:=LOC_REFERENCE;
-                paraloc.lochigh:=LOC_INVALID;
+                paraloc^.loc:=LOC_REFERENCE;
                 if side=callerside then
                 if side=callerside then
-                  paraloc.reference.index:=NR_STACK_POINTER_REG
+                  paraloc^.reference.index:=NR_STACK_POINTER_REG
                 else
                 else
-                  paraloc.reference.index:=NR_FRAME_POINTER_REG;
+                  paraloc^.reference.index:=NR_FRAME_POINTER_REG;
                 l:=push_size(hp.paratyp,hp.paratype.def,p.proccalloption);
                 l:=push_size(hp.paratyp,hp.paratype.def,p.proccalloption);
                 varalign:=size_2_align(l);
                 varalign:=size_2_align(l);
-                paraloc.reference.offset:=parasize;
+                paraloc^.reference.offset:=parasize;
                 varalign:=used_align(varalign,paraalign,paraalign);
                 varalign:=used_align(varalign,paraalign,paraalign);
                 parasize:=align(parasize+l,varalign);
                 parasize:=align(parasize+l,varalign);
               end;
               end;
-            { Location High if required }
-            if (paraloc.lochigh<>LOC_INVALID) then
+            { Second location }
+            if (loc2<>LOC_INVALID) then
               begin
               begin
-                if (paraloc.lochigh=LOC_REGISTER) and
+                if (loc2=LOC_REGISTER) and
                    (intparareg<=high(paraintsupregs)) then
                    (intparareg<=high(paraintsupregs)) then
                   begin
                   begin
-                    paraloc.registerhigh:=newreg(R_INTREGISTER,paraintsupregs[intparareg],R_SUBWHOLE);
+                    paraloc2:=hp.paraloc[side].add_location;
+                    paraloc2^.loc:=LOC_REGISTER;
+                    paraloc2^.register:=newreg(R_INTREGISTER,paraintsupregs[intparareg],R_SUBWHOLE);
+                    paraloc2^.size:=OS_INT;
                     inc(intparareg);
                     inc(intparareg);
                   end
                   end
                 else
                 else
-                 if (paraloc.lochigh=LOC_MMREGISTER) and
+                 if (loc2=LOC_MMREGISTER) and
                     (mmparareg<=high(parammsupregs)) then
                     (mmparareg<=high(parammsupregs)) then
                   begin
                   begin
-                    paraloc.registerhigh:=newreg(R_MMREGISTER,parammsupregs[mmparareg],R_SUBNONE);
+                    paraloc2:=hp.paraloc[side].add_location;
+                    paraloc2^.loc:=LOC_REGISTER;
+                    paraloc2^.register:=newreg(R_MMREGISTER,parammsupregs[mmparareg],R_SUBNONE);
+                    if paracgsize=OS_F128 then
+                      paraloc2^.size:=OS_F64
+                    else
+                      paraloc2^.size:=paracgsize;
                     inc(mmparareg);
                     inc(mmparareg);
                   end
                   end
                 else
                 else
                   begin
                   begin
                     { Release when location low has already registers
                     { Release when location low has already registers
                       assigned }
                       assigned }
-                    if paraloc.loc=LOC_REGISTER then
+                    if paraloc^.loc=LOC_REGISTER then
                       dec(intparareg);
                       dec(intparareg);
-                    if paraloc.loc=LOC_MMREGISTER then
+                    if paraloc^.loc=LOC_MMREGISTER then
                       dec(mmparareg);
                       dec(mmparareg);
                     { Overwrite with LOC_REFERENCE }
                     { Overwrite with LOC_REFERENCE }
-                    paraloc.loc:=LOC_REFERENCE;
-                    paraloc.lochigh:=LOC_INVALID;
-                    fillchar(paraloc.reference,sizeof(paraloc.reference),0);
+                    paraloc^.loc:=LOC_REFERENCE;
                     if side=callerside then
                     if side=callerside then
-                      paraloc.reference.index:=NR_STACK_POINTER_REG
+                      paraloc^.reference.index:=NR_STACK_POINTER_REG
                     else
                     else
-                      paraloc.reference.index:=NR_FRAME_POINTER_REG;
+                      paraloc^.reference.index:=NR_FRAME_POINTER_REG;
                     l:=push_size(hp.paratyp,hp.paratype.def,p.proccalloption);
                     l:=push_size(hp.paratyp,hp.paratype.def,p.proccalloption);
                     varalign:=size_2_align(l);
                     varalign:=size_2_align(l);
-                    paraloc.reference.offset:=parasize;
+                    paraloc^.reference.offset:=parasize;
                     varalign:=used_align(varalign,paraalign,paraalign);
                     varalign:=used_align(varalign,paraalign,paraalign);
                     parasize:=align(parasize+l,varalign);
                     parasize:=align(parasize+l,varalign);
                   end;
                   end;
               end;
               end;
-            hp.paraloc[side]:=paraloc;
             hp:=tparaitem(hp.next);
             hp:=tparaitem(hp.next);
           end;
           end;
         { Register parameters are assigned from left-to-right, but the
         { Register parameters are assigned from left-to-right, but the
@@ -343,8 +379,9 @@ unit cpupara;
             hp:=tparaitem(p.para.first);
             hp:=tparaitem(p.para.first);
             while assigned(hp) do
             while assigned(hp) do
               begin
               begin
-                if (hp.paraloc[side].loc=LOC_REFERENCE) then
-                  inc(hp.paraloc[side].reference.offset,target_info.first_parm_offset);
+                with hp.paraloc[side].location^ do
+                  if (loc=LOC_REFERENCE) then
+                    inc(reference.offset,target_info.first_parm_offset);
                 hp:=tparaitem(hp.next);
                 hp:=tparaitem(hp.next);
               end;
               end;
           end;
           end;
@@ -390,7 +427,13 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.9  2004-06-20 08:55:32  florian
+  Revision 1.10  2004-09-21 17:25:13  peter
+    * paraloc branch merged
+
+  Revision 1.9.4.1  2004/08/31 20:43:06  peter
+    * paraloc patch
+
+  Revision 1.9  2004/06/20 08:55:32  florian
     * logs truncated
     * logs truncated
 
 
   Revision 1.8  2004/06/16 20:07:11  florian
   Revision 1.8  2004/06/16 20:07:11  florian