fpc/compiler/powerpc64/cpupi.pas
tom_at_work 3462426b1d * stack frame optimizations
git-svn-id: trunk@2172 -
2006-01-04 23:27:40 +00:00

120 lines
3.4 KiB
ObjectPascal

{
Copyright (c) 2002 by Florian Klaempfl
This unit contains the CPU specific part of tprocinfo
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.
****************************************************************************
}
{ This unit contains the CPU specific part of tprocinfo. }
unit cpupi;
{$I fpcdefs.inc}
interface
uses
cutils,
procinfo, cpuinfo, psub;
type
tppcprocinfo = class(tcgprocinfo)
{ offset where the frame pointer from the outer procedure is stored. }
parent_framepointer_offset: longint;
constructor create(aparent: tprocinfo); override;
procedure set_first_temp_offset; override;
procedure allocate_push_parasize(size: longint); override;
function calc_stackframe_size: longint; override;
function calc_stackframe_size(numgpr, numfpr : longint): longint;
needs_frame_pointer : boolean;
end;
implementation
uses
globtype, globals, systems,
cpubase, cgbase,
aasmtai,
tgobj,
symconst, symsym, paramgr, symutil,
verbose;
constructor tppcprocinfo.create(aparent: tprocinfo);
begin
inherited create(aparent);
maxpushedparasize := 0;
needs_frame_pointer := false;
end;
procedure tppcprocinfo.set_first_temp_offset;
var
ofs: aword;
locals: longint;
begin
if not (po_assembler in procdef.procoptions) then begin
{ align the stack properly }
ofs := align(maxpushedparasize + LinkageAreaSizeELF, 8);
{ 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,
so we don't that too. Uncomment the next three lines if this is required }
// if (ofs < 112) then begin
// ofs := 112;
// end;
tg.setfirsttemp(ofs);
end else begin
locals := 0;
current_procinfo.procdef.localst.foreach_static(@count_locals, @locals);
if locals <> 0 then
{ at 0(r1), the previous value of r1 will be stored }
tg.setfirsttemp(8);
end;
end;
procedure tppcprocinfo.allocate_push_parasize(size: longint);
begin
if size > maxpushedparasize then
maxpushedparasize := size;
end;
function tppcprocinfo.calc_stackframe_size: longint;
begin
result := calc_stackframe_size(18, 18);
end;
function tppcprocinfo.calc_stackframe_size(numgpr, numfpr : longint) : longint;
begin
{ more or less copied from cgcpu.pas/g_stackframe_entry }
if not (po_assembler in procdef.procoptions) then begin
// no VMX support
result := align(numgpr * tcgsize2size[OS_INT] +
numfpr * tcgsize2size[OS_FLOAT], ELF_STACK_ALIGN);
if not ((not (pi_do_call in flags)) and (tg.lasttemp = tg.firsttemp) and
(result <= RED_ZONE_SIZE)) then
result := align(result + tg.lasttemp, ELF_STACK_ALIGN);
end else
result := align(tg.lasttemp, ELF_STACK_ALIGN);
end;
begin
cprocinfo := tppcprocinfo;
end.