mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-01 15:50:16 +02:00
* keep track of whether a routine has a C-style variadic parameter in the
procoptions even when it's through an array-of-const parameter * always call create_varargs_paraloc_info() instead of create_paraloc_info() in the former case, even when no varargs parameters are specified (because on some platforms even some non-variadic parameters need to be passed differently, such as on ARM with gnueabihf) git-svn-id: trunk@41420 -
This commit is contained in:
parent
1a559f5c60
commit
8b9e90dc7a
@ -42,7 +42,7 @@ unit cpupara;
|
||||
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;
|
||||
function create_varargs_paraloc_info(p: tabstractprocdef; varargspara: tvarargsparalist):longint;override;
|
||||
function create_varargs_paraloc_info(p: tabstractprocdef; side: tcallercallee; varargspara: tvarargsparalist):longint;override;
|
||||
function get_funcretloc(p: tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara;override;
|
||||
function param_use_paraloc(const cgpara: tcgpara): boolean; override;
|
||||
private
|
||||
@ -639,12 +639,12 @@ unit cpupara;
|
||||
end;
|
||||
|
||||
|
||||
function tcpuparamanager.create_varargs_paraloc_info(p: tabstractprocdef; varargspara: tvarargsparalist):longint;
|
||||
function tcpuparamanager.create_varargs_paraloc_info(p: tabstractprocdef; side: tcallercallee; varargspara: tvarargsparalist):longint;
|
||||
begin
|
||||
init_para_alloc_values;
|
||||
|
||||
{ non-variadic parameters }
|
||||
create_paraloc_info_intern(p,callerside,p.paras,false);
|
||||
create_paraloc_info_intern(p,side,p.paras,false);
|
||||
if p.proccalloption in cstylearrayofconst then
|
||||
begin
|
||||
{ on Darwin, we cannot use any registers for variadic parameters }
|
||||
@ -654,11 +654,19 @@ unit cpupara;
|
||||
curmmreg:=succ(RS_LAST_MM_PARAM_SUPREG);
|
||||
end;
|
||||
{ continue loading the parameters }
|
||||
create_paraloc_info_intern(p,callerside,varargspara,true);
|
||||
if assigned(varargspara) then
|
||||
begin
|
||||
if side=callerside then
|
||||
create_paraloc_info_intern(p,side,varargspara,true)
|
||||
else
|
||||
internalerror(2019021916);
|
||||
end;
|
||||
result:=curstackoffset;
|
||||
end
|
||||
else
|
||||
internalerror(200410231);
|
||||
|
||||
create_funcretloc_info(p,side);
|
||||
end;
|
||||
|
||||
begin
|
||||
|
@ -42,7 +42,7 @@ unit cpupara;
|
||||
function ret_in_param(def:tdef;pd:tabstractprocdef):boolean;override;
|
||||
procedure getintparaloc(list: TAsmList; pd : tabstractprocdef; nr : longint; var cgpara : tcgpara);override;
|
||||
function create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;override;
|
||||
function create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargsparalist):longint;override;
|
||||
function create_varargs_paraloc_info(p : tabstractprocdef; side: tcallercallee; varargspara:tvarargsparalist):longint;override;
|
||||
function get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara;override;
|
||||
private
|
||||
procedure init_values(p: tabstractprocdef; side: tcallercallee; var curintreg,
|
||||
@ -778,20 +778,30 @@ unit cpupara;
|
||||
end;
|
||||
|
||||
|
||||
function tcpuparamanager.create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargsparalist):longint;
|
||||
function tcpuparamanager.create_varargs_paraloc_info(p : tabstractprocdef; side: tcallercallee; varargspara:tvarargsparalist):longint;
|
||||
var
|
||||
cur_stack_offset: aword;
|
||||
curintreg, curfloatreg, curmmreg: tsuperregister;
|
||||
sparesinglereg:tregister;
|
||||
begin
|
||||
init_values(p,callerside,curintreg,curfloatreg,curmmreg,cur_stack_offset,sparesinglereg);
|
||||
init_values(p,side,curintreg,curfloatreg,curmmreg,cur_stack_offset,sparesinglereg);
|
||||
|
||||
result:=create_paraloc_info_intern(p,callerside,p.paras,curintreg,curfloatreg,curmmreg,cur_stack_offset,sparesinglereg,true);
|
||||
result:=create_paraloc_info_intern(p,side,p.paras,curintreg,curfloatreg,curmmreg,cur_stack_offset,sparesinglereg,true);
|
||||
if (p.proccalloption in cstylearrayofconst) then
|
||||
{ just continue loading the parameters in the registers }
|
||||
result:=create_paraloc_info_intern(p,callerside,varargspara,curintreg,curfloatreg,curmmreg,cur_stack_offset,sparesinglereg,true)
|
||||
begin
|
||||
{ just continue loading the parameters in the registers }
|
||||
if assigned(varargspara) then
|
||||
begin
|
||||
if side=callerside then
|
||||
result:=create_paraloc_info_intern(p,side,varargspara,curintreg,curfloatreg,curmmreg,cur_stack_offset,sparesinglereg,true)
|
||||
else
|
||||
internalerror(2019021915);
|
||||
end;
|
||||
end
|
||||
else
|
||||
internalerror(200410231);
|
||||
|
||||
create_funcretloc_info(p,side);
|
||||
end;
|
||||
|
||||
begin
|
||||
|
@ -39,7 +39,7 @@ unit cpupara;
|
||||
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;
|
||||
function create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargsparalist):longint;override;
|
||||
function create_varargs_paraloc_info(p : tabstractprocdef; side: tcallercallee; varargspara:tvarargsparalist):longint;override;
|
||||
function get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara;override;
|
||||
private
|
||||
procedure init_values(var curintreg, curfloatreg, curmmreg: tsuperregister; var cur_stack_offset: aword);
|
||||
@ -526,17 +526,25 @@ unit cpupara;
|
||||
end;
|
||||
|
||||
|
||||
function tcpuparamanager.create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargsparalist):longint;
|
||||
function tcpuparamanager.create_varargs_paraloc_info(p : tabstractprocdef; side: tcallercallee; varargspara:tvarargsparalist):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,callerside,p.paras,curintreg,curfloatreg,curmmreg,cur_stack_offset);
|
||||
result:=create_paraloc_info_intern(p,side,p.paras,curintreg,curfloatreg,curmmreg,cur_stack_offset);
|
||||
if (p.proccalloption in cstylearrayofconst) then
|
||||
{ just continue loading the parameters in the registers }
|
||||
result:=create_paraloc_info_intern(p,callerside,varargspara,curintreg,curfloatreg,curmmreg,cur_stack_offset)
|
||||
begin
|
||||
{ just continue loading the parameters in the registers }
|
||||
if assigned(varargspara) then
|
||||
begin
|
||||
if side=callerside then
|
||||
result:=create_paraloc_info_intern(p,side,varargspara,curintreg,curfloatreg,curmmreg,cur_stack_offset)
|
||||
else
|
||||
internalerror(2019021914);
|
||||
end;
|
||||
end
|
||||
else
|
||||
internalerror(200410231);
|
||||
end;
|
||||
|
@ -325,6 +325,9 @@ interface
|
||||
{ # returns true if the procdef has no parameters and no specified return type }
|
||||
function is_bareprocdef(pd : tprocdef): boolean;
|
||||
|
||||
{ returns true if the procdef is a C-style variadic function }
|
||||
function is_c_variadic(pd: tabstractprocdef): boolean; {$ifdef USEINLINE}inline;{$endif}
|
||||
|
||||
{ # returns the smallest base integer type whose range encompasses that of
|
||||
both ld and rd; if keep_sign_if_equal, then if ld and rd have the same
|
||||
signdness, the result will also get that signdness }
|
||||
@ -1496,6 +1499,12 @@ implementation
|
||||
(pd.proctypeoption = potype_constructor));
|
||||
end;
|
||||
|
||||
function is_c_variadic(pd: tabstractprocdef): boolean;
|
||||
begin
|
||||
result:=
|
||||
(po_varargs in pd.procoptions) or
|
||||
(po_variadic in pd.procoptions);
|
||||
end;
|
||||
|
||||
function get_common_intdef(ld, rd: torddef; keep_sign_if_equal: boolean): torddef;
|
||||
var
|
||||
|
@ -42,7 +42,7 @@ unit cpupara;
|
||||
function get_volatile_registers_mm(calloption : tproccalloption):tcpuregisterset;override;
|
||||
function get_saved_registers_int(calloption : tproccalloption):tcpuregisterarray;override;
|
||||
function create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;override;
|
||||
function create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargsparalist):longint;override;
|
||||
function create_varargs_paraloc_info(p : tabstractprocdef; side: tcallercallee; varargspara:tvarargsparalist):longint;override;
|
||||
procedure createtempparaloc(list: TAsmList;calloption : tproccalloption;parasym : tparavarsym;can_use_final_stack_loc : boolean;var cgpara:TCGPara);override;
|
||||
function get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): TCGPara;override;
|
||||
private
|
||||
@ -767,15 +767,22 @@ unit cpupara;
|
||||
end;
|
||||
|
||||
|
||||
function tcpuparamanager.create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargsparalist):longint;
|
||||
function tcpuparamanager.create_varargs_paraloc_info(p : tabstractprocdef; side: tcallercallee; varargspara:tvarargsparalist):longint;
|
||||
var
|
||||
parasize : longint;
|
||||
begin
|
||||
parasize:=0;
|
||||
{ calculate the registers for the normal parameters }
|
||||
create_stdcall_paraloc_info(p,callerside,p.paras,parasize);
|
||||
create_stdcall_paraloc_info(p,side,p.paras,parasize);
|
||||
{ append the varargs }
|
||||
create_stdcall_paraloc_info(p,callerside,varargspara,parasize);
|
||||
if assigned(varargspara) then
|
||||
begin
|
||||
if side=callerside then
|
||||
create_stdcall_paraloc_info(p,side,varargspara,parasize)
|
||||
else
|
||||
internalerror(2019021926);
|
||||
end;
|
||||
create_funcretloc_info(p,side);
|
||||
result:=parasize;
|
||||
end;
|
||||
|
||||
|
@ -55,7 +55,7 @@ unit cpupara;
|
||||
}
|
||||
procedure getintparaloc(list: TAsmList; pd : tabstractprocdef; nr : longint; var cgpara : tcgpara);override;
|
||||
function create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;override;
|
||||
function create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargsparalist):longint;override;
|
||||
function create_varargs_paraloc_info(p : tabstractprocdef; side: tcallercallee; varargspara:tvarargsparalist):longint;override;
|
||||
procedure createtempparaloc(list: TAsmList;calloption : tproccalloption;parasym : tparavarsym;can_use_final_stack_loc : boolean;var cgpara:TCGPara);override;
|
||||
function get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): TCGPara;override;
|
||||
private
|
||||
@ -783,15 +783,22 @@ unit cpupara;
|
||||
end;
|
||||
|
||||
|
||||
function tcpuparamanager.create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargsparalist):longint;
|
||||
function tcpuparamanager.create_varargs_paraloc_info(p : tabstractprocdef; side: tcallercallee; varargspara:tvarargsparalist):longint;
|
||||
var
|
||||
parasize : longint;
|
||||
begin
|
||||
parasize:=0;
|
||||
{ calculate the registers for the normal parameters }
|
||||
create_stdcall_paraloc_info(p,callerside,p.paras,parasize);
|
||||
create_stdcall_paraloc_info(p,side,p.paras,parasize);
|
||||
{ append the varargs }
|
||||
create_stdcall_paraloc_info(p,callerside,varargspara,parasize);
|
||||
if assigned(varargspara) then
|
||||
begin
|
||||
if side=callerside then
|
||||
create_stdcall_paraloc_info(p,side,varargspara,parasize)
|
||||
else
|
||||
internalerror(2019021925);
|
||||
end;
|
||||
create_funcretloc_info(p,side);
|
||||
result:=parasize;
|
||||
end;
|
||||
|
||||
|
@ -46,7 +46,7 @@ interface
|
||||
@param(nr Parameter number of routine, starting from 1)}
|
||||
procedure getintparaloc(list: TAsmList; pd : tabstractprocdef; nr : longint; var cgpara : tcgpara);override;
|
||||
function create_paraloc_info(p : TAbstractProcDef; side: tcallercallee):longint;override;
|
||||
function create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargsparalist):longint;override;
|
||||
function create_varargs_paraloc_info(p : tabstractprocdef; side: tcallercallee; varargspara:tvarargsparalist):longint;override;
|
||||
function get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara;override;
|
||||
function param_use_paraloc(const cgpara: tcgpara): boolean; override;
|
||||
function ret_in_param(def:tdef;pd:tabstractprocdef):boolean;override;
|
||||
@ -209,15 +209,22 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
function tcpuparamanager.create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargsparalist):longint;
|
||||
function tcpuparamanager.create_varargs_paraloc_info(p : tabstractprocdef; side: tcallercallee; varargspara:tvarargsparalist):longint;
|
||||
var
|
||||
parasize : longint;
|
||||
begin
|
||||
parasize:=0;
|
||||
{ calculate the registers for the normal parameters }
|
||||
create_paraloc_info_intern(p,callerside,p.paras,parasize);
|
||||
create_paraloc_info_intern(p,side,p.paras,parasize);
|
||||
{ append the varargs }
|
||||
create_paraloc_info_intern(p,callerside,varargspara,parasize);
|
||||
if assigned(varargspara) then
|
||||
begin
|
||||
if side=callerside then
|
||||
create_paraloc_info_intern(p,side,varargspara,parasize)
|
||||
else
|
||||
internalerror(2019021924);
|
||||
end;
|
||||
create_funcretloc_info(p,side);
|
||||
result:=parasize;
|
||||
end;
|
||||
|
||||
|
@ -45,7 +45,7 @@ unit cpupara;
|
||||
function push_addr_param(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean;override;
|
||||
function get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara;override;
|
||||
procedure createtempparaloc(list: TAsmList;calloption : tproccalloption;parasym : tparavarsym;can_use_final_stack_loc : boolean;var cgpara:TCGPara);override;
|
||||
function create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargsparalist):longint;override;
|
||||
function create_varargs_paraloc_info(p : tabstractprocdef; side: tcallercallee; varargspara:tvarargsparalist):longint;override;
|
||||
function parsefuncretloc(p : tabstractprocdef; const s : string) : boolean;override;
|
||||
function get_volatile_registers_int(calloption:tproccalloption):tcpuregisterset;override;
|
||||
function get_volatile_registers_address(calloption:tproccalloption):tcpuregisterset;override;
|
||||
@ -675,18 +675,27 @@ unit cpupara;
|
||||
inherited createtempparaloc(list,calloption,parasym,can_use_final_stack_loc,cgpara);
|
||||
end;
|
||||
|
||||
function tcpuparamanager.create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargsparalist):longint;
|
||||
function tcpuparamanager.create_varargs_paraloc_info(p : tabstractprocdef; side: tcallercallee; varargspara:tvarargsparalist):longint;
|
||||
var
|
||||
cur_stack_offset: aword;
|
||||
begin
|
||||
cur_stack_offset:=0;
|
||||
|
||||
result:=create_stdcall_paraloc_info(p,callerside,p.paras,cur_stack_offset);
|
||||
result:=create_stdcall_paraloc_info(p,side,p.paras,cur_stack_offset);
|
||||
if (p.proccalloption in cstylearrayofconst) then
|
||||
{ just continue loading the parameters in the registers }
|
||||
result:=create_stdcall_paraloc_info(p,callerside,varargspara,cur_stack_offset)
|
||||
begin
|
||||
{ just continue loading the parameters in the registers }
|
||||
if assigned(varargspara) then
|
||||
begin
|
||||
if side=callerside then
|
||||
result:=create_stdcall_paraloc_info(p,side,varargspara,cur_stack_offset)
|
||||
else
|
||||
internalerror(2019021923);
|
||||
end;
|
||||
end
|
||||
else
|
||||
internalerror(200410231);
|
||||
create_funcretloc_info(p,side);
|
||||
end;
|
||||
|
||||
|
||||
|
@ -73,7 +73,7 @@ interface
|
||||
function get_volatile_registers_fpu(calloption : tproccalloption):TCpuRegisterSet;override;
|
||||
function get_saved_registers_int(calloption : tproccalloption):TCpuRegisterArray;override;
|
||||
function create_paraloc_info(p : TAbstractProcDef; side: tcallercallee):longint;override;
|
||||
function create_varargs_paraloc_info(p : TAbstractProcDef; varargspara:tvarargsparalist):longint;override;
|
||||
function create_varargs_paraloc_info(p : TAbstractProcDef; side: tcallercallee; varargspara:tvarargsparalist):longint;override;
|
||||
function get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara;override;
|
||||
function param_use_paraloc(const cgpara: tcgpara): boolean; override;
|
||||
private
|
||||
@ -490,7 +490,7 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
function tcpuparamanager.create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargsparalist):longint;
|
||||
function tcpuparamanager.create_varargs_paraloc_info(p : tabstractprocdef; side: tcallercallee; varargspara:tvarargsparalist):longint;
|
||||
begin
|
||||
intparareg:=0;
|
||||
intparasize:=0;
|
||||
@ -498,13 +498,20 @@ implementation
|
||||
{ Create Function result paraloc }
|
||||
create_funcretloc_info(p,callerside);
|
||||
{ calculate the registers for the normal parameters }
|
||||
create_paraloc_info_intern(p,callerside,p.paras);
|
||||
create_paraloc_info_intern(p,side,p.paras);
|
||||
{ append the varargs }
|
||||
can_use_float := false;
|
||||
{ restore correct intparasize value }
|
||||
if intparareg < 4 then
|
||||
intparasize:=intparareg * 4;
|
||||
create_paraloc_info_intern(p,callerside,varargspara);
|
||||
if assigned(varargspara) then
|
||||
begin
|
||||
if side=callerside then
|
||||
create_paraloc_info_intern(p,side,varargspara)
|
||||
else
|
||||
internalerror(2019021922);
|
||||
end;
|
||||
create_funcretloc_info(p,side);
|
||||
{ We need to return the size allocated on the stack }
|
||||
result:=intparasize;
|
||||
end;
|
||||
|
@ -4416,7 +4416,7 @@ implementation
|
||||
|
||||
{ calculate the parameter size needed for this call include varargs if they are available }
|
||||
if assigned(varargsparas) then
|
||||
pushedparasize:=paramanager.create_varargs_paraloc_info(procdefinition,varargsparas)
|
||||
pushedparasize:=paramanager.create_varargs_paraloc_info(procdefinition,callerside,varargsparas)
|
||||
else
|
||||
pushedparasize:=procdefinition.callerargareasize;
|
||||
|
||||
|
@ -140,7 +140,7 @@ unit paramgr;
|
||||
for the routine that are passed as varargs. It returns
|
||||
the size allocated on the stack (including the normal parameters)
|
||||
}
|
||||
function create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargsparalist):longint;virtual;abstract;
|
||||
function create_varargs_paraloc_info(p : tabstractprocdef; side: tcallercallee; varargspara:tvarargsparalist):longint;virtual;abstract;
|
||||
|
||||
function is_stack_paraloc(paraloc: pcgparalocation): boolean;virtual;
|
||||
procedure createtempparaloc(list: TAsmList;calloption : tproccalloption;parasym : tparavarsym;can_use_final_stack_loc : boolean;var cgpara:TCGPara);virtual;
|
||||
|
@ -1520,6 +1520,13 @@ implementation
|
||||
internalerror(2015052202);
|
||||
end;
|
||||
|
||||
if (pd.proccalloption in cdecl_pocalls) and
|
||||
(pd.paras.count>0) and
|
||||
is_array_of_const(tparavarsym(pd.paras[pd.paras.count-1]).vardef) then
|
||||
begin
|
||||
include(pd.procoptions,po_variadic);
|
||||
end;
|
||||
|
||||
{ file types can't be function results }
|
||||
if assigned(pd) and
|
||||
(pd.returndef.typ=filedef) then
|
||||
|
@ -40,7 +40,7 @@ unit cpupara;
|
||||
|
||||
procedure getintparaloc(list: TAsmList; pd : tabstractprocdef; nr : longint; var cgpara : tcgpara);override;
|
||||
function create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;override;
|
||||
function create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargsparalist):longint;override;
|
||||
function create_varargs_paraloc_info(p : tabstractprocdef; side: tcallercallee; varargspara:tvarargsparalist):longint;override;
|
||||
function get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara;override;
|
||||
private
|
||||
procedure init_values(var curintreg, curfloatreg, curmmreg: tsuperregister; var cur_stack_offset: aword);
|
||||
@ -628,7 +628,7 @@ unit cpupara;
|
||||
end;
|
||||
|
||||
|
||||
function tcpuparamanager.create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargsparalist):longint;
|
||||
function tcpuparamanager.create_varargs_paraloc_info(p : tabstractprocdef; side: tcallercallee; varargspara:tvarargsparalist):longint;
|
||||
var
|
||||
cur_stack_offset: aword;
|
||||
parasize, l: longint;
|
||||
@ -640,36 +640,27 @@ unit cpupara;
|
||||
init_values(curintreg,curfloatreg,curmmreg,cur_stack_offset);
|
||||
firstfloatreg:=curfloatreg;
|
||||
|
||||
result:=create_paraloc_info_intern(p,callerside,p.paras,curintreg,curfloatreg,curmmreg,cur_stack_offset, false);
|
||||
result:=create_paraloc_info_intern(p,side,p.paras,curintreg,curfloatreg,curmmreg,cur_stack_offset, false);
|
||||
if (p.proccalloption in cstylearrayofconst) then
|
||||
{ just continue loading the parameters in the registers }
|
||||
begin
|
||||
result:=create_paraloc_info_intern(p,callerside,varargspara,curintreg,curfloatreg,curmmreg,cur_stack_offset,true);
|
||||
if assigned(varargspara) then
|
||||
begin
|
||||
if side=callerside then
|
||||
result:=create_paraloc_info_intern(p,side,varargspara,curintreg,curfloatreg,curmmreg,cur_stack_offset,true)
|
||||
else
|
||||
internalerror(2019021921);
|
||||
if curfloatreg<>firstfloatreg then
|
||||
include(varargspara.varargsinfo,va_uses_float_reg);
|
||||
end;
|
||||
{ varargs routines have to reserve at least 32 bytes for the AIX abi }
|
||||
if (target_info.abi in [abi_powerpc_aix,abi_powerpc_darwin]) and
|
||||
(result < 32) then
|
||||
result := 32;
|
||||
end
|
||||
else
|
||||
begin
|
||||
parasize:=cur_stack_offset;
|
||||
for i:=0 to varargspara.count-1 do
|
||||
begin
|
||||
hp:=tparavarsym(varargspara[i]);
|
||||
hp.paraloc[callerside].alignment:=4;
|
||||
paraloc:=hp.paraloc[callerside].add_location;
|
||||
paraloc^.loc:=LOC_REFERENCE;
|
||||
paraloc^.size:=def_cgsize(hp.vardef);
|
||||
paraloc^.def:=hp.vardef;
|
||||
paraloc^.reference.index:=NR_STACK_POINTER_REG;
|
||||
l:=push_size(hp.varspez,hp.vardef,p.proccalloption);
|
||||
paraloc^.reference.offset:=parasize;
|
||||
parasize:=parasize+l;
|
||||
end;
|
||||
result:=parasize;
|
||||
end;
|
||||
if curfloatreg<>firstfloatreg then
|
||||
include(varargspara.varargsinfo,va_uses_float_reg);
|
||||
internalerror(2019021710);
|
||||
create_funcretloc_info(p,side);
|
||||
end;
|
||||
|
||||
|
||||
|
@ -45,8 +45,7 @@ type
|
||||
|
||||
procedure getintparaloc(list: TAsmList; pd : tabstractprocdef; nr: longint; var cgpara: tcgpara); override;
|
||||
function create_paraloc_info(p: tabstractprocdef; side: tcallercallee): longint; override;
|
||||
function create_varargs_paraloc_info(p: tabstractprocdef; varargspara:
|
||||
tvarargsparalist): longint; override;
|
||||
function create_varargs_paraloc_info(p: tabstractprocdef; side: tcallercallee; varargspara: tvarargsparalist): longint; override;
|
||||
function get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara;override;
|
||||
|
||||
private
|
||||
@ -743,7 +742,7 @@ implemented
|
||||
end;
|
||||
end;
|
||||
|
||||
function tcpuparamanager.create_varargs_paraloc_info(p: tabstractprocdef;
|
||||
function tcpuparamanager.create_varargs_paraloc_info(p: tabstractprocdef; side: tcallercallee;
|
||||
varargspara: tvarargsparalist): longint;
|
||||
var
|
||||
cur_stack_offset: aword;
|
||||
@ -756,33 +755,28 @@ begin
|
||||
init_values(curintreg, curfloatreg, curmmreg, cur_stack_offset);
|
||||
firstfloatreg := curfloatreg;
|
||||
|
||||
result := create_paraloc_info_intern(p, callerside, p.paras, curintreg,
|
||||
result := create_paraloc_info_intern(p, side, p.paras, curintreg,
|
||||
curfloatreg, curmmreg, cur_stack_offset, false);
|
||||
if (p.proccalloption in cstylearrayofconst) then begin
|
||||
{ just continue loading the parameters in the registers }
|
||||
result := create_paraloc_info_intern(p, callerside, varargspara, curintreg,
|
||||
curfloatreg, curmmreg, cur_stack_offset, true);
|
||||
{ varargs routines have to reserve at least 64 bytes for the PPC64 ABI }
|
||||
if (result < 64) then
|
||||
result := 64;
|
||||
end else begin
|
||||
parasize := cur_stack_offset;
|
||||
for i := 0 to varargspara.count - 1 do begin
|
||||
hp := tparavarsym(varargspara[i]);
|
||||
hp.paraloc[callerside].alignment := 8;
|
||||
paraloc := hp.paraloc[callerside].add_location;
|
||||
paraloc^.loc := LOC_REFERENCE;
|
||||
paraloc^.size := def_cgsize(hp.vardef);
|
||||
paraloc^.def := hp.vardef;
|
||||
paraloc^.reference.index := NR_STACK_POINTER_REG;
|
||||
l := push_size(hp.varspez, hp.vardef, p.proccalloption);
|
||||
paraloc^.reference.offset := parasize;
|
||||
parasize := parasize + l;
|
||||
end;
|
||||
result := parasize;
|
||||
end;
|
||||
if curfloatreg <> firstfloatreg then
|
||||
include(varargspara.varargsinfo, va_uses_float_reg);
|
||||
if (p.proccalloption in cstylearrayofconst) then
|
||||
begin
|
||||
{ just continue loading the parameters in the registers }
|
||||
if assigned(varargspara) then
|
||||
begin
|
||||
if side=callerside then
|
||||
result := create_paraloc_info_intern(p, side, varargspara, curintreg,
|
||||
curfloatreg, curmmreg, cur_stack_offset, true)
|
||||
else
|
||||
internalerror(2019021920);
|
||||
if curfloatreg <> firstfloatreg then
|
||||
include(varargspara.varargsinfo, va_uses_float_reg);
|
||||
end;
|
||||
{ varargs routines have to reserve at least 64 bytes for the PPC64 ABI }
|
||||
if (result < 64) then
|
||||
result := 64;
|
||||
end
|
||||
else
|
||||
internalerror(2019021911);
|
||||
create_funcretloc_info(p, side);
|
||||
end;
|
||||
|
||||
function tcpuparamanager.parseparaloc(p: tparavarsym; const s: string): boolean;
|
||||
|
@ -39,7 +39,7 @@ unit cpupara;
|
||||
|
||||
procedure getintparaloc(list: TAsmList; pd : tabstractprocdef; nr : longint; var cgpara : tcgpara);override;
|
||||
function create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;override;
|
||||
function create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargsparalist):longint;override;
|
||||
function create_varargs_paraloc_info(p : tabstractprocdef; side: tcallercallee; varargspara:tvarargsparalist):longint;override;
|
||||
function get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara;override;
|
||||
private
|
||||
procedure init_values(var curintreg, curfloatreg, curmmreg: tsuperregister; var cur_stack_offset: aword);
|
||||
@ -505,7 +505,7 @@ unit cpupara;
|
||||
end;
|
||||
|
||||
|
||||
function tcpuparamanager.create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargsparalist):longint;
|
||||
function tcpuparamanager.create_varargs_paraloc_info(p : tabstractprocdef; side: tcallercallee; varargspara:tvarargsparalist):longint;
|
||||
var
|
||||
cur_stack_offset: aword;
|
||||
parasize, l: longint;
|
||||
@ -517,32 +517,23 @@ unit cpupara;
|
||||
init_values(curintreg,curfloatreg,curmmreg,cur_stack_offset);
|
||||
firstfloatreg:=curfloatreg;
|
||||
|
||||
result:=create_paraloc_info_intern(p,callerside,p.paras,curintreg,curfloatreg,curmmreg,cur_stack_offset, false);
|
||||
result:=create_paraloc_info_intern(p,side,p.paras,curintreg,curfloatreg,curmmreg,cur_stack_offset, false);
|
||||
if (p.proccalloption in cstylearrayofconst) then
|
||||
{ just continue loading the parameters in the registers }
|
||||
begin
|
||||
result:=create_paraloc_info_intern(p,callerside,varargspara,curintreg,curfloatreg,curmmreg,cur_stack_offset,true);
|
||||
if assigned(varargspara) then
|
||||
begin
|
||||
if side=callerside then
|
||||
result:=create_paraloc_info_intern(p,side,varargspara,curintreg,curfloatreg,curmmreg,cur_stack_offset,true)
|
||||
else
|
||||
internalerror(2019021919);
|
||||
if curfloatreg<>firstfloatreg then
|
||||
include(varargspara.varargsinfo,va_uses_float_reg);
|
||||
end;
|
||||
end
|
||||
else
|
||||
begin
|
||||
parasize:=cur_stack_offset;
|
||||
for i:=0 to varargspara.count-1 do
|
||||
begin
|
||||
hp:=tparavarsym(varargspara[i]);
|
||||
hp.paraloc[callerside].alignment:=4;
|
||||
paraloc:=hp.paraloc[callerside].add_location;
|
||||
paraloc^.loc:=LOC_REFERENCE;
|
||||
paraloc^.size:=def_cgsize(hp.vardef);
|
||||
paraloc^.def:=hp.vardef;
|
||||
paraloc^.reference.index:=NR_STACK_POINTER_REG;
|
||||
l:=push_size(hp.varspez,hp.vardef,p.proccalloption);
|
||||
paraloc^.reference.offset:=parasize;
|
||||
parasize:=parasize+l;
|
||||
end;
|
||||
result:=parasize;
|
||||
end;
|
||||
if curfloatreg<>firstfloatreg then
|
||||
include(varargspara.varargsinfo,va_uses_float_reg);
|
||||
internalerror(2019021912);
|
||||
create_funcretloc_info(p,side);
|
||||
end;
|
||||
|
||||
begin
|
||||
|
@ -40,7 +40,7 @@ unit cpupara;
|
||||
|
||||
procedure getintparaloc(list: TAsmList; pd : tabstractprocdef; nr: longint; var cgpara: tcgpara); override;
|
||||
function create_paraloc_info(p: tabstractprocdef; side: tcallercallee): longint; override;
|
||||
function create_varargs_paraloc_info(p: tabstractprocdef; varargspara: tvarargsparalist): longint; override;
|
||||
function create_varargs_paraloc_info(p: tabstractprocdef; side: tcallercallee; varargspara: tvarargsparalist): longint; override;
|
||||
function get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara;override;
|
||||
|
||||
private
|
||||
@ -490,7 +490,7 @@ implementation
|
||||
end;
|
||||
end;
|
||||
|
||||
function tcpuparamanager.create_varargs_paraloc_info(p: tabstractprocdef;
|
||||
function tcpuparamanager.create_varargs_paraloc_info(p: tabstractprocdef; side: tcallercallee;
|
||||
varargspara: tvarargsparalist): longint;
|
||||
var
|
||||
cur_stack_offset: aword;
|
||||
@ -503,33 +503,29 @@ begin
|
||||
init_values(curintreg, curfloatreg, curmmreg, cur_stack_offset);
|
||||
firstfloatreg := curfloatreg;
|
||||
|
||||
result := create_paraloc_info_intern(p, callerside, p.paras, curintreg,
|
||||
result := create_paraloc_info_intern(p, side, p.paras, curintreg,
|
||||
curfloatreg, curmmreg, cur_stack_offset, false);
|
||||
if (p.proccalloption in [pocall_cdecl, pocall_cppdecl, pocall_mwpascal]) then begin
|
||||
{ just continue loading the parameters in the registers }
|
||||
result := create_paraloc_info_intern(p, callerside, varargspara, curintreg,
|
||||
curfloatreg, curmmreg, cur_stack_offset, true);
|
||||
{ varargs routines have to reserve at least 64 bytes for the RiscV ABI }
|
||||
if (result < 64) then
|
||||
result := 64;
|
||||
end else begin
|
||||
parasize := cur_stack_offset;
|
||||
for i := 0 to varargspara.count - 1 do begin
|
||||
hp := tparavarsym(varargspara[i]);
|
||||
hp.paraloc[callerside].alignment := 8;
|
||||
paraloc := hp.paraloc[callerside].add_location;
|
||||
paraloc^.loc := LOC_REFERENCE;
|
||||
paraloc^.size := def_cgsize(hp.vardef);
|
||||
paraloc^.def := hp.vardef;
|
||||
paraloc^.reference.index := NR_STACK_POINTER_REG;
|
||||
l := push_size(hp.varspez, hp.vardef, p.proccalloption);
|
||||
paraloc^.reference.offset := parasize;
|
||||
parasize := parasize + l;
|
||||
end;
|
||||
result := parasize;
|
||||
end;
|
||||
if curfloatreg <> firstfloatreg then
|
||||
include(varargspara.varargsinfo, va_uses_float_reg);
|
||||
if (p.proccalloption in [pocall_cdecl, pocall_cppdecl, pocall_mwpascal]) then
|
||||
begin
|
||||
{ just continue loading the parameters in the registers }
|
||||
if assigned(varargspara) then
|
||||
begin
|
||||
if side=callerside then
|
||||
result := create_paraloc_info_intern(p, side, varargspara, curintreg,
|
||||
curfloatreg, curmmreg, cur_stack_offset, true)
|
||||
else
|
||||
internalerror(2019021918);
|
||||
if curfloatreg <> firstfloatreg then
|
||||
include(varargspara.varargsinfo, va_uses_float_reg);
|
||||
end;
|
||||
{ varargs routines have to reserve at least 64 bytes for the RiscV ABI }
|
||||
if (result < 64) then
|
||||
result := 64;
|
||||
end
|
||||
else
|
||||
internalerror(2019021913);
|
||||
|
||||
create_funcretloc_info(p, side);
|
||||
end;
|
||||
|
||||
function tcpuparamanager.parseparaloc(p: tparavarsym; const s: string): boolean;
|
||||
|
@ -35,7 +35,7 @@ interface
|
||||
function get_volatile_registers_int(calloption : tproccalloption):TCpuRegisterSet;override;
|
||||
function get_volatile_registers_fpu(calloption : tproccalloption):TCpuRegisterSet;override;
|
||||
function create_paraloc_info(p : TAbstractProcDef; side: tcallercallee):longint;override;
|
||||
function create_varargs_paraloc_info(p : TAbstractProcDef; varargspara:tvarargsparalist):longint;override;
|
||||
function create_varargs_paraloc_info(p : TAbstractProcDef; side: tcallercallee; varargspara:tvarargsparalist):longint;override;
|
||||
procedure create_paraloc_info_intern(p : tabstractprocdef; side: tcallercallee; paras: tparalist;
|
||||
var curintreg: longint; curfloatreg: tsuperregister; var cur_stack_offset: aword);virtual;abstract;
|
||||
end;
|
||||
@ -66,7 +66,7 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
function tsparcparamanager.create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargsparalist):longint;
|
||||
function tsparcparamanager.create_varargs_paraloc_info(p : tabstractprocdef; side: tcallercallee; varargspara:tvarargsparalist):longint;
|
||||
var
|
||||
curintreg : LongInt;
|
||||
curfloatreg : TSuperRegister;
|
||||
@ -76,9 +76,15 @@ implementation
|
||||
curfloatreg:=RS_F0;
|
||||
cur_stack_offset:=0;
|
||||
{ calculate the registers for the normal parameters }
|
||||
create_paraloc_info_intern(p,callerside,p.paras,curintreg,curfloatreg,cur_stack_offset);
|
||||
create_paraloc_info_intern(p,side,p.paras,curintreg,curfloatreg,cur_stack_offset);
|
||||
{ append the varargs }
|
||||
create_paraloc_info_intern(p,callerside,varargspara,curintreg,curfloatreg,cur_stack_offset);
|
||||
if assigned(varargspara) then
|
||||
begin
|
||||
if side=callerside then
|
||||
create_paraloc_info_intern(p,callerside,varargspara,curintreg,curfloatreg,cur_stack_offset)
|
||||
else
|
||||
internalerror(2019021927);
|
||||
end;
|
||||
result:=cur_stack_offset;
|
||||
end;
|
||||
|
||||
|
@ -415,7 +415,10 @@ type
|
||||
{ procedure is an automatically generated property setter }
|
||||
po_is_auto_setter,
|
||||
{ must never be inlined by auto-inlining }
|
||||
po_noinline
|
||||
po_noinline,
|
||||
{ same as po_varargs, but with an array-of-const parameter instead of with the
|
||||
"varargs" modifier or Mac-Pascal ".." parameter }
|
||||
po_variadic
|
||||
);
|
||||
tprocoptions=set of tprocoption;
|
||||
|
||||
@ -1027,7 +1030,8 @@ inherited_objectoptions : tobjectoptions = [oo_has_virtual,oo_has_private,oo_has
|
||||
'C-style blocks',{po_is_block}
|
||||
'po_is_auto_getter',{po_is_auto_getter}
|
||||
'po_is_auto_setter',{po_is_auto_setter}
|
||||
'po_noinline'{po_noinline}
|
||||
'po_noinline',{po_noinline}
|
||||
'C-style array-of-const' {po_variadic}
|
||||
);
|
||||
|
||||
implementation
|
||||
|
@ -5284,7 +5284,10 @@ implementation
|
||||
if (side in [callerside,callbothsides]) and
|
||||
not(has_paraloc_info in [callerside,callbothsides]) then
|
||||
begin
|
||||
callerargareasize:=paramanager.create_paraloc_info(self,callerside);
|
||||
if not is_c_variadic(self) then
|
||||
callerargareasize:=paramanager.create_paraloc_info(self,callerside)
|
||||
else
|
||||
callerargareasize:=paramanager.create_varargs_paraloc_info(self,callerside,nil);
|
||||
if has_paraloc_info in [calleeside,callbothsides] then
|
||||
has_paraloc_info:=callbothsides
|
||||
else
|
||||
@ -5293,7 +5296,10 @@ implementation
|
||||
if (side in [calleeside,callbothsides]) and
|
||||
not(has_paraloc_info in [calleeside,callbothsides]) then
|
||||
begin
|
||||
calleeargareasize:=paramanager.create_paraloc_info(self,calleeside);
|
||||
if not is_c_variadic(self) then
|
||||
calleeargareasize:=paramanager.create_paraloc_info(self,calleeside)
|
||||
else
|
||||
callerargareasize:=paramanager.create_varargs_paraloc_info(self,calleeside,nil);
|
||||
if has_paraloc_info in [callerside,callbothsides] then
|
||||
has_paraloc_info:=callbothsides
|
||||
else
|
||||
|
@ -2016,7 +2016,8 @@ const
|
||||
(mask:po_is_block; str: 'C "Block"'),
|
||||
(mask:po_is_auto_getter; str: 'Automatically generated getter'),
|
||||
(mask:po_is_auto_setter; str: 'Automatically generated setter'),
|
||||
(mask:po_noinline; str: 'Never inline')
|
||||
(mask:po_noinline; str: 'Never inline'),
|
||||
(mask:po_variadic; str: 'C VarArgs with array-of-const para')
|
||||
);
|
||||
var
|
||||
proctypeoption : tproctypeoption;
|
||||
|
@ -46,7 +46,7 @@ unit cpupara;
|
||||
function get_saved_registers_int(calloption : tproccalloption):tcpuregisterarray;override;
|
||||
function get_saved_registers_mm(calloption: tproccalloption):tcpuregisterarray;override;
|
||||
function create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;override;
|
||||
function create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargsparalist):longint;override;
|
||||
function create_varargs_paraloc_info(p : tabstractprocdef; side: tcallercallee; varargspara:tvarargsparalist):longint;override;
|
||||
function get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara;override;
|
||||
end;
|
||||
|
||||
@ -1946,7 +1946,7 @@ unit cpupara;
|
||||
end;
|
||||
|
||||
|
||||
function tcpuparamanager.create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargsparalist):longint;
|
||||
function tcpuparamanager.create_varargs_paraloc_info(p : tabstractprocdef; side: tcallercallee; varargspara:tvarargsparalist):longint;
|
||||
var
|
||||
intparareg,mmparareg,
|
||||
parasize : longint;
|
||||
@ -1958,11 +1958,18 @@ unit cpupara;
|
||||
else
|
||||
parasize:=0;
|
||||
{ calculate the registers for the normal parameters }
|
||||
create_paraloc_info_intern(p,callerside,p.paras,intparareg,mmparareg,parasize,false);
|
||||
create_paraloc_info_intern(p,side,p.paras,intparareg,mmparareg,parasize,false);
|
||||
{ append the varargs }
|
||||
create_paraloc_info_intern(p,callerside,varargspara,intparareg,mmparareg,parasize,true);
|
||||
{ store used no. of SSE registers, that needs to be passed in %AL }
|
||||
varargspara.mmregsused:=mmparareg;
|
||||
if assigned(varargspara) then
|
||||
begin
|
||||
if side=callerside then
|
||||
create_paraloc_info_intern(p,side,varargspara,intparareg,mmparareg,parasize,true)
|
||||
else
|
||||
internalerror(2019021917);
|
||||
{ store used no. of SSE registers, that needs to be passed in %AL }
|
||||
varargspara.mmregsused:=mmparareg;
|
||||
end;
|
||||
create_funcretloc_info(p,side);
|
||||
result:=parasize;
|
||||
end;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user