mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-05-08 21:52:35 +02:00
120 lines
3.4 KiB
ObjectPascal
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.
|
|
|