mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-18 16:29:19 +02:00
* Xtensa: arrays are always passed as by reference but still returned in up to 4 registers
git-svn-id: trunk@46770 -
This commit is contained in:
parent
6c8b0614b1
commit
965f759c0d
@ -49,7 +49,7 @@ unit cpupara;
|
|||||||
paras : tparalist; var curintreg : tsuperregister;
|
paras : tparalist; var curintreg : tsuperregister;
|
||||||
var cur_stack_offset : aword; varargsparas : boolean) : longint;
|
var cur_stack_offset : aword; varargsparas : boolean) : longint;
|
||||||
function create_paraloc1_info_intern(p: tabstractprocdef; side: tcallercallee; paradef: tdef; var loc: TCGPara; varspez: tvarspez; varoptions: tvaroptions;
|
function create_paraloc1_info_intern(p: tabstractprocdef; side: tcallercallee; paradef: tdef; var loc: TCGPara; varspez: tvarspez; varoptions: tvaroptions;
|
||||||
var curintreg: tsuperregister; var cur_stack_offset: aword; varargsparas: boolean): longint;
|
var curintreg: tsuperregister; var cur_stack_offset: aword; varargsparas, funcret: boolean): longint;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
@ -153,10 +153,7 @@ unit cpupara;
|
|||||||
recorddef :
|
recorddef :
|
||||||
result:=(varspez = vs_const);
|
result:=(varspez = vs_const);
|
||||||
arraydef:
|
arraydef:
|
||||||
result:=((varspez = vs_const) and (tarraydef(def).highrange>=tarraydef(def).lowrange)) or
|
result:=true;
|
||||||
is_open_array(def) or
|
|
||||||
is_array_of_const(def) or
|
|
||||||
is_array_constructor(def);
|
|
||||||
objectdef :
|
objectdef :
|
||||||
result:=is_object(def) and (varspez = vs_const);
|
result:=is_object(def) and (varspez = vs_const);
|
||||||
variantdef,
|
variantdef,
|
||||||
@ -252,7 +249,7 @@ unit cpupara;
|
|||||||
else if (result.def.size>4) and (result.def.size<=16) then
|
else if (result.def.size>4) and (result.def.size<=16) then
|
||||||
begin
|
begin
|
||||||
init_values(p,side,curintreg,cur_stack_offset);
|
init_values(p,side,curintreg,cur_stack_offset);
|
||||||
create_paraloc1_info_intern(p,side,result.def,result,vs_value,[],curintreg,cur_stack_offset,false);
|
create_paraloc1_info_intern(p,side,result.def,result,vs_value,[],curintreg,cur_stack_offset,false,true);
|
||||||
|
|
||||||
{ check if everything is ok }
|
{ check if everything is ok }
|
||||||
if result.location^.loc=LOC_INVALID then
|
if result.location^.loc=LOC_INVALID then
|
||||||
@ -320,7 +317,7 @@ unit cpupara;
|
|||||||
|
|
||||||
|
|
||||||
function tcpuparamanager.create_paraloc1_info_intern(p : tabstractprocdef; side: tcallercallee; paradef:tdef;var loc : TCGPara;varspez : tvarspez;varoptions : tvaroptions;
|
function tcpuparamanager.create_paraloc1_info_intern(p : tabstractprocdef; side: tcallercallee; paradef:tdef;var loc : TCGPara;varspez : tvarspez;varoptions : tvaroptions;
|
||||||
var curintreg: tsuperregister; var cur_stack_offset: aword; varargsparas: boolean):longint;
|
var curintreg: tsuperregister; var cur_stack_offset: aword; varargsparas, funcret: boolean):longint;
|
||||||
var
|
var
|
||||||
paralen: aint;
|
paralen: aint;
|
||||||
locdef,
|
locdef,
|
||||||
@ -349,19 +346,21 @@ unit cpupara;
|
|||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if push_addr_param(varspez,paradef,p.proccalloption) then
|
if not is_special_array(paradef) then
|
||||||
|
paralen:=paradef.size
|
||||||
|
else
|
||||||
|
paralen:=tcgsize2size[def_cgsize(paradef)];
|
||||||
|
|
||||||
|
if (not(funcret) and push_addr_param(varspez,paradef,p.proccalloption)) or
|
||||||
|
(funcret and (paralen>24)) then
|
||||||
begin
|
begin
|
||||||
paradef:=cpointerdef.getreusable_no_free(paradef);
|
paradef:=cpointerdef.getreusable_no_free(paradef);
|
||||||
locpara:=LOC_REGISTER;
|
locpara:=LOC_REGISTER;
|
||||||
paracgsize := OS_ADDR;
|
paracgsize:=OS_ADDR;
|
||||||
paralen := tcgsize2size[OS_ADDR];
|
paralen:=tcgsize2size[OS_ADDR];
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
if not is_special_array(paradef) then
|
|
||||||
paralen := paradef.size
|
|
||||||
else
|
|
||||||
paralen := tcgsize2size[def_cgsize(paradef)];
|
|
||||||
if (paradef.typ in [objectdef,arraydef,recorddef,setdef,stringdef]) and
|
if (paradef.typ in [objectdef,arraydef,recorddef,setdef,stringdef]) and
|
||||||
not is_special_array(paradef) and
|
not is_special_array(paradef) and
|
||||||
(varspez in [vs_value,vs_const]) then
|
(varspez in [vs_value,vs_const]) then
|
||||||
@ -369,10 +368,10 @@ unit cpupara;
|
|||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
paracgsize:=def_cgsize(paradef);
|
paracgsize:=def_cgsize(paradef);
|
||||||
if (paracgsize=OS_NO) then
|
if paracgsize=OS_NO then
|
||||||
begin
|
begin
|
||||||
paracgsize:=OS_ADDR;
|
paracgsize:=OS_ADDR;
|
||||||
paralen := tcgsize2size[OS_ADDR];
|
paralen:=tcgsize2size[OS_ADDR];
|
||||||
paradef:=voidpointertype;
|
paradef:=voidpointertype;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -481,7 +480,7 @@ unit cpupara;
|
|||||||
result:=0;
|
result:=0;
|
||||||
for i:=0 to paras.count-1 do
|
for i:=0 to paras.count-1 do
|
||||||
result:=create_paraloc1_info_intern(p,side,tparavarsym(paras[i]).vardef,tparavarsym(paras[i]).paraloc[side],tparavarsym(paras[i]).varspez,
|
result:=create_paraloc1_info_intern(p,side,tparavarsym(paras[i]).vardef,tparavarsym(paras[i]).paraloc[side],tparavarsym(paras[i]).varspez,
|
||||||
tparavarsym(paras[i]).varoptions,curintreg,cur_stack_offset,false);
|
tparavarsym(paras[i]).varoptions,curintreg,cur_stack_offset,false,false);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user