powerpc: reworked syscall generation once more. instead of making various assumptions on the syscallib location based on the calling convention, simply search for the lib and use its location. also unified the call generation itself

git-svn-id: trunk@34435 -
This commit is contained in:
Károly Balogh 2016-09-05 21:11:51 +00:00
parent 95520ea767
commit 7a6f18c496

View File

@ -43,7 +43,7 @@ implementation
uses uses
globtype,systems, globtype,systems,
cutils,verbose,globals, cutils,verbose,globals,
symconst,symbase,symsym,symcpu,symtable,defutil,paramgr,parabase, symconst,symtype,symbase,symsym,symcpu,symtable,defutil,paramgr,parabase,
cgbase,pass_2, cgbase,pass_2,
cpuinfo,cpubase,aasmbase,aasmtai,aasmdata,aasmcpu, cpuinfo,cpubase,aasmbase,aasmtai,aasmdata,aasmcpu,
nmem,nld,ncnv, nmem,nld,ncnv,
@ -71,23 +71,28 @@ implementation
end; end;
end; end;
procedure tppccallnode.do_syscall; procedure tppccallnode.do_syscall;
procedure do_call_ref(constref ref: treference);
begin
cg.getcpuregister(current_asmdata.CurrAsmList,NR_R0);
cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_ADDR,OS_ADDR,ref,NR_R0);
cg.a_call_reg(current_asmdata.CurrAsmList,NR_R0);
cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_R0);
end;
var var
tmpref: treference; tmpref: treference;
libparaloc: pcgparalocation; libparaloc: pcgparalocation;
hsym: tsym;
begin begin
case target_info.system of case target_info.system of
system_powerpc_amiga: system_powerpc_amiga:
begin begin
// one syscall convention for Amiga/PowerPC { one syscall convention for AmigaOS/PowerPC
// which is very similar to basesysv on MorphOS which is very similar to basesysv on MorphOS }
cg.getcpuregister(current_asmdata.CurrAsmList,NR_R0);
reference_reset_base(tmpref,NR_R3,tprocdef(procdefinition).extnumber,sizeof(pint)); reference_reset_base(tmpref,NR_R3,tprocdef(procdefinition).extnumber,sizeof(pint));
current_asmdata.CurrAsmList.concat(taicpu.op_reg_ref(A_LWZ,NR_R0,tmpref)); do_call_ref(tmpref);
current_asmdata.CurrAsmList.concat(taicpu.op_reg(A_MTCTR,NR_R0));
current_asmdata.CurrAsmList.concat(taicpu.op_none(A_BCTRL));
cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_R0);
end; end;
system_powerpc_morphos: system_powerpc_morphos:
begin begin
@ -95,54 +100,42 @@ implementation
if ([po_syscall_basesysv,po_syscall_sysv, if ([po_syscall_basesysv,po_syscall_sysv,
po_syscall_sysvbase,po_syscall_r12base] * tprocdef(procdefinition).procoptions) <> [] then po_syscall_sysvbase,po_syscall_r12base] * tprocdef(procdefinition).procoptions) <> [] then
begin begin
cg.getcpuregister(current_asmdata.CurrAsmList,NR_R0);
cg.getcpuregister(current_asmdata.CurrAsmList,NR_R12); cg.getcpuregister(current_asmdata.CurrAsmList,NR_R12);
if (po_syscall_sysvbase in tprocdef(procdefinition).procoptions) then hsym:=tsym(procdefinition.parast.Find('syscalllib'));
begin if not assigned(hsym) then
{ for sysvbase, find the last para, and get the libbase from there } internalerror(2016090501);
libparaloc:=paralocs[procdefinition.paras.count-1]^.location; libparaloc:=tparavarsym(hsym).paraloc[callerside].location;
if libparaloc^.loc = LOC_REGISTER then if not assigned(libparaloc) then
reference_reset_base(tmpref,libparaloc^.register,-tprocdef(procdefinition).extnumber,sizeof(pint)) internalerror(2016090502);
else if libparaloc^.loc = LOC_REFERENCE then
case libparaloc^.loc of
LOC_REGISTER:
reference_reset_base(tmpref,libparaloc^.register,-tprocdef(procdefinition).extnumber,sizeof(pint));
LOC_REFERENCE:
begin 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)); 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); 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)); reference_reset_base(tmpref,NR_R12,-tprocdef(procdefinition).extnumber,sizeof(pint));
end end;
else else
internalerror(2016090202); internalerror(2016090202);
end end;
else
if (po_syscall_basesysv in tprocdef(procdefinition).procoptions) then
reference_reset_base(tmpref,NR_R3,-tprocdef(procdefinition).extnumber,sizeof(pint))
else
{ other calling conventions expect the base in R12 at this point }
reference_reset_base(tmpref,NR_R12,-tprocdef(procdefinition).extnumber,sizeof(pint));
current_asmdata.CurrAsmList.concat(taicpu.op_reg_ref(A_LWZ,NR_R0,tmpref));
current_asmdata.CurrAsmList.concat(taicpu.op_reg(A_MTCTR,NR_R0));
current_asmdata.CurrAsmList.concat(taicpu.op_none(A_BCTRL));
do_call_ref(tmpref);
cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_R12); cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_R12);
cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_R0);
end end
else if po_syscall_legacy in tprocdef(procdefinition).procoptions then else if po_syscall_legacy in tprocdef(procdefinition).procoptions then
begin begin
cg.getcpuregister(current_asmdata.CurrAsmList,NR_R0);
cg.getcpuregister(current_asmdata.CurrAsmList,NR_R3); cg.getcpuregister(current_asmdata.CurrAsmList,NR_R3);
{ store call offset into R3 } { R3 must contain the call offset }
current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI,NR_R3,-tprocdef(procdefinition).extnumber)); current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI,NR_R3,-tprocdef(procdefinition).extnumber));
{ prepare LR, and call function }
reference_reset_base(tmpref,NR_R2,100,4); { 100 ($64) is EmulDirectCallOS offset } reference_reset_base(tmpref,NR_R2,100,4); { 100 ($64) is EmulDirectCallOS offset }
current_asmdata.CurrAsmList.concat(taicpu.op_reg_ref(A_LWZ,NR_R0,tmpref));
current_asmdata.CurrAsmList.concat(taicpu.op_reg(A_MTLR,NR_R0));
current_asmdata.CurrAsmList.concat(taicpu.op_none(A_BLRL));
do_call_ref(tmpref);
cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_R3); cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_R3);
cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_R0);
end end
else else
internalerror(2005010403); internalerror(2005010403);