* RiscV: unify push_addr_param

This commit is contained in:
florian 2024-12-25 23:32:47 +01:00
parent b4a83e29a4
commit 9ba3b12eaa
3 changed files with 48 additions and 82 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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