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:
Károly Balogh 2016-12-03 19:00:41 +00:00
parent ba33da711a
commit 0cb555c07c
5 changed files with 30 additions and 69 deletions

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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;