syscalls: unify call reference creation across 4 different CPU archs. less copypasted code, brings x86_64 AROS support up to speed

git-svn-id: trunk@35034 -
This commit is contained in:
Károly Balogh 2016-12-02 09:29:09 +00:00
parent c2af5a104e
commit f5f895e2a3
5 changed files with 58 additions and 76 deletions

View File

@ -54,36 +54,16 @@ implementation
procedure tarmcallnode.do_syscall;
var
tmpref: treference;
libparaloc: pcgparalocation;
hsym: tsym;
begin
case target_info.system of
system_arm_aros:
begin
if (po_syscall_baselast in tprocdef(procdefinition).procoptions) then
begin
current_asmdata.CurrAsmList.concat(tai_comment.create(strpnew('AROS SysCall - BaseLast')));
current_asmdata.CurrAsmList.concat(tai_comment.create(strpnew('AROS SysCall')));
cg.getcpuregister(current_asmdata.CurrAsmList,NR_R12);
hsym:=tsym(procdefinition.parast.Find('syscalllib'));
if not assigned(hsym) then
internalerror(2016110605);
libparaloc:=tparavarsym(hsym).paraloc[callerside].location;
if not assigned(libparaloc) then
internalerror(2016110604);
case libparaloc^.loc of
LOC_REGISTER:
reference_reset_base(tmpref,libparaloc^.register,-tprocdef(procdefinition).extnumber,sizeof(pint),[]);
LOC_REFERENCE:
begin
reference_reset_base(tmpref,libparaloc^.reference.index,libparaloc^.reference.offset,sizeof(pint),[]);
cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_ADDR,OS_ADDR,tmpref,NR_R12);
reference_reset_base(tmpref,NR_R12,-tprocdef(procdefinition).extnumber,sizeof(pint),[]);
end;
else
internalerror(2016110603);
end;
get_syscall_call_ref(tmpref,NR_R12);
cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_ADDR,OS_ADDR,tmpref,NR_R12);
cg.a_call_reg(current_asmdata.CurrAsmList,NR_R12);

View File

@ -63,36 +63,21 @@ implementation
procedure ti386callnode.do_syscall;
var
tmpref: treference;
libparaloc: pcgparalocation;
begin
case target_info.system of
system_i386_aros:
begin
if (po_syscall_baselast in tprocdef(procdefinition).procoptions) then
if ([po_syscall_baselast, po_syscall_basereg] * tprocdef(procdefinition).procoptions) <> [] then
begin
current_asmdata.CurrAsmList.concat(tai_comment.create(strpnew('AROS SysCall - BaseLast on Stack')));
{ re-read the libbase pushed first on the stack, instead of just trusting the
mangledname will work. this is important for example for threadvar libbases.
and this way they also don't need to be resolved twice then. (KB) }
libparaloc:=paralocs[procdefinition.paras.count-1]^.location;
if libparaloc^.loc <> LOC_REFERENCE then
internalerror(2016090203);
reference_reset_base(tmpref,libparaloc^.reference.index,libparaloc^.reference.offset,sizeof(pint),[]);
current_asmdata.CurrAsmList.concat(tai_comment.create(strpnew('AROS SysCall')));
cg.getcpuregister(current_asmdata.CurrAsmList,NR_EAX);
cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_ADDR,OS_ADDR,tmpref,NR_EAX);
reference_reset_base(tmpref,NR_EAX,-tprocdef(procdefinition).extnumber,sizeof(pint),[]);
get_syscall_call_ref(tmpref,NR_EAX);
current_asmdata.CurrAsmList.concat(taicpu.op_ref(A_CALL,S_NO,tmpref));
cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_EAX);
exit;
end;
if (po_syscall_basereg in tprocdef(procdefinition).procoptions) then
begin
current_asmdata.CurrAsmList.concat(tai_comment.create(strpnew('AROS SysCall - RegBase in EAX')));
{ libbase must be in EAX already, so just piggyback that, and dereference it }
reference_reset_base(tmpref,NR_EAX,-tprocdef(procdefinition).extnumber,sizeof(pint),[]);
current_asmdata.CurrAsmList.concat(taicpu.op_ref(A_CALL,S_NO,tmpref));
exit;
end;
internalerror(2016090104);
end;
else

View File

@ -79,6 +79,9 @@ interface
procedure extra_pre_call_code;virtual;
procedure extra_call_code;virtual;
procedure extra_post_call_code;virtual;
function get_syscall_libbase_paraloc: pcgparalocation;virtual;
procedure get_syscall_call_ref(out tmpref: treference; reg: tregister);virtual;
procedure do_syscall;virtual;abstract;
{ The function result is returned in a tcgpara. This tcgpara has to
@ -436,6 +439,40 @@ implementation
begin
end;
function tcgcallnode.get_syscall_libbase_paraloc: pcgparalocation;
var
hsym: tsym;
begin
hsym:=tsym(procdefinition.parast.Find('syscalllib'));
if not assigned(hsym) then
internalerror(2016110605);
result:=tparavarsym(hsym).paraloc[callerside].location;
if not assigned(result) then
internalerror(2016110604);
end;
procedure tcgcallnode.get_syscall_call_ref(out tmpref: treference; reg: tregister);
var
libparaloc: pcgparalocation;
begin
libparaloc:=get_syscall_libbase_paraloc;
case libparaloc^.loc of
LOC_REGISTER:
reference_reset_base(tmpref,libparaloc^.register,-tprocdef(procdefinition).extnumber,sizeof(pint),[]);
LOC_REFERENCE:
begin
reference_reset_base(tmpref,libparaloc^.reference.index,libparaloc^.reference.offset,sizeof(pint),[]);
cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_ADDR,OS_ADDR,tmpref,reg);
reference_reset_base(tmpref,reg,-tprocdef(procdefinition).extnumber,sizeof(pint),[]);
end;
else
begin
reference_reset(tmpref,0,[]);
internalerror(2016090202);
end;
end;
end;
function tcgcallnode.can_call_ref(var ref: treference): boolean;
begin

View File

@ -43,7 +43,7 @@ implementation
uses
globtype,systems,
cutils,verbose,globals,
symconst,symtype,symbase,symsym,symcpu,symtable,defutil,paramgr,parabase,
symconst,symbase,symsym,symcpu,symtable,defutil,paramgr,parabase,
cgbase,pass_2,
cpuinfo,cpubase,aasmbase,aasmtai,aasmdata,aasmcpu,
nmem,nld,ncnv,
@ -83,8 +83,6 @@ implementation
var
tmpref: treference;
libparaloc: pcgparalocation;
hsym: tsym;
begin
case target_info.system of
system_powerpc_amiga:
@ -101,27 +99,7 @@ implementation
po_syscall_baselast,po_syscall_basereg] * tprocdef(procdefinition).procoptions) <> [] then
begin
cg.getcpuregister(current_asmdata.CurrAsmList,NR_R12);
hsym:=tsym(procdefinition.parast.Find('syscalllib'));
if not assigned(hsym) then
internalerror(2016090501);
libparaloc:=tparavarsym(hsym).paraloc[callerside].location;
if not assigned(libparaloc) then
internalerror(2016090502);
case libparaloc^.loc of
LOC_REGISTER:
reference_reset_base(tmpref,libparaloc^.register,-tprocdef(procdefinition).extnumber,sizeof(pint),[]);
LOC_REFERENCE:
begin
{ this can happen for sysvbase; if we run out of regs, the libbase will be passed on the stack }
reference_reset_base(tmpref,libparaloc^.reference.index,libparaloc^.reference.offset,sizeof(pint),[]);
cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_ADDR,OS_ADDR,tmpref,NR_R12);
reference_reset_base(tmpref,NR_R12,-tprocdef(procdefinition).extnumber,sizeof(pint),[]);
end;
else
internalerror(2016090202);
end;
get_syscall_call_ref(tmpref,NR_R12);
do_call_ref(tmpref);
cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_R12);

View File

@ -67,16 +67,18 @@ implementation
case target_info.system of
system_x86_64_aros:
begin
// one syscall convention for AROS
current_asmdata.CurrAsmList.concat(tai_comment.create(strpnew('AROS SysCall')));
reference_reset(tmpref,sizeof(pint),[]);
tmpref.symbol:=current_asmdata.RefAsmSymbol(tstaticvarsym(tcpuprocdef(procdefinition).libsym).mangledname,AT_FUNCTION);
cg.getcpuregister(current_asmdata.CurrAsmList,NR_RAX);
cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_ADDR,OS_ADDR,tmpref,NR_RAX);
reference_reset_base(tmpref,NR_RAX,-tprocdef(procdefinition).extnumber,sizeof(pint),[]);
cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_ADDR,OS_ADDR,tmpref,NR_RAX);
cg.a_call_reg(current_asmdata.CurrAsmList,NR_RAX);
cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_RAX);
if ([po_syscall_baselast,po_syscall_basereg] * tprocdef(procdefinition).procoptions) <> [] then
begin
current_asmdata.CurrAsmList.concat(tai_comment.create(strpnew('AROS SysCall')));
cg.getcpuregister(current_asmdata.CurrAsmList,NR_RAX);
get_syscall_call_ref(tmpref,NR_RAX);
current_asmdata.CurrAsmList.concat(taicpu.op_ref(A_CALL,S_NO,tmpref));
cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_RAX);
exit;
end;
internalerror(2016120101);
end;
else
internalerror(2015062801);