mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-07 06:28:55 +02:00
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:
parent
c2af5a104e
commit
f5f895e2a3
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user