mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-20 09:49:08 +02:00
powerpc: simplified code generation for MorphOS syscalls
git-svn-id: trunk@34417 -
This commit is contained in:
parent
464ecab542
commit
84abdd8287
@ -664,8 +664,10 @@ unit cpupara;
|
|||||||
var
|
var
|
||||||
paraloc : pcgparalocation;
|
paraloc : pcgparalocation;
|
||||||
paracgsize : tcgsize;
|
paracgsize : tcgsize;
|
||||||
|
offset : aint;
|
||||||
begin
|
begin
|
||||||
result:=false;
|
result:=false;
|
||||||
|
offset:=-1;
|
||||||
case target_info.system of
|
case target_info.system of
|
||||||
system_powerpc_morphos:
|
system_powerpc_morphos:
|
||||||
begin
|
begin
|
||||||
@ -674,58 +676,34 @@ unit cpupara;
|
|||||||
p.paraloc[callerside].size:=paracgsize;
|
p.paraloc[callerside].size:=paracgsize;
|
||||||
p.paraloc[callerside].intsize:=tcgsize2size[paracgsize];
|
p.paraloc[callerside].intsize:=tcgsize2size[paracgsize];
|
||||||
paraloc:=p.paraloc[callerside].add_location;
|
paraloc:=p.paraloc[callerside].add_location;
|
||||||
paraloc^.loc:=LOC_REFERENCE;
|
|
||||||
{ The OS side should be zero extended and the entire "virtual"
|
{ The OS side should be zero extended and the entire "virtual"
|
||||||
68k register should be overwritten. This is what the C ppcinline
|
68k register should be overwritten. This is what the C ppcinline
|
||||||
macros do as well, by casting all arguments to ULONG. A call
|
macros do as well, by casting all arguments to ULONG. A call
|
||||||
which breaks w/o this is for example exec/RawPutChar (KB) }
|
which breaks w/o this is for example exec/RawPutChar (KB) }
|
||||||
paraloc^.size:=OS_ADDR;
|
paraloc^.size:=OS_ADDR;
|
||||||
paraloc^.def:=p.vardef;
|
paraloc^.def:=p.vardef;
|
||||||
paraloc^.reference.index:=newreg(R_INTREGISTER,RS_R2,R_SUBWHOLE);
|
|
||||||
{ pattern is always uppercase'd }
|
{ convert d0-d7/a0-a6 virtual 68k reg patterns into offsets }
|
||||||
if s='D0' then
|
if length(s) = 2 then
|
||||||
paraloc^.reference.offset:=0
|
begin
|
||||||
else if s='D1' then
|
if (s[1] = 'D') and (s[2] in ['0'..'7']) then
|
||||||
paraloc^.reference.offset:=4
|
offset:=(ord(s[2]) - ord('0')) * sizeof(pint)
|
||||||
else if s='D2' then
|
else if (s[1] = 'A') and (s[2] in ['0'..'6']) then
|
||||||
paraloc^.reference.offset:=8
|
offset:=(ord(s[2]) - ord('0') + 8) * sizeof(pint);
|
||||||
else if s='D3' then
|
|
||||||
paraloc^.reference.offset:=12
|
if offset < 0 then
|
||||||
else if s='D4' then
|
exit;
|
||||||
paraloc^.reference.offset:=16
|
|
||||||
else if s='D5' then
|
paraloc^.loc:=LOC_REFERENCE;
|
||||||
paraloc^.reference.offset:=20
|
paraloc^.reference.index:=newreg(R_INTREGISTER,RS_R2,R_SUBWHOLE);
|
||||||
else if s='D6' then
|
paraloc^.reference.offset:=offset;
|
||||||
paraloc^.reference.offset:=24
|
end
|
||||||
else if s='D7' then
|
{ 'R12' is special, used internally to support r12base and sysv
|
||||||
paraloc^.reference.offset:=28
|
|
||||||
else if s='A0' then
|
|
||||||
paraloc^.reference.offset:=32
|
|
||||||
else if s='A1' then
|
|
||||||
paraloc^.reference.offset:=36
|
|
||||||
else if s='A2' then
|
|
||||||
paraloc^.reference.offset:=40
|
|
||||||
else if s='A3' then
|
|
||||||
paraloc^.reference.offset:=44
|
|
||||||
else if s='A4' then
|
|
||||||
paraloc^.reference.offset:=48
|
|
||||||
else if s='A5' then
|
|
||||||
paraloc^.reference.offset:=52
|
|
||||||
{ 'A6' (offset 56) is used by mossyscall as libbase, so API
|
|
||||||
never passes parameters in it,
|
|
||||||
Indeed, but this allows to declare libbase either explicitly
|
|
||||||
or let the compiler insert it }
|
|
||||||
else if s='A6' then
|
|
||||||
paraloc^.reference.offset:=56
|
|
||||||
{ 'A7' is the stack pointer on 68k, can't be overwritten
|
|
||||||
by API calls, so it has no offset }
|
|
||||||
{ 'R12' is special, used internally to support r12base sysv
|
|
||||||
calling convention }
|
calling convention }
|
||||||
else if s='R12' then
|
else if s='R12' then
|
||||||
begin
|
begin
|
||||||
paraloc^.loc:=LOC_REGISTER;
|
paraloc^.loc:=LOC_REGISTER;
|
||||||
paraloc^.size:=OS_ADDR;
|
|
||||||
paraloc^.def:=voidpointertype;
|
|
||||||
paraloc^.register:=NR_R12;
|
paraloc^.register:=NR_R12;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
|
@ -75,6 +75,7 @@ implementation
|
|||||||
procedure tppccallnode.do_syscall;
|
procedure tppccallnode.do_syscall;
|
||||||
var
|
var
|
||||||
tmpref: treference;
|
tmpref: treference;
|
||||||
|
libparaloc: pcgparalocation;
|
||||||
begin
|
begin
|
||||||
case target_info.system of
|
case target_info.system of
|
||||||
system_powerpc_amiga:
|
system_powerpc_amiga:
|
||||||
@ -90,21 +91,35 @@ implementation
|
|||||||
end;
|
end;
|
||||||
system_powerpc_morphos:
|
system_powerpc_morphos:
|
||||||
begin
|
begin
|
||||||
if (po_syscall_sysv in tprocdef(procdefinition).procoptions) or
|
{ all conventions but legacy }
|
||||||
(po_syscall_sysvbase in tprocdef(procdefinition).procoptions) then
|
if ([po_syscall_basesysv,po_syscall_sysv,
|
||||||
|
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_R0);
|
||||||
cg.getcpuregister(current_asmdata.CurrAsmList,NR_R12);
|
cg.getcpuregister(current_asmdata.CurrAsmList,NR_R12);
|
||||||
|
|
||||||
reference_reset(tmpref,sizeof(pint));
|
if (po_syscall_sysvbase in tprocdef(procdefinition).procoptions) then
|
||||||
tmpref.symbol:=current_asmdata.RefAsmSymbol(tstaticvarsym(tcpuprocdef(procdefinition).libsym).mangledname,AT_DATA);
|
begin
|
||||||
tmpref.refaddr:=addr_higha;
|
{ for sysvbase, find the last para, and get the libbase from there }
|
||||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_ref(A_LIS,NR_R12,tmpref));
|
libparaloc:=paralocs[procdefinition.paras.count-1]^.location;
|
||||||
tmpref.base:=NR_R12;
|
if libparaloc^.loc = LOC_REGISTER then
|
||||||
tmpref.refaddr:=addr_low;
|
reference_reset_base(tmpref,libparaloc^.register,-tprocdef(procdefinition).extnumber,sizeof(pint))
|
||||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_ref(A_LWZ,NR_R12,tmpref));
|
else if libparaloc^.loc = LOC_REFERENCE then
|
||||||
|
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(2016090202);
|
||||||
|
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));
|
||||||
|
|
||||||
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_ref(A_LWZ,NR_R0,tmpref));
|
||||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg(A_MTCTR,NR_R0));
|
current_asmdata.CurrAsmList.concat(taicpu.op_reg(A_MTCTR,NR_R0));
|
||||||
current_asmdata.CurrAsmList.concat(taicpu.op_none(A_BCTRL));
|
current_asmdata.CurrAsmList.concat(taicpu.op_none(A_BCTRL));
|
||||||
@ -112,19 +127,6 @@ implementation
|
|||||||
cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_R12);
|
cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_R12);
|
||||||
cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_R0);
|
cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_R0);
|
||||||
end
|
end
|
||||||
else if (po_syscall_basesysv in tprocdef(procdefinition).procoptions) or
|
|
||||||
(po_syscall_r12base in tprocdef(procdefinition).procoptions) then
|
|
||||||
begin
|
|
||||||
cg.getcpuregister(current_asmdata.CurrAsmList,NR_R0);
|
|
||||||
if (po_syscall_basesysv in tprocdef(procdefinition).procoptions) then
|
|
||||||
reference_reset_base(tmpref,NR_R3,-tprocdef(procdefinition).extnumber,sizeof(pint))
|
|
||||||
else
|
|
||||||
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));
|
|
||||||
cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_R0);
|
|
||||||
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_R0);
|
||||||
|
Loading…
Reference in New Issue
Block a user