diff --git a/.gitattributes b/.gitattributes index 02d9b2dc2d..9995794a50 100644 --- a/.gitattributes +++ b/.gitattributes @@ -345,6 +345,7 @@ compiler/llvm/nllvmbas.pas svneol=native#text/plain compiler/llvm/nllvmcal.pas svneol=native#text/plain compiler/llvm/nllvmcnv.pas svneol=native#text/plain compiler/llvm/nllvmcon.pas svneol=native#text/plain +compiler/llvm/nllvmflw.pas svneol=native#text/plain compiler/llvm/nllvminl.pas svneol=native#text/plain compiler/llvm/nllvmld.pas svneol=native#text/plain compiler/llvm/nllvmmat.pas svneol=native#text/plain @@ -470,6 +471,7 @@ compiler/ncginl.pas svneol=native#text/plain compiler/ncgld.pas svneol=native#text/plain compiler/ncgmat.pas svneol=native#text/plain compiler/ncgmem.pas svneol=native#text/plain +compiler/ncgnstfl.pas svneol=native#text/plain compiler/ncgnstld.pas svneol=native#text/plain compiler/ncgnstmm.pas svneol=native#text/plain compiler/ncgobjc.pas svneol=native#text/plain diff --git a/compiler/llvm/llvmnode.pas b/compiler/llvm/llvmnode.pas index 0d464c0454..e8162e56d9 100644 --- a/compiler/llvm/llvmnode.pas +++ b/compiler/llvm/llvmnode.pas @@ -37,8 +37,8 @@ implementation ncgbas,ncgflw,ncgcnv,ncgld,ncgmem,ncgcon,ncgset, ncgadd,ncgcal,ncgmat,ncginl, tgllvm,hlcgllvm, - nllvmadd,nllvmbas,nllvmcal,nllvmcnv,nllvmcon,nllvminl,nllvmld,nllvmmat, - nllvmmem,nllvmtcon,nllvmutil, + nllvmadd,nllvmbas,nllvmcal,nllvmcnv,nllvmcon,nllvmflw,nllvminl,nllvmld, + nllvmmat,nllvmmem,nllvmtcon,nllvmutil, llvmpara, symllvm; diff --git a/compiler/llvm/nllvmflw.pas b/compiler/llvm/nllvmflw.pas new file mode 100644 index 0000000000..177461bfd8 --- /dev/null +++ b/compiler/llvm/nllvmflw.pas @@ -0,0 +1,67 @@ +{ + Copyright (c) 2016 by Jonas Maebe + + Generate assembler for nodes that influence the flow for llvm + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + **************************************************************************** +} +unit nllvmflw; + +{$i fpcdefs.inc} + +interface + + uses + aasmbase, + nflw, ncgflw, ncgnstfl; + + type + tllvmlabelnode = class(tcglabelnode) + function getasmlabel: tasmlabel; override; + end; + + +implementation + +{***************************************************************************** + SecondLabel +*****************************************************************************} + + uses + aasmdata; + + + function tllvmlabelnode.getasmlabel: tasmlabel; + begin + { don't allocate global labels even if the label is accessed from + another routine: we always have to refer to such labels using the + blockaddress() construct, which works with local labels too. + Additionally, LLVM does not support defining global labels in the + middle of a routine -> jumping to such a label from assembler code + from another function will not work anyway (have to handle that by + passing a blockaddress as argument to an assembler block, although + "some targets may provide defined semantics when using the value as + the operand to an inline assembly") } + if not(assigned(asmlabel)) then + current_asmdata.getjumplabel(asmlabel); + result:=asmlabel + end; + +begin + clabelnode:=tllvmlabelnode; +end. + diff --git a/compiler/ncgflw.pas b/compiler/ncgflw.pas index d0215a09a1..cb9c6cb70f 100644 --- a/compiler/ncgflw.pas +++ b/compiler/ncgflw.pas @@ -62,10 +62,10 @@ interface end; tcglabelnode = class(tlabelnode) - private + protected asmlabel : tasmlabel; public - function getasmlabel : tasmlabel; + function getasmlabel : tasmlabel; virtual; procedure pass_generate_code;override; end; diff --git a/compiler/ncgnstfl.pas b/compiler/ncgnstfl.pas new file mode 100644 index 0000000000..6a573c9316 --- /dev/null +++ b/compiler/ncgnstfl.pas @@ -0,0 +1,68 @@ +{ + Copyright (c) 2016 by Jonas Maebe + + Generate assembler for nodes that influence the flow + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + **************************************************************************** +} +unit ncgnstfl; + +{$i fpcdefs.inc} + +interface + + uses + node, + nflw, ncgflw; + + type + tcgnestgotonode = class(tcggotonode) + function pass_typecheck: tnode; override; + end; + +implementation + + uses + globtype,globals, + nld, + symdef,symsym,symcreat; + + + function tcgnestgotonode.pass_typecheck: tnode; + begin + result:=inherited; + if (m_non_local_goto in current_settings.modeswitches) and + assigned(labelsym.jumpbuf) then + begin + { we will access this jumpbuf local variable from a nested context, + but the loadnode to do so only gets created in pass_1. This is too + late for us to detect that it should have been added to the + parentfpstruct, so temporarily create and typecheckpass a load + node for the jumpbuf here (so that it can be added now) } + with cloadnode.create(labelsym.jumpbuf,labelsym.jumpbuf.Owner) do + begin + pass_typecheck; + free + end; + end; + end; + + +begin + cgotonode:=tcgnestgotonode; +end. +