mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-10-25 21:05:20 +02:00
syscalls: move the reference implementation of parseparaloc to paramgr. removes two identical copies from CPU specific code and enables basereg convention for AROS/x86_64. also, other minor fixes and cleanups in related code.
git-svn-id: trunk@35047 -
This commit is contained in:
parent
ba33da711a
commit
0cb555c07c
@ -44,7 +44,6 @@ unit cpupara;
|
|||||||
function create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargsparalist):longint;override;
|
function create_varargs_paraloc_info(p : tabstractprocdef; 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;
|
||||||
function parseparaloc(p : tparavarsym;const s : string) : boolean;override;
|
|
||||||
private
|
private
|
||||||
procedure create_stdcall_paraloc_info(p : tabstractprocdef; side: tcallercallee;paras:tparalist;var parasize:longint);
|
procedure create_stdcall_paraloc_info(p : tabstractprocdef; side: tcallercallee;paras:tparalist;var parasize:longint);
|
||||||
procedure create_register_paraloc_info(p : tabstractprocdef; side: tcallercallee;paras:tparalist;var parareg,parasize:longint);
|
procedure create_register_paraloc_info(p : tabstractprocdef; side: tcallercallee;paras:tparalist;var parareg,parasize:longint);
|
||||||
@ -287,32 +286,6 @@ unit cpupara;
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
function tcpuparamanager.parseparaloc(p : tparavarsym;const s : string) : boolean;
|
|
||||||
var
|
|
||||||
paraloc : pcgparalocation;
|
|
||||||
begin
|
|
||||||
result:=false;
|
|
||||||
case target_info.system of
|
|
||||||
system_i386_aros:
|
|
||||||
begin
|
|
||||||
p.paraloc[callerside].alignment:=4;
|
|
||||||
paraloc:=p.paraloc[callerside].add_location;
|
|
||||||
paraloc^.loc:=LOC_REGISTER;
|
|
||||||
paraloc^.size:=def_cgsize(p.vardef);
|
|
||||||
paraloc^.def:=p.vardef;
|
|
||||||
paraloc^.register:=std_regnum_search(lowercase(s));
|
|
||||||
if paraloc^.register = NR_NO then
|
|
||||||
exit;
|
|
||||||
|
|
||||||
{ copy to callee side }
|
|
||||||
p.paraloc[calleeside].add_location^:=paraloc^;
|
|
||||||
end;
|
|
||||||
else
|
|
||||||
internalerror(2016090103);
|
|
||||||
end;
|
|
||||||
result:=true;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function tcpuparamanager.get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): TCGPara;
|
function tcpuparamanager.get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): TCGPara;
|
||||||
var
|
var
|
||||||
retcgsize : tcgsize;
|
retcgsize : tcgsize;
|
||||||
|
|||||||
@ -46,7 +46,6 @@ unit cpupara;
|
|||||||
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; varargspara:tvarargsparalist):longint;override;
|
||||||
function parseparaloc(p : tparavarsym;const s : string) : boolean;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;
|
||||||
@ -579,32 +578,6 @@ unit cpupara;
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function tcpuparamanager.parseparaloc(p : tparavarsym;const s : string) : boolean;
|
|
||||||
var
|
|
||||||
paraloc : pcgparalocation;
|
|
||||||
begin
|
|
||||||
result:=false;
|
|
||||||
case target_info.system of
|
|
||||||
system_m68k_amiga:
|
|
||||||
begin
|
|
||||||
p.paraloc[callerside].alignment:=4;
|
|
||||||
paraloc:=p.paraloc[callerside].add_location;
|
|
||||||
paraloc^.loc:=LOC_REGISTER;
|
|
||||||
paraloc^.size:=def_cgsize(p.vardef);
|
|
||||||
paraloc^.def:=p.vardef;
|
|
||||||
|
|
||||||
if not parse_loc_string_to_register(paraloc^.register, s) then
|
|
||||||
exit;
|
|
||||||
|
|
||||||
{ copy to callee side }
|
|
||||||
p.paraloc[calleeside].add_location^:=paraloc^;
|
|
||||||
end;
|
|
||||||
else
|
|
||||||
internalerror(200405092);
|
|
||||||
end;
|
|
||||||
result:=true;
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
procedure tcpuparamanager.createtempparaloc(list: TAsmList;calloption : tproccalloption;parasym : tparavarsym;can_use_final_stack_loc : boolean;var cgpara:TCGPara);
|
procedure tcpuparamanager.createtempparaloc(list: TAsmList;calloption : tproccalloption;parasym : tparavarsym;can_use_final_stack_loc : boolean;var cgpara:TCGPara);
|
||||||
begin
|
begin
|
||||||
|
|||||||
@ -503,10 +503,24 @@ implementation
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
{ used by syscall conventions which require explicit paralocation support }
|
||||||
|
{ this is the standard implementation, CGs might overwrite it }
|
||||||
function tparamanager.parseparaloc(parasym: tparavarsym; const s: string): boolean;
|
function tparamanager.parseparaloc(parasym: tparavarsym; const s: string): boolean;
|
||||||
|
var
|
||||||
|
paraloc : pcgparalocation;
|
||||||
begin
|
begin
|
||||||
Result:=False;
|
parasym.paraloc[callerside].alignment:=sizeof(pint);
|
||||||
internalerror(200807235);
|
paraloc:=parasym.paraloc[callerside].add_location;
|
||||||
|
paraloc^.loc:=LOC_REGISTER;
|
||||||
|
paraloc^.size:=def_cgsize(parasym.vardef);
|
||||||
|
paraloc^.def:=parasym.vardef;
|
||||||
|
paraloc^.register:=std_regnum_search(lowercase(s));
|
||||||
|
|
||||||
|
{ copy to callee side }
|
||||||
|
parasym.paraloc[calleeside].add_location^:=paraloc^;
|
||||||
|
|
||||||
|
result:=(paraloc^.register <> NR_NO) and
|
||||||
|
(paraloc^.register <> NR_STACK_POINTER_REG);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -528,7 +528,7 @@ implementation
|
|||||||
Message(parser_e_paraloc_all_paras);
|
Message(parser_e_paraloc_all_paras);
|
||||||
explicit_paraloc:=true;
|
explicit_paraloc:=true;
|
||||||
include(vs.varoptions,vo_has_explicit_paraloc);
|
include(vs.varoptions,vo_has_explicit_paraloc);
|
||||||
if not(paramanager.parseparaloc(vs,upper(locationstr))) then
|
if not(paramanager.parseparaloc(vs,locationstr)) then
|
||||||
message(parser_e_illegal_explicit_paraloc);
|
message(parser_e_illegal_explicit_paraloc);
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
@ -2100,21 +2100,21 @@ procedure pd_syscall(pd:tabstractprocdef);
|
|||||||
function po_syscall_to_regname: string;
|
function po_syscall_to_regname: string;
|
||||||
begin
|
begin
|
||||||
if po_syscall_legacy in tprocdef(pd).procoptions then
|
if po_syscall_legacy in tprocdef(pd).procoptions then
|
||||||
result:='A6'
|
result:='a6'
|
||||||
{ let nobase on MorphOS store the libbase in r12 as well, because
|
{ let nobase on MorphOS store the libbase in r12 as well, because
|
||||||
we will need the libbase anyway during the call generation }
|
we will need the libbase anyway during the call generation }
|
||||||
else if (po_syscall_basenone in tprocdef(pd).procoptions) and
|
else if (po_syscall_basenone in tprocdef(pd).procoptions) and
|
||||||
(target_info.system = system_powerpc_morphos) then
|
(target_info.system = system_powerpc_morphos) then
|
||||||
result:='R12'
|
result:='r12'
|
||||||
else if po_syscall_basereg in tprocdef(pd).procoptions then
|
else if po_syscall_basereg in tprocdef(pd).procoptions then
|
||||||
begin
|
begin
|
||||||
case target_info.system of
|
case target_info.system of
|
||||||
system_i386_aros:
|
system_i386_aros:
|
||||||
result:='EAX';
|
result:='eax';
|
||||||
system_x86_64_aros:
|
system_x86_64_aros:
|
||||||
result:='RAX';
|
result:='rax';
|
||||||
system_powerpc_morphos:
|
system_powerpc_morphos:
|
||||||
result:='R12';
|
result:='r12';
|
||||||
else
|
else
|
||||||
internalerror(2016090201);
|
internalerror(2016090201);
|
||||||
end;
|
end;
|
||||||
@ -2171,7 +2171,8 @@ begin
|
|||||||
paranr:=syscall_paranr[po_syscall_basefirst in tprocdef(pd).procoptions];
|
paranr:=syscall_paranr[po_syscall_basefirst in tprocdef(pd).procoptions];
|
||||||
vs:=cparavarsym.create('$syscalllib',paranr,vs_value,tabstractvarsym(sym).vardef,vo);
|
vs:=cparavarsym.create('$syscalllib',paranr,vs_value,tabstractvarsym(sym).vardef,vo);
|
||||||
if vo_has_explicit_paraloc in vo then
|
if vo_has_explicit_paraloc in vo then
|
||||||
paramanager.parseparaloc(vs,po_syscall_to_regname);
|
if not paramanager.parseparaloc(vs,po_syscall_to_regname) then
|
||||||
|
internalerror(2016120301);
|
||||||
pd.parast.insert(vs);
|
pd.parast.insert(vs);
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
|
|||||||
@ -687,9 +687,9 @@ unit cpupara;
|
|||||||
{ convert d0-d7/a0-a6 virtual 68k reg patterns into offsets }
|
{ convert d0-d7/a0-a6 virtual 68k reg patterns into offsets }
|
||||||
if length(s) = 2 then
|
if length(s) = 2 then
|
||||||
begin
|
begin
|
||||||
if (s[1] = 'D') and (s[2] in ['0'..'7']) then
|
if (lowercase(s[1]) = 'd') and (s[2] in ['0'..'7']) then
|
||||||
offset:=(ord(s[2]) - ord('0')) * sizeof(pint)
|
offset:=(ord(s[2]) - ord('0')) * sizeof(pint)
|
||||||
else if (s[1] = 'A') and (s[2] in ['0'..'6']) then
|
else if (lowercase(s[1]) = 'a') and (s[2] in ['0'..'6']) then
|
||||||
offset:=(ord(s[2]) - ord('0') + 8) * sizeof(pint);
|
offset:=(ord(s[2]) - ord('0') + 8) * sizeof(pint);
|
||||||
|
|
||||||
if offset < 0 then
|
if offset < 0 then
|
||||||
@ -699,9 +699,9 @@ unit cpupara;
|
|||||||
paraloc^.reference.index:=newreg(R_INTREGISTER,RS_R2,R_SUBWHOLE);
|
paraloc^.reference.index:=newreg(R_INTREGISTER,RS_R2,R_SUBWHOLE);
|
||||||
paraloc^.reference.offset:=offset;
|
paraloc^.reference.offset:=offset;
|
||||||
end
|
end
|
||||||
{ 'R12' is special, used internally to support r12base and sysv
|
{ 'R12' is special, used internally to support regbase and nobase
|
||||||
calling convention }
|
calling convention }
|
||||||
else if s='R12' then
|
else if lowercase(s)='r12' then
|
||||||
begin
|
begin
|
||||||
paraloc^.loc:=LOC_REGISTER;
|
paraloc^.loc:=LOC_REGISTER;
|
||||||
paraloc^.register:=NR_R12;
|
paraloc^.register:=NR_R12;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user