mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-09 00:08:12 +02:00
* RiscV: unify push_addr_param
This commit is contained in:
parent
b4a83e29a4
commit
9ba3b12eaa
@ -48,6 +48,8 @@ unit pararv;
|
||||
|
||||
function create_varargs_paraloc_info(p: tabstractprocdef; side: tcallercallee; varargspara: tvarargsparalist): longint;override;
|
||||
|
||||
function push_addr_param(varspez: tvarspez; def: tdef; calloption: tproccalloption): boolean;override;
|
||||
|
||||
protected
|
||||
procedure init_values(var curintreg, curfloatreg, curmmreg: tsuperregister; var cur_stack_offset: aword);
|
||||
end;
|
||||
@ -198,6 +200,52 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
function trvparamanager.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 trvparamanager.get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara;
|
||||
var
|
||||
paraloc : pcgparalocation;
|
||||
|
@ -34,8 +34,6 @@ unit cpupara;
|
||||
|
||||
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;
|
||||
|
||||
@ -47,52 +45,6 @@ unit cpupara;
|
||||
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;
|
||||
|
@ -34,7 +34,6 @@ unit cpupara;
|
||||
|
||||
type
|
||||
tcpuparamanager = class(trvparamanager)
|
||||
function push_addr_param(varspez: tvarspez; def: tdef; calloption: tproccalloption): boolean; override;
|
||||
function ret_in_param(def: tdef; pd: tabstractprocdef): boolean; override;
|
||||
|
||||
function create_paraloc_info(p: tabstractprocdef; side: tcallercallee): longint; override;
|
||||
@ -50,39 +49,6 @@ implementation
|
||||
defutil,symtable,symcpu,
|
||||
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;
|
||||
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.ret_in_param(def: tdef; pd: tabstractprocdef): boolean;
|
||||
begin
|
||||
if handle_common_ret_in_param(def,pd,result) then
|
||||
|
Loading…
Reference in New Issue
Block a user