Browse Source

* fixed code generation after recent changes of int_cgsize()
* initial code generation for gprof

git-svn-id: trunk@3271 -

tom_at_work 19 years ago
parent
commit
f31ede0b12

+ 16 - 6
compiler/powerpc64/cgcpu.pas

@@ -99,6 +99,7 @@ type
     procedure g_flags2reg(list: TAsmList; size: TCgSize; const f: TResFlags;
     procedure g_flags2reg(list: TAsmList; size: TCgSize; const f: TResFlags;
       reg: TRegister); override;
       reg: TRegister); override;
 
 
+    procedure g_profilecode(list: TAsmList); override;
     procedure g_proc_entry(list: TAsmList; localsize: longint; nostackframe:
     procedure g_proc_entry(list: TAsmList; localsize: longint; nostackframe:
       boolean); override;
       boolean); override;
     procedure g_proc_exit(list: TAsmList; parasize: longint; nostackframe:
     procedure g_proc_exit(list: TAsmList; parasize: longint; nostackframe:
@@ -182,7 +183,7 @@ uses
   sysutils,
   sysutils,
   globals, verbose, systems, cutils,
   globals, verbose, systems, cutils,
   symconst, symsym, fmodule,
   symconst, symsym, fmodule,
-  rgobj, tgobj, cpupi, procinfo, paramgr;
+  rgobj, tgobj, cpupi, procinfo, paramgr, cpupara;
 
 
 function ref2string(const ref : treference) : string;
 function ref2string(const ref : treference) : string;
 begin
 begin
@@ -1299,6 +1300,14 @@ begin
       end;
       end;
 end;
 end;
 
 
+
+procedure tcgppc.g_profilecode(list: TAsmList);
+begin
+    // TODO: save GPRs
+    a_call_name_direct(list, '_mcount', false, true);
+    // TODO: restore GPRs
+end;
+
 { Generates the entry code of a procedure/function.
 { Generates the entry code of a procedure/function.
 
 
  This procedure may be called before, as well as after g_return_from_proc
  This procedure may be called before, as well as after g_return_from_proc
@@ -1356,12 +1365,12 @@ var
         end;
         end;
       { VMX registers not supported by FPC atm }
       { VMX registers not supported by FPC atm }
 
 
-      { in this branch we may always need to store LR ourselves}
+      { in this branch we always need to store LR ourselves}
       mayNeedLRStore := true;
       mayNeedLRStore := true;
     end;
     end;
 
 
     { we may need to store R0 (=LR) ourselves }
     { we may need to store R0 (=LR) ourselves }
-    if (mayNeedLRStore) and (needslinkreg) then begin
+    if ((cs_profile in initmoduleswitches) or (mayNeedLRStore)) and (needslinkreg) then begin
       reference_reset_base(href, NR_STACK_POINTER_REG, LA_LR_ELF);
       reference_reset_base(href, NR_STACK_POINTER_REG, LA_LR_ELF);
       list.concat(taicpu.op_reg_ref(A_STD, NR_R0, href));
       list.concat(taicpu.op_reg_ref(A_STD, NR_R0, href));
     end;
     end;
@@ -1369,7 +1378,6 @@ var
 
 
 var
 var
   href: treference;
   href: treference;
-
 begin
 begin
   calcFirstUsedFPR(firstregfpu, fprcount);
   calcFirstUsedFPR(firstregfpu, fprcount);
   calcFirstUsedGPR(firstreggpr, gprcount);
   calcFirstUsedGPR(firstreggpr, gprcount);
@@ -1380,7 +1388,8 @@ begin
 
 
   { determine whether we need to save the link register }
   { determine whether we need to save the link register }
   needslinkreg :=
   needslinkreg :=
-    ((not (po_assembler in current_procinfo.procdef.procoptions)) and (pi_do_call in current_procinfo.flags)) or
+    ((not (po_assembler in current_procinfo.procdef.procoptions)) and 
+      ((pi_do_call in current_procinfo.flags) or (cs_profile in initmoduleswitches))) or
     ((cs_opt_size in aktoptimizerswitches) and ((fprcount > 0) or (gprcount > 0))) or
     ((cs_opt_size in aktoptimizerswitches) and ((fprcount > 0) or (gprcount > 0))) or
     ([cs_lineinfo, cs_debuginfo] * aktmoduleswitches <> []);
     ([cs_lineinfo, cs_debuginfo] * aktmoduleswitches <> []);
 
 
@@ -1518,7 +1527,8 @@ begin
 
 
   { determine whether we need to restore the link register }
   { determine whether we need to restore the link register }
   needslinkreg :=
   needslinkreg :=
-    ((not (po_assembler in current_procinfo.procdef.procoptions)) and (pi_do_call in current_procinfo.flags)) or
+    ((not (po_assembler in current_procinfo.procdef.procoptions)) and 
+      ((pi_do_call in current_procinfo.flags) or (cs_profile in initmoduleswitches))) or
     ((cs_opt_size in aktoptimizerswitches) and ((fprcount > 0) or (gprcount > 0))) or
     ((cs_opt_size in aktoptimizerswitches) and ((fprcount > 0) or (gprcount > 0))) or
     ([cs_lineinfo, cs_debuginfo] * aktmoduleswitches <> []);
     ([cs_lineinfo, cs_debuginfo] * aktmoduleswitches <> []);
 
 

+ 2 - 1
compiler/powerpc64/cpubase.pas

@@ -348,7 +348,8 @@ const
      stdcall and cdecl. The alignment value should be the one defined
      stdcall and cdecl. The alignment value should be the one defined
      by GCC or the target ABI.
      by GCC or the target ABI.
   }
   }
-  std_param_align = 16;
+  std_param_align = 8;
+  vmx_std_param_align = 16;
 
 
   {*****************************************************************************
   {*****************************************************************************
                               CPU Dependent Constants
                               CPU Dependent Constants

+ 13 - 15
compiler/powerpc64/cpupara.pas

@@ -90,7 +90,7 @@ begin
   with paraloc^ do begin
   with paraloc^ do begin
     size := OS_INT;
     size := OS_INT;
     if (nr <= 8) then begin
     if (nr <= 8) then begin
-      if nr = 0 then
+      if (nr = 0) then
         internalerror(200309271);
         internalerror(200309271);
       loc := LOC_REGISTER;
       loc := LOC_REGISTER;
       register := newreg(R_INTREGISTER, RS_R2 + nr, R_SUBWHOLE);
       register := newreg(R_INTREGISTER, RS_R2 + nr, R_SUBWHOLE);
@@ -248,10 +248,9 @@ end;
 
 
 function tppcparamanager.create_paraloc_info(p: tabstractprocdef; side:
 function tppcparamanager.create_paraloc_info(p: tabstractprocdef; side:
   tcallercallee): longint;
   tcallercallee): longint;
-
 var
 var
   cur_stack_offset: aword;
   cur_stack_offset: aword;
-  curintreg, curfloatreg, curmmreg: tsuperregister;
+  curintreg, curfloatreg, curmmreg : tsuperregister;
 begin
 begin
   init_values(curintreg, curfloatreg, curmmreg, cur_stack_offset);
   init_values(curintreg, curfloatreg, curmmreg, cur_stack_offset);
 
 
@@ -265,7 +264,6 @@ function tppcparamanager.create_paraloc_info_intern(p: tabstractprocdef; side:
   tcallercallee; paras: tparalist;
   tcallercallee; paras: tparalist;
   var curintreg, curfloatreg, curmmreg: tsuperregister; var cur_stack_offset:
   var curintreg, curfloatreg, curmmreg: tsuperregister; var cur_stack_offset:
   aword; isVararg : boolean): longint;
   aword; isVararg : boolean): longint;
-
 var
 var
   stack_offset: longint;
   stack_offset: longint;
   paralen: aint;
   paralen: aint;
@@ -280,6 +278,7 @@ var
   parashift : byte;
   parashift : byte;
 
 
 begin
 begin
+//writeln('begin create_paraloc_info');
 {$IFDEF extdebug}
 {$IFDEF extdebug}
   if po_explicitparaloc in p.procoptions then
   if po_explicitparaloc in p.procoptions then
     internalerror(200411141);
     internalerror(200411141);
@@ -341,7 +340,7 @@ begin
           loc := LOC_REGISTER;
           loc := LOC_REGISTER;
           paracgsize := int_cgsize(paralen);
           paracgsize := int_cgsize(paralen);
           if (paralen in [3,5,6,7]) then
           if (paralen in [3,5,6,7]) then
-            parashift := (tcgsize2size[paracgsize]-paralen) * 8;
+            parashift := (8-paralen) * 8;
         end;
         end;
       end else begin
       end else begin
         loc := getparaloc(paradef);
         loc := getparaloc(paradef);
@@ -382,14 +381,13 @@ begin
         paraloc^.loc := loc;
         paraloc^.loc := loc;
         paraloc^.shiftval := parashift;
         paraloc^.shiftval := parashift;
 
 
-        if (paracgsize <> OS_NO) then
-          { make sure we don't lose whether or not the type is signed }
-          if (paradef.deftype <> orddef) then
-            paraloc^.size := int_cgsize(paralen)
-          else
-            paraloc^.size := paracgsize
-        else
-          paraloc^.size := OS_INT;
+        { make sure we don't lose whether or not the type is signed }
+        if (paracgsize <> OS_NO) and (paradef.deftype <> orddef) then
+          paracgsize := int_cgsize(paralen);
+        if (paracgsize = OS_NO) then
+          paraloc^.size := OS_INT
+        else 
+          paraloc^.size := paracgsize;
 
 
         paraloc^.register := newreg(R_INTREGISTER, nextintreg, R_SUBNONE);
         paraloc^.register := newreg(R_INTREGISTER, nextintreg, R_SUBNONE);
         inc(nextintreg);
         inc(nextintreg);
@@ -406,7 +404,7 @@ begin
         inc(nextintreg);
         inc(nextintreg);
         inc(nextfloatreg);
         inc(nextfloatreg);
         dec(paralen, tcgsize2size[paraloc^.size]);
         dec(paralen, tcgsize2size[paraloc^.size]);
-        
+     
         inc(stack_offset, tcgsize2size[OS_FLOAT]);
         inc(stack_offset, tcgsize2size[OS_FLOAT]);
       end else if (loc = LOC_MMREGISTER) then begin
       end else if (loc = LOC_MMREGISTER) then begin
         { Altivec not supported }
         { Altivec not supported }
@@ -444,7 +442,7 @@ function tppcparamanager.create_varargs_paraloc_info(p: tabstractprocdef;
 var
 var
   cur_stack_offset: aword;
   cur_stack_offset: aword;
   parasize, l: longint;
   parasize, l: longint;
-  curintreg, firstfloatreg, curfloatreg, curmmreg: tsuperregister;
+  curintreg, firstfloatreg, curfloatreg, curmmreg: tsuperregister;  
   i: integer;
   i: integer;
   hp: tparavarsym;
   hp: tparavarsym;
   paraloc: pcgparalocation;
   paraloc: pcgparalocation;

+ 5 - 5
compiler/powerpc64/cpupi.pas

@@ -68,14 +68,14 @@ var
 begin
 begin
   if not (po_assembler in procdef.procoptions) then begin
   if not (po_assembler in procdef.procoptions) then begin
     { align the stack properly }
     { align the stack properly }
-    ofs := align(maxpushedparasize + LinkageAreaSizeELF, 8);
+    ofs := align(maxpushedparasize + LinkageAreaSizeELF, ELF_STACK_ALIGN);
 
 
     { the ABI specification says that it is required to always allocate space for 8 * 8 bytes
     { the ABI specification says that it is required to always allocate space for 8 * 8 bytes
       for registers R3-R10 and stack header if there's a stack frame, but GCC doesn't do that,
       for registers R3-R10 and stack header if there's a stack frame, but GCC doesn't do that,
       so we don't that too. Uncomment the next three lines if this is required }
       so we don't that too. Uncomment the next three lines if this is required }
-//    if (ofs < 112) then begin
-//      ofs := 112;
-//    end;
+    if (cs_profile in initmoduleswitches) and (ofs < 112) then begin
+      ofs := 112;
+    end;
     tg.setfirsttemp(ofs);
     tg.setfirsttemp(ofs);
   end else begin
   end else begin
     locals := 0;
     locals := 0;
@@ -100,7 +100,7 @@ begin
         numfpr * tcgsize2size[OS_FLOAT], ELF_STACK_ALIGN);
         numfpr * tcgsize2size[OS_FLOAT], ELF_STACK_ALIGN);
 
 
     if (pi_do_call in flags) or (tg.lasttemp <> tg.firsttemp) or
     if (pi_do_call in flags) or (tg.lasttemp <> tg.firsttemp) or
-      (result > RED_ZONE_SIZE) then begin
+      (result > RED_ZONE_SIZE) {or (cs_profile in initmoduleswitches)} then begin
       result := align(result + tg.lasttemp, ELF_STACK_ALIGN);
       result := align(result + tg.lasttemp, ELF_STACK_ALIGN);
     end;
     end;
   end else
   end else

+ 1 - 1
compiler/powerpc64/nppccnv.pas

@@ -79,7 +79,7 @@ begin
     // everything that is less than 64 bits is converted to a 64 bit signed
     // everything that is less than 64 bits is converted to a 64 bit signed
     // integer - because the int_to_real conversion is faster for 64 bit
     // integer - because the int_to_real conversion is faster for 64 bit
     // signed ints compared to 64 bit unsigned ints.
     // signed ints compared to 64 bit unsigned ints.
-    if (not (torddef(left.resulttype.def).typ in [s64bit, u64bit])) then begin
+    if (not (torddef(left.resulttype.def).typ in [s64bit, u64bit, scurrency])) then begin
       inserttypeconv(left, s64inttype);
       inserttypeconv(left, s64inttype);
     end;
     end;
   end;
   end;