From 657aa063608bbb6640493cab21df66bcc30dae94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A1roly=20Balogh?= <karoly@freepascal.org> Date: Sun, 6 Nov 2016 14:31:42 +0000 Subject: [PATCH] arm: arm-aros syscall support git-svn-id: trunk@34809 - --- compiler/arm/narmcal.pas | 65 +++++++++++++++++++++++++++++++++++++--- compiler/arm/symcpu.pas | 59 ++++++++++++++++++++++++++++++++++-- compiler/parser.pas | 1 + compiler/pdecsub.pas | 8 ++--- compiler/ppu.pas | 2 +- 5 files changed, 124 insertions(+), 11 deletions(-) diff --git a/compiler/arm/narmcal.pas b/compiler/arm/narmcal.pas index 67978e3f0f..42aaab58fc 100644 --- a/compiler/arm/narmcal.pas +++ b/compiler/arm/narmcal.pas @@ -30,18 +30,73 @@ interface type tarmcallnode = class(tcgcallnode) + procedure gen_syscall_para(para: tcallparanode); override; procedure set_result_location(realresdef: tstoreddef);override; + public + procedure do_syscall;override; end; implementation uses - verbose,globtype,globals,aasmdata, - symconst, - cgbase,cgutils,cpuinfo, - ncgutil,tgobj, + verbose,globtype,globals,aasmdata,aasmtai, + symconst,symtype,symbase,symsym,symcpu,parabase,paramgr, + cgbase,cgobj,cgutils,cpuinfo,cpubase,cutils, + ncgutil,tgobj,nld, systems; + procedure tarmcallnode.gen_syscall_para(para: tcallparanode); + begin + { lib parameter has no special type but proccalloptions must be a syscall } + para.left:=cloadnode.create(tcpuprocdef(procdefinition).libsym,tcpuprocdef(procdefinition).libsym.owner); + end; + + 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'))); + + 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; + + cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_ADDR,OS_ADDR,tmpref,NR_R12); + cg.a_call_reg(current_asmdata.CurrAsmList,NR_R12); + cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_R12); + exit; + end; + internalerror(2016110601); + end; + else + internalerror(2016110602); + end; + end; + procedure tarmcallnode.set_result_location(realresdef: tstoreddef); begin if (realresdef.typ=floatdef) and @@ -77,6 +132,8 @@ implementation end; + + begin ccallnode:=tarmcallnode; end. diff --git a/compiler/arm/symcpu.pas b/compiler/arm/symcpu.pas index 79e89c19f2..926ef4f581 100644 --- a/compiler/arm/symcpu.pas +++ b/compiler/arm/symcpu.pas @@ -26,7 +26,7 @@ unit symcpu; interface uses - symtype,symdef,symsym,globtype; + symtype,symdef,symsym,symconst,globtype; type { defs } @@ -92,9 +92,18 @@ type tcpuprocdef = class(tprocdef) { the arm paramanager might need to know the total size of the stackframe - to avoid cyclic unit dependencies or global variables, this infomatation is + to avoid cyclic unit dependencies or global variables, this information is stored in total_stackframe_size } total_stackframe_size : aint; + procedure ppuload_platform(ppufile: tcompilerppufile); override; + procedure ppuwrite_platform(ppufile: tcompilerppufile); override; + public + { library symbol for AROS } + libsym : tsym; + libsymderef : tderef; + function getcopyas(newtyp: tdeftyp; copytyp: tproccopytyp): tstoreddef; override; + procedure buildderef; override; + procedure deref; override; end; tcpuprocdefclass = class of tcpuprocdef; @@ -178,6 +187,52 @@ const implementation + +{**************************************************************************** + tcpuprocdef +****************************************************************************} + + procedure tcpuprocdef.ppuload_platform(ppufile: tcompilerppufile); + begin + inherited; + if po_syscall_has_libsym in procoptions then + ppufile.getderef(libsymderef); + end; + + + procedure tcpuprocdef.ppuwrite_platform(ppufile: tcompilerppufile); + begin + inherited; + if po_syscall_has_libsym in procoptions then + ppufile.putderef(libsymderef); + end; + + + function tcpuprocdef.getcopyas(newtyp: tdeftyp; copytyp: tproccopytyp): tstoreddef; + begin + result:=inherited; + if newtyp=procdef then + tcpuprocdef(result).libsym:=libsym; + end; + + + procedure tcpuprocdef.buildderef; + begin + inherited; + if po_syscall_has_libsym in procoptions then + libsymderef.build(libsym); + end; + + + procedure tcpuprocdef.deref; + begin + inherited; + if po_syscall_has_libsym in procoptions then + libsym:=tsym(libsymderef.resolve) + else + libsym:=nil; + end; + begin { used tdef classes } cfiledef:=tcpufiledef; diff --git a/compiler/parser.pas b/compiler/parser.pas index bddb8ce1ed..21e395b31e 100644 --- a/compiler/parser.pas +++ b/compiler/parser.pas @@ -119,6 +119,7 @@ implementation system_powerpc_amiga, system_powerpc_morphos, system_m68k_amiga, + system_arm_aros, system_i386_aros, system_x86_64_aros: include(supported_calling_conventions,pocall_syscall); diff --git a/compiler/pdecsub.pas b/compiler/pdecsub.pas index 4d93fff8ed..45986afae2 100644 --- a/compiler/pdecsub.pas +++ b/compiler/pdecsub.pas @@ -2108,7 +2108,7 @@ procedure pd_syscall(pd:tabstractprocdef); internalerror(2016090101); end; -{$if defined(powerpc) or defined(m68k) or defined(i386) or defined(x86_64)} +{$if defined(powerpc) or defined(m68k) or defined(i386) or defined(x86_64) or defined(arm)} const syscall_paranr: array[boolean] of aint = ( paranr_syscall_lib_last, paranr_syscall_lib_first ); @@ -2119,12 +2119,12 @@ var v: Tconstexprint; vo: tvaroptions; paranr: aint; -{$endif defined(powerpc) or defined(m68k) or defined(i386) or defined(x86_64)} +{$endif defined(powerpc) or defined(m68k) or defined(i386) or defined(x86_64) or defined(arm)} begin if (pd.typ<>procdef) and (target_info.system <> system_powerpc_amiga) then internalerror(2003042614); tprocdef(pd).forwarddef:=false; -{$if defined(powerpc) or defined(m68k) or defined(i386) or defined(x86_64)} +{$if defined(powerpc) or defined(m68k) or defined(i386) or defined(x86_64) or defined(arm)} include_po_syscall; if target_info.system = system_m68k_atari then @@ -2173,7 +2173,7 @@ begin Tprocdef(pd).extnumber:=v.uvalue * sizeof(pint) else Tprocdef(pd).extnumber:=v.uvalue; -{$endif defined(powerpc) or defined(m68k) or defined(i386) or defined(x86_64)} +{$endif defined(powerpc) or defined(m68k) or defined(i386) or defined(x86_64) or defined(arm)} end; diff --git a/compiler/ppu.pas b/compiler/ppu.pas index 1ded2a9a8a..3882b5ec95 100644 --- a/compiler/ppu.pas +++ b/compiler/ppu.pas @@ -43,7 +43,7 @@ type {$endif Test_Double_checksum} const - CurrentPPUVersion = 187; + CurrentPPUVersion = 188; { unit flags } uf_init = $000001; { unit has initialization section }