mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-08 19:48:29 +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;
|
||||
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 parseparaloc(p : tparavarsym;const s : string) : boolean;override;
|
||||
private
|
||||
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);
|
||||
@ -287,32 +286,6 @@ unit cpupara;
|
||||
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;
|
||||
var
|
||||
retcgsize : tcgsize;
|
||||
|
@ -46,7 +46,6 @@ unit cpupara;
|
||||
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 parseparaloc(p : tparavarsym;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_address(calloption:tproccalloption):tcpuregisterset;override;
|
||||
@ -579,32 +578,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_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);
|
||||
begin
|
||||
|
@ -503,10 +503,24 @@ implementation
|
||||
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;
|
||||
var
|
||||
paraloc : pcgparalocation;
|
||||
begin
|
||||
Result:=False;
|
||||
internalerror(200807235);
|
||||
parasym.paraloc[callerside].alignment:=sizeof(pint);
|
||||
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;
|
||||
|
||||
|
||||
|
@ -528,7 +528,7 @@ implementation
|
||||
Message(parser_e_paraloc_all_paras);
|
||||
explicit_paraloc:=true;
|
||||
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);
|
||||
end
|
||||
else
|
||||
@ -2100,21 +2100,21 @@ procedure pd_syscall(pd:tabstractprocdef);
|
||||
function po_syscall_to_regname: string;
|
||||
begin
|
||||
if po_syscall_legacy in tprocdef(pd).procoptions then
|
||||
result:='A6'
|
||||
{ let no base on MorphOS store the libbase in r12 as well, because
|
||||
result:='a6'
|
||||
{ let nobase on MorphOS store the libbase in r12 as well, because
|
||||
we will need the libbase anyway during the call generation }
|
||||
else if (po_syscall_basenone in tprocdef(pd).procoptions) and
|
||||
(target_info.system = system_powerpc_morphos) then
|
||||
result:='R12'
|
||||
result:='r12'
|
||||
else if po_syscall_basereg in tprocdef(pd).procoptions then
|
||||
begin
|
||||
case target_info.system of
|
||||
system_i386_aros:
|
||||
result:='EAX';
|
||||
result:='eax';
|
||||
system_x86_64_aros:
|
||||
result:='RAX';
|
||||
result:='rax';
|
||||
system_powerpc_morphos:
|
||||
result:='R12';
|
||||
result:='r12';
|
||||
else
|
||||
internalerror(2016090201);
|
||||
end;
|
||||
@ -2154,7 +2154,7 @@ begin
|
||||
if ((v<0) or (v>high(smallint))) then
|
||||
message(parser_e_range_check_error)
|
||||
else
|
||||
tprocdef(pd).import_nr:=longint(v.svalue);
|
||||
tprocdef(pd).import_nr:=longint(v.svalue);
|
||||
|
||||
exit;
|
||||
end;
|
||||
@ -2171,7 +2171,8 @@ begin
|
||||
paranr:=syscall_paranr[po_syscall_basefirst in tprocdef(pd).procoptions];
|
||||
vs:=cparavarsym.create('$syscalllib',paranr,vs_value,tabstractvarsym(sym).vardef,vo);
|
||||
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);
|
||||
end
|
||||
else
|
||||
|
@ -687,9 +687,9 @@ unit cpupara;
|
||||
{ convert d0-d7/a0-a6 virtual 68k reg patterns into offsets }
|
||||
if length(s) = 2 then
|
||||
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)
|
||||
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);
|
||||
|
||||
if offset < 0 then
|
||||
@ -699,9 +699,9 @@ unit cpupara;
|
||||
paraloc^.reference.index:=newreg(R_INTREGISTER,RS_R2,R_SUBWHOLE);
|
||||
paraloc^.reference.offset:=offset;
|
||||
end
|
||||
{ 'R12' is special, used internally to support r12base and sysv
|
||||
{ 'R12' is special, used internally to support regbase and nobase
|
||||
calling convention }
|
||||
else if s='R12' then
|
||||
else if lowercase(s)='r12' then
|
||||
begin
|
||||
paraloc^.loc:=LOC_REGISTER;
|
||||
paraloc^.register:=NR_R12;
|
||||
|
Loading…
Reference in New Issue
Block a user