mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-27 20:13:43 +02:00
111 lines
3.8 KiB
ObjectPascal
111 lines
3.8 KiB
ObjectPascal
{
|
|
Copyright (c) 2002 by Florian Klaempfl
|
|
|
|
Risc-V32 specific calling conventions
|
|
|
|
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 cpupara;
|
|
|
|
{$i fpcdefs.inc}
|
|
|
|
interface
|
|
|
|
uses
|
|
globtype,
|
|
aasmtai,aasmdata,
|
|
cpubase,
|
|
symconst,symtype,symdef,symsym,
|
|
paramgr,parabase,cgbase,cgutils,
|
|
pararv;
|
|
|
|
type
|
|
tcpuparamanager = class(trvparamanager)
|
|
function push_addr_param(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean;override;
|
|
|
|
function create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;override;
|
|
end;
|
|
|
|
implementation
|
|
|
|
uses
|
|
cpuinfo,globals,
|
|
verbose,systems,
|
|
defutil,symtable,
|
|
procinfo,cpupi;
|
|
|
|
function tcpuparamanager.push_addr_param(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean;
|
|
begin
|
|
result:=false;
|
|
{ var,out,constref always require address }
|
|
if varspez in [vs_var,vs_out,vs_constref] then
|
|
begin
|
|
result:=true;
|
|
exit;
|
|
end;
|
|
case def.typ of
|
|
variantdef,
|
|
formaldef :
|
|
result:=true;
|
|
{ regular procvars must be passed by value, because you cannot pass
|
|
the address of a local stack location when calling e.g.
|
|
pthread_create with the address of a function (first of all it
|
|
expects the address of the function to execute and not the address
|
|
of a memory location containing that address, and secondly if you
|
|
first store the address on the stack and then pass the address of
|
|
this stack location, then this stack location may no longer be
|
|
valid when the newly started thread accesses it.
|
|
|
|
However, for "procedure of object" we must use the same calling
|
|
convention as for "8 byte record" due to the need for
|
|
interchangeability with the TMethod record type.
|
|
}
|
|
procvardef,
|
|
recorddef:
|
|
result := not(def.size in [0..sizeof(aint)*2]) or (varspez = vs_const);
|
|
arraydef:
|
|
result:=(tarraydef(def).highrange>=tarraydef(def).lowrange) or
|
|
is_open_array(def) or
|
|
is_array_of_const(def) or
|
|
is_array_constructor(def);
|
|
objectdef :
|
|
result:=is_object(def);
|
|
setdef :
|
|
result:=not is_smallset(def);
|
|
stringdef :
|
|
result:=tstringdef(def).stringtype in [st_shortstring,st_longstring];
|
|
else
|
|
;
|
|
end;
|
|
end;
|
|
|
|
|
|
function tcpuparamanager.create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;
|
|
var
|
|
cur_stack_offset: aword;
|
|
curintreg, curfloatreg, curmmreg: tsuperregister;
|
|
begin
|
|
init_values(curintreg,curfloatreg,curmmreg,cur_stack_offset);
|
|
|
|
result := create_paraloc_info_intern(p,side,p.paras,curintreg,curfloatreg,curmmreg,cur_stack_offset,false);
|
|
|
|
create_funcretloc_info(p,side);
|
|
end;
|
|
|
|
begin
|
|
paramanager:=tcpuparamanager.create;
|
|
end.
|