mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-10-28 08:41:35 +01: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 push_addr_param(varspez: tvarspez; def: tdef; calloption: tproccalloption): boolean; override;
|
||||||
function ret_in_param(def: tdef; pd: tabstractprocdef):boolean;override;
|
function ret_in_param(def: tdef; pd: tabstractprocdef):boolean;override;
|
||||||
function create_paraloc_info(p: tabstractprocdef; side: tcallercallee):longint;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 get_funcretloc(p: tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara;override;
|
||||||
function param_use_paraloc(const cgpara: tcgpara): boolean; override;
|
function param_use_paraloc(const cgpara: tcgpara): boolean; override;
|
||||||
private
|
private
|
||||||
@ -639,12 +639,12 @@ unit cpupara;
|
|||||||
end;
|
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
|
begin
|
||||||
init_para_alloc_values;
|
init_para_alloc_values;
|
||||||
|
|
||||||
{ non-variadic parameters }
|
{ 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
|
if p.proccalloption in cstylearrayofconst then
|
||||||
begin
|
begin
|
||||||
{ on Darwin, we cannot use any registers for variadic parameters }
|
{ on Darwin, we cannot use any registers for variadic parameters }
|
||||||
@ -654,11 +654,19 @@ unit cpupara;
|
|||||||
curmmreg:=succ(RS_LAST_MM_PARAM_SUPREG);
|
curmmreg:=succ(RS_LAST_MM_PARAM_SUPREG);
|
||||||
end;
|
end;
|
||||||
{ continue loading the parameters }
|
{ 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;
|
result:=curstackoffset;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
internalerror(200410231);
|
internalerror(200410231);
|
||||||
|
|
||||||
|
create_funcretloc_info(p,side);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
|||||||
@ -42,7 +42,7 @@ unit cpupara;
|
|||||||
function ret_in_param(def:tdef;pd:tabstractprocdef):boolean;override;
|
function ret_in_param(def:tdef;pd:tabstractprocdef):boolean;override;
|
||||||
procedure getintparaloc(list: TAsmList; pd : tabstractprocdef; nr : longint; var cgpara : tcgpara);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_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 get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara;override;
|
||||||
private
|
private
|
||||||
procedure init_values(p: tabstractprocdef; side: tcallercallee; var curintreg,
|
procedure init_values(p: tabstractprocdef; side: tcallercallee; var curintreg,
|
||||||
@ -778,20 +778,30 @@ unit cpupara;
|
|||||||
end;
|
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
|
var
|
||||||
cur_stack_offset: aword;
|
cur_stack_offset: aword;
|
||||||
curintreg, curfloatreg, curmmreg: tsuperregister;
|
curintreg, curfloatreg, curmmreg: tsuperregister;
|
||||||
sparesinglereg:tregister;
|
sparesinglereg:tregister;
|
||||||
begin
|
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
|
if (p.proccalloption in cstylearrayofconst) then
|
||||||
|
begin
|
||||||
{ just continue loading the parameters in the registers }
|
{ just continue loading the parameters in the registers }
|
||||||
result:=create_paraloc_info_intern(p,callerside,varargspara,curintreg,curfloatreg,curmmreg,cur_stack_offset,sparesinglereg,true)
|
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
|
else
|
||||||
internalerror(200410231);
|
internalerror(200410231);
|
||||||
|
|
||||||
|
create_funcretloc_info(p,side);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
|||||||
@ -39,7 +39,7 @@ unit cpupara;
|
|||||||
function push_addr_param(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean;override;
|
function push_addr_param(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean;override;
|
||||||
function ret_in_param(def:tdef;pd:tabstractprocdef):boolean;override;
|
function ret_in_param(def:tdef;pd:tabstractprocdef):boolean;override;
|
||||||
function create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;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 get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara;override;
|
||||||
private
|
private
|
||||||
procedure init_values(var curintreg, curfloatreg, curmmreg: tsuperregister; var cur_stack_offset: aword);
|
procedure init_values(var curintreg, curfloatreg, curmmreg: tsuperregister; var cur_stack_offset: aword);
|
||||||
@ -526,17 +526,25 @@ unit cpupara;
|
|||||||
end;
|
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
|
var
|
||||||
cur_stack_offset: aword;
|
cur_stack_offset: aword;
|
||||||
curintreg, curfloatreg, curmmreg: tsuperregister;
|
curintreg, curfloatreg, curmmreg: tsuperregister;
|
||||||
begin
|
begin
|
||||||
init_values(curintreg,curfloatreg,curmmreg,cur_stack_offset);
|
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
|
if (p.proccalloption in cstylearrayofconst) then
|
||||||
|
begin
|
||||||
{ just continue loading the parameters in the registers }
|
{ just continue loading the parameters in the registers }
|
||||||
result:=create_paraloc_info_intern(p,callerside,varargspara,curintreg,curfloatreg,curmmreg,cur_stack_offset)
|
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
|
else
|
||||||
internalerror(200410231);
|
internalerror(200410231);
|
||||||
end;
|
end;
|
||||||
|
|||||||
@ -325,6 +325,9 @@ interface
|
|||||||
{ # returns true if the procdef has no parameters and no specified return type }
|
{ # returns true if the procdef has no parameters and no specified return type }
|
||||||
function is_bareprocdef(pd : tprocdef): boolean;
|
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
|
{ # 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
|
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 }
|
signdness, the result will also get that signdness }
|
||||||
@ -1496,6 +1499,12 @@ implementation
|
|||||||
(pd.proctypeoption = potype_constructor));
|
(pd.proctypeoption = potype_constructor));
|
||||||
end;
|
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;
|
function get_common_intdef(ld, rd: torddef; keep_sign_if_equal: boolean): torddef;
|
||||||
var
|
var
|
||||||
|
|||||||
@ -42,7 +42,7 @@ unit cpupara;
|
|||||||
function get_volatile_registers_mm(calloption : tproccalloption):tcpuregisterset;override;
|
function get_volatile_registers_mm(calloption : tproccalloption):tcpuregisterset;override;
|
||||||
function get_saved_registers_int(calloption : tproccalloption):tcpuregisterarray;override;
|
function get_saved_registers_int(calloption : tproccalloption):tcpuregisterarray;override;
|
||||||
function create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;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;
|
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;
|
function get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): TCGPara;override;
|
||||||
private
|
private
|
||||||
@ -767,15 +767,22 @@ unit cpupara;
|
|||||||
end;
|
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
|
var
|
||||||
parasize : longint;
|
parasize : longint;
|
||||||
begin
|
begin
|
||||||
parasize:=0;
|
parasize:=0;
|
||||||
{ calculate the registers for the normal parameters }
|
{ 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 }
|
{ 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;
|
result:=parasize;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|||||||
@ -55,7 +55,7 @@ unit cpupara;
|
|||||||
}
|
}
|
||||||
procedure getintparaloc(list: TAsmList; pd : tabstractprocdef; nr : longint; var cgpara : tcgpara);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_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;
|
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;
|
function get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): TCGPara;override;
|
||||||
private
|
private
|
||||||
@ -783,15 +783,22 @@ unit cpupara;
|
|||||||
end;
|
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
|
var
|
||||||
parasize : longint;
|
parasize : longint;
|
||||||
begin
|
begin
|
||||||
parasize:=0;
|
parasize:=0;
|
||||||
{ calculate the registers for the normal parameters }
|
{ 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 }
|
{ 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;
|
result:=parasize;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|||||||
@ -46,7 +46,7 @@ interface
|
|||||||
@param(nr Parameter number of routine, starting from 1)}
|
@param(nr Parameter number of routine, starting from 1)}
|
||||||
procedure getintparaloc(list: TAsmList; pd : tabstractprocdef; nr : longint; var cgpara : tcgpara);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_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 get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara;override;
|
||||||
function param_use_paraloc(const cgpara: tcgpara): boolean; override;
|
function param_use_paraloc(const cgpara: tcgpara): boolean; override;
|
||||||
function ret_in_param(def:tdef;pd:tabstractprocdef):boolean;override;
|
function ret_in_param(def:tdef;pd:tabstractprocdef):boolean;override;
|
||||||
@ -209,15 +209,22 @@ implementation
|
|||||||
end;
|
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
|
var
|
||||||
parasize : longint;
|
parasize : longint;
|
||||||
begin
|
begin
|
||||||
parasize:=0;
|
parasize:=0;
|
||||||
{ calculate the registers for the normal parameters }
|
{ 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 }
|
{ 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;
|
result:=parasize;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|||||||
@ -45,7 +45,7 @@ unit cpupara;
|
|||||||
function push_addr_param(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean;override;
|
function push_addr_param(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean;override;
|
||||||
function get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara;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;
|
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 parsefuncretloc(p : tabstractprocdef; const s : string) : boolean;override;
|
||||||
function get_volatile_registers_int(calloption:tproccalloption):tcpuregisterset;override;
|
function get_volatile_registers_int(calloption:tproccalloption):tcpuregisterset;override;
|
||||||
function get_volatile_registers_address(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);
|
inherited createtempparaloc(list,calloption,parasym,can_use_final_stack_loc,cgpara);
|
||||||
end;
|
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
|
var
|
||||||
cur_stack_offset: aword;
|
cur_stack_offset: aword;
|
||||||
begin
|
begin
|
||||||
cur_stack_offset:=0;
|
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
|
if (p.proccalloption in cstylearrayofconst) then
|
||||||
|
begin
|
||||||
{ just continue loading the parameters in the registers }
|
{ just continue loading the parameters in the registers }
|
||||||
result:=create_stdcall_paraloc_info(p,callerside,varargspara,cur_stack_offset)
|
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
|
else
|
||||||
internalerror(200410231);
|
internalerror(200410231);
|
||||||
|
create_funcretloc_info(p,side);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -73,7 +73,7 @@ interface
|
|||||||
function get_volatile_registers_fpu(calloption : tproccalloption):TCpuRegisterSet;override;
|
function get_volatile_registers_fpu(calloption : tproccalloption):TCpuRegisterSet;override;
|
||||||
function get_saved_registers_int(calloption : tproccalloption):TCpuRegisterArray;override;
|
function get_saved_registers_int(calloption : tproccalloption):TCpuRegisterArray;override;
|
||||||
function create_paraloc_info(p : TAbstractProcDef; side: tcallercallee):longint;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 get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara;override;
|
||||||
function param_use_paraloc(const cgpara: tcgpara): boolean; override;
|
function param_use_paraloc(const cgpara: tcgpara): boolean; override;
|
||||||
private
|
private
|
||||||
@ -490,7 +490,7 @@ implementation
|
|||||||
end;
|
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
|
begin
|
||||||
intparareg:=0;
|
intparareg:=0;
|
||||||
intparasize:=0;
|
intparasize:=0;
|
||||||
@ -498,13 +498,20 @@ implementation
|
|||||||
{ Create Function result paraloc }
|
{ Create Function result paraloc }
|
||||||
create_funcretloc_info(p,callerside);
|
create_funcretloc_info(p,callerside);
|
||||||
{ calculate the registers for the normal parameters }
|
{ 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 }
|
{ append the varargs }
|
||||||
can_use_float := false;
|
can_use_float := false;
|
||||||
{ restore correct intparasize value }
|
{ restore correct intparasize value }
|
||||||
if intparareg < 4 then
|
if intparareg < 4 then
|
||||||
intparasize:=intparareg * 4;
|
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 }
|
{ We need to return the size allocated on the stack }
|
||||||
result:=intparasize;
|
result:=intparasize;
|
||||||
end;
|
end;
|
||||||
|
|||||||
@ -4416,7 +4416,7 @@ implementation
|
|||||||
|
|
||||||
{ calculate the parameter size needed for this call include varargs if they are available }
|
{ calculate the parameter size needed for this call include varargs if they are available }
|
||||||
if assigned(varargsparas) then
|
if assigned(varargsparas) then
|
||||||
pushedparasize:=paramanager.create_varargs_paraloc_info(procdefinition,varargsparas)
|
pushedparasize:=paramanager.create_varargs_paraloc_info(procdefinition,callerside,varargsparas)
|
||||||
else
|
else
|
||||||
pushedparasize:=procdefinition.callerargareasize;
|
pushedparasize:=procdefinition.callerargareasize;
|
||||||
|
|
||||||
|
|||||||
@ -140,7 +140,7 @@ unit paramgr;
|
|||||||
for the routine that are passed as varargs. It returns
|
for the routine that are passed as varargs. It returns
|
||||||
the size allocated on the stack (including the normal parameters)
|
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;
|
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;
|
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);
|
internalerror(2015052202);
|
||||||
end;
|
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 }
|
{ file types can't be function results }
|
||||||
if assigned(pd) and
|
if assigned(pd) and
|
||||||
(pd.returndef.typ=filedef) then
|
(pd.returndef.typ=filedef) then
|
||||||
|
|||||||
@ -40,7 +40,7 @@ unit cpupara;
|
|||||||
|
|
||||||
procedure getintparaloc(list: TAsmList; pd : tabstractprocdef; nr : longint; var cgpara : tcgpara);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_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 get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara;override;
|
||||||
private
|
private
|
||||||
procedure init_values(var curintreg, curfloatreg, curmmreg: tsuperregister; var cur_stack_offset: aword);
|
procedure init_values(var curintreg, curfloatreg, curmmreg: tsuperregister; var cur_stack_offset: aword);
|
||||||
@ -628,7 +628,7 @@ unit cpupara;
|
|||||||
end;
|
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
|
var
|
||||||
cur_stack_offset: aword;
|
cur_stack_offset: aword;
|
||||||
parasize, l: longint;
|
parasize, l: longint;
|
||||||
@ -640,36 +640,27 @@ unit cpupara;
|
|||||||
init_values(curintreg,curfloatreg,curmmreg,cur_stack_offset);
|
init_values(curintreg,curfloatreg,curmmreg,cur_stack_offset);
|
||||||
firstfloatreg:=curfloatreg;
|
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
|
if (p.proccalloption in cstylearrayofconst) then
|
||||||
{ just continue loading the parameters in the registers }
|
{ just continue loading the parameters in the registers }
|
||||||
begin
|
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 }
|
{ 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
|
if (target_info.abi in [abi_powerpc_aix,abi_powerpc_darwin]) and
|
||||||
(result < 32) then
|
(result < 32) then
|
||||||
result := 32;
|
result := 32;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
internalerror(2019021710);
|
||||||
parasize:=cur_stack_offset;
|
create_funcretloc_info(p,side);
|
||||||
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);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -45,8 +45,7 @@ type
|
|||||||
|
|
||||||
procedure getintparaloc(list: TAsmList; pd : tabstractprocdef; nr: longint; var cgpara: tcgpara); 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_paraloc_info(p: tabstractprocdef; side: tcallercallee): longint; override;
|
||||||
function create_varargs_paraloc_info(p: tabstractprocdef; varargspara:
|
function create_varargs_paraloc_info(p: tabstractprocdef; side: tcallercallee; varargspara: tvarargsparalist): longint; override;
|
||||||
tvarargsparalist): longint; override;
|
|
||||||
function get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara;override;
|
function get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara;override;
|
||||||
|
|
||||||
private
|
private
|
||||||
@ -743,7 +742,7 @@ implemented
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function tcpuparamanager.create_varargs_paraloc_info(p: tabstractprocdef;
|
function tcpuparamanager.create_varargs_paraloc_info(p: tabstractprocdef; side: tcallercallee;
|
||||||
varargspara: tvarargsparalist): longint;
|
varargspara: tvarargsparalist): longint;
|
||||||
var
|
var
|
||||||
cur_stack_offset: aword;
|
cur_stack_offset: aword;
|
||||||
@ -756,33 +755,28 @@ begin
|
|||||||
init_values(curintreg, curfloatreg, curmmreg, cur_stack_offset);
|
init_values(curintreg, curfloatreg, curmmreg, cur_stack_offset);
|
||||||
firstfloatreg := curfloatreg;
|
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);
|
curfloatreg, curmmreg, cur_stack_offset, false);
|
||||||
if (p.proccalloption in cstylearrayofconst) then begin
|
if (p.proccalloption in cstylearrayofconst) then
|
||||||
|
begin
|
||||||
{ just continue loading the parameters in the registers }
|
{ just continue loading the parameters in the registers }
|
||||||
result := create_paraloc_info_intern(p, callerside, varargspara, curintreg,
|
if assigned(varargspara) then
|
||||||
curfloatreg, curmmreg, cur_stack_offset, true);
|
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 }
|
{ varargs routines have to reserve at least 64 bytes for the PPC64 ABI }
|
||||||
if (result < 64) then
|
if (result < 64) then
|
||||||
result := 64;
|
result := 64;
|
||||||
end else begin
|
end
|
||||||
parasize := cur_stack_offset;
|
else
|
||||||
for i := 0 to varargspara.count - 1 do begin
|
internalerror(2019021911);
|
||||||
hp := tparavarsym(varargspara[i]);
|
create_funcretloc_info(p, side);
|
||||||
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);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function tcpuparamanager.parseparaloc(p: tparavarsym; const s: string): boolean;
|
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;
|
procedure getintparaloc(list: TAsmList; pd : tabstractprocdef; nr : longint; var cgpara : tcgpara);override;
|
||||||
function create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;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 get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara;override;
|
||||||
private
|
private
|
||||||
procedure init_values(var curintreg, curfloatreg, curmmreg: tsuperregister; var cur_stack_offset: aword);
|
procedure init_values(var curintreg, curfloatreg, curmmreg: tsuperregister; var cur_stack_offset: aword);
|
||||||
@ -505,7 +505,7 @@ unit cpupara;
|
|||||||
end;
|
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
|
var
|
||||||
cur_stack_offset: aword;
|
cur_stack_offset: aword;
|
||||||
parasize, l: longint;
|
parasize, l: longint;
|
||||||
@ -517,33 +517,24 @@ unit cpupara;
|
|||||||
init_values(curintreg,curfloatreg,curmmreg,cur_stack_offset);
|
init_values(curintreg,curfloatreg,curmmreg,cur_stack_offset);
|
||||||
firstfloatreg:=curfloatreg;
|
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
|
if (p.proccalloption in cstylearrayofconst) then
|
||||||
{ just continue loading the parameters in the registers }
|
{ just continue loading the parameters in the registers }
|
||||||
begin
|
begin
|
||||||
result:=create_paraloc_info_intern(p,callerside,varargspara,curintreg,curfloatreg,curmmreg,cur_stack_offset,true);
|
if assigned(varargspara) then
|
||||||
end
|
begin
|
||||||
|
if side=callerside then
|
||||||
|
result:=create_paraloc_info_intern(p,side,varargspara,curintreg,curfloatreg,curmmreg,cur_stack_offset,true)
|
||||||
else
|
else
|
||||||
begin
|
internalerror(2019021919);
|
||||||
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
|
if curfloatreg<>firstfloatreg then
|
||||||
include(varargspara.varargsinfo,va_uses_float_reg);
|
include(varargspara.varargsinfo,va_uses_float_reg);
|
||||||
end;
|
end;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
internalerror(2019021912);
|
||||||
|
create_funcretloc_info(p,side);
|
||||||
|
end;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
paramanager:=tcpuparamanager.create;
|
paramanager:=tcpuparamanager.create;
|
||||||
|
|||||||
@ -40,7 +40,7 @@ unit cpupara;
|
|||||||
|
|
||||||
procedure getintparaloc(list: TAsmList; pd : tabstractprocdef; nr: longint; var cgpara: tcgpara); 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_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 get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara;override;
|
||||||
|
|
||||||
private
|
private
|
||||||
@ -490,7 +490,7 @@ implementation
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function tcpuparamanager.create_varargs_paraloc_info(p: tabstractprocdef;
|
function tcpuparamanager.create_varargs_paraloc_info(p: tabstractprocdef; side: tcallercallee;
|
||||||
varargspara: tvarargsparalist): longint;
|
varargspara: tvarargsparalist): longint;
|
||||||
var
|
var
|
||||||
cur_stack_offset: aword;
|
cur_stack_offset: aword;
|
||||||
@ -503,33 +503,29 @@ begin
|
|||||||
init_values(curintreg, curfloatreg, curmmreg, cur_stack_offset);
|
init_values(curintreg, curfloatreg, curmmreg, cur_stack_offset);
|
||||||
firstfloatreg := curfloatreg;
|
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);
|
curfloatreg, curmmreg, cur_stack_offset, false);
|
||||||
if (p.proccalloption in [pocall_cdecl, pocall_cppdecl, pocall_mwpascal]) then begin
|
if (p.proccalloption in [pocall_cdecl, pocall_cppdecl, pocall_mwpascal]) then
|
||||||
|
begin
|
||||||
{ just continue loading the parameters in the registers }
|
{ just continue loading the parameters in the registers }
|
||||||
result := create_paraloc_info_intern(p, callerside, varargspara, curintreg,
|
if assigned(varargspara) then
|
||||||
curfloatreg, curmmreg, cur_stack_offset, true);
|
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 }
|
{ varargs routines have to reserve at least 64 bytes for the RiscV ABI }
|
||||||
if (result < 64) then
|
if (result < 64) then
|
||||||
result := 64;
|
result := 64;
|
||||||
end else begin
|
end
|
||||||
parasize := cur_stack_offset;
|
else
|
||||||
for i := 0 to varargspara.count - 1 do begin
|
internalerror(2019021913);
|
||||||
hp := tparavarsym(varargspara[i]);
|
|
||||||
hp.paraloc[callerside].alignment := 8;
|
create_funcretloc_info(p, side);
|
||||||
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);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function tcpuparamanager.parseparaloc(p: tparavarsym; const s: string): boolean;
|
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_int(calloption : tproccalloption):TCpuRegisterSet;override;
|
||||||
function get_volatile_registers_fpu(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_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;
|
procedure create_paraloc_info_intern(p : tabstractprocdef; side: tcallercallee; paras: tparalist;
|
||||||
var curintreg: longint; curfloatreg: tsuperregister; var cur_stack_offset: aword);virtual;abstract;
|
var curintreg: longint; curfloatreg: tsuperregister; var cur_stack_offset: aword);virtual;abstract;
|
||||||
end;
|
end;
|
||||||
@ -66,7 +66,7 @@ implementation
|
|||||||
end;
|
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
|
var
|
||||||
curintreg : LongInt;
|
curintreg : LongInt;
|
||||||
curfloatreg : TSuperRegister;
|
curfloatreg : TSuperRegister;
|
||||||
@ -76,9 +76,15 @@ implementation
|
|||||||
curfloatreg:=RS_F0;
|
curfloatreg:=RS_F0;
|
||||||
cur_stack_offset:=0;
|
cur_stack_offset:=0;
|
||||||
{ calculate the registers for the normal parameters }
|
{ 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 }
|
{ 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;
|
result:=cur_stack_offset;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|||||||
@ -415,7 +415,10 @@ type
|
|||||||
{ procedure is an automatically generated property setter }
|
{ procedure is an automatically generated property setter }
|
||||||
po_is_auto_setter,
|
po_is_auto_setter,
|
||||||
{ must never be inlined by auto-inlining }
|
{ 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;
|
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}
|
'C-style blocks',{po_is_block}
|
||||||
'po_is_auto_getter',{po_is_auto_getter}
|
'po_is_auto_getter',{po_is_auto_getter}
|
||||||
'po_is_auto_setter',{po_is_auto_setter}
|
'po_is_auto_setter',{po_is_auto_setter}
|
||||||
'po_noinline'{po_noinline}
|
'po_noinline',{po_noinline}
|
||||||
|
'C-style array-of-const' {po_variadic}
|
||||||
);
|
);
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|||||||
@ -5284,7 +5284,10 @@ implementation
|
|||||||
if (side in [callerside,callbothsides]) and
|
if (side in [callerside,callbothsides]) and
|
||||||
not(has_paraloc_info in [callerside,callbothsides]) then
|
not(has_paraloc_info in [callerside,callbothsides]) then
|
||||||
begin
|
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
|
if has_paraloc_info in [calleeside,callbothsides] then
|
||||||
has_paraloc_info:=callbothsides
|
has_paraloc_info:=callbothsides
|
||||||
else
|
else
|
||||||
@ -5293,7 +5296,10 @@ implementation
|
|||||||
if (side in [calleeside,callbothsides]) and
|
if (side in [calleeside,callbothsides]) and
|
||||||
not(has_paraloc_info in [calleeside,callbothsides]) then
|
not(has_paraloc_info in [calleeside,callbothsides]) then
|
||||||
begin
|
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
|
if has_paraloc_info in [callerside,callbothsides] then
|
||||||
has_paraloc_info:=callbothsides
|
has_paraloc_info:=callbothsides
|
||||||
else
|
else
|
||||||
|
|||||||
@ -2016,7 +2016,8 @@ const
|
|||||||
(mask:po_is_block; str: 'C "Block"'),
|
(mask:po_is_block; str: 'C "Block"'),
|
||||||
(mask:po_is_auto_getter; str: 'Automatically generated getter'),
|
(mask:po_is_auto_getter; str: 'Automatically generated getter'),
|
||||||
(mask:po_is_auto_setter; str: 'Automatically generated setter'),
|
(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
|
var
|
||||||
proctypeoption : tproctypeoption;
|
proctypeoption : tproctypeoption;
|
||||||
|
|||||||
@ -46,7 +46,7 @@ unit cpupara;
|
|||||||
function get_saved_registers_int(calloption : tproccalloption):tcpuregisterarray;override;
|
function get_saved_registers_int(calloption : tproccalloption):tcpuregisterarray;override;
|
||||||
function get_saved_registers_mm(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_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 get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara;override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -1946,7 +1946,7 @@ unit cpupara;
|
|||||||
end;
|
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
|
var
|
||||||
intparareg,mmparareg,
|
intparareg,mmparareg,
|
||||||
parasize : longint;
|
parasize : longint;
|
||||||
@ -1958,11 +1958,18 @@ unit cpupara;
|
|||||||
else
|
else
|
||||||
parasize:=0;
|
parasize:=0;
|
||||||
{ calculate the registers for the normal parameters }
|
{ 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 }
|
{ append the varargs }
|
||||||
create_paraloc_info_intern(p,callerside,varargspara,intparareg,mmparareg,parasize,true);
|
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 }
|
{ store used no. of SSE registers, that needs to be passed in %AL }
|
||||||
varargspara.mmregsused:=mmparareg;
|
varargspara.mmregsused:=mmparareg;
|
||||||
|
end;
|
||||||
|
create_funcretloc_info(p,side);
|
||||||
result:=parasize;
|
result:=parasize;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user