nllvmflw.pas 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. {
  2. Copyright (c) 2016 by Jonas Maebe
  3. Generate assembler for nodes that influence the flow for llvm
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. ****************************************************************************
  16. }
  17. unit nllvmflw;
  18. {$i fpcdefs.inc}
  19. interface
  20. uses
  21. globtype,
  22. symtype,symdef,
  23. aasmbase,aasmdata,
  24. cgbase,
  25. node, nflw, ncgflw, ncgnstfl;
  26. type
  27. tllvmlabelnode = class(tcglabelnode)
  28. function getasmlabel: tasmlabel; override;
  29. end;
  30. tllvmtryexceptnode = class(tcgtryexceptnode)
  31. end;
  32. tllvmtryfinallynode = class(tcgtryfinallynode)
  33. function pass_1: tnode; override;
  34. end;
  35. tllvmraisenode = class(tcgraisenode)
  36. function pass_1: tnode; override;
  37. procedure pass_generate_code; override;
  38. end;
  39. implementation
  40. uses
  41. systems,globals,verbose,
  42. symconst,symtable,symsym,llvmdef,defutil,
  43. pass_2,cgutils,hlcgobj,parabase,paramgr,tgobj,
  44. llvmbase,aasmtai,aasmllvm,
  45. procinfo,llvmpi;
  46. {*****************************************************************************
  47. SecondLabel
  48. *****************************************************************************}
  49. function tllvmlabelnode.getasmlabel: tasmlabel;
  50. begin
  51. { don't allocate global labels even if the label is accessed from
  52. another routine: we always have to refer to such labels using the
  53. blockaddress() construct, which works with local labels too.
  54. Additionally, LLVM does not support defining global labels in the
  55. middle of a routine -> jumping to such a label from assembler code
  56. from another function will not work anyway (have to handle that by
  57. passing a blockaddress as argument to an assembler block, although
  58. "some targets may provide defined semantics when using the value as
  59. the operand to an inline assembly") }
  60. if not(assigned(asmlabel)) then
  61. current_asmdata.getjumplabel(asmlabel);
  62. result:=asmlabel
  63. end;
  64. {*****************************************************************************
  65. tllvmtryfinallynode
  66. *****************************************************************************}
  67. function tllvmtryfinallynode.pass_1: tnode;
  68. begin
  69. { make a copy of the "finally" code for the "no exception happened"
  70. case }
  71. if not assigned(third) then
  72. third:=right.getcopy;
  73. result:=inherited;
  74. end;
  75. {*****************************************************************************
  76. tllvmraisenode
  77. *****************************************************************************}
  78. function tllvmraisenode.pass_1: tnode;
  79. begin
  80. if assigned(left) then
  81. result:=inherited
  82. else
  83. begin
  84. expectloc:=LOC_VOID;
  85. result:=nil;
  86. end;
  87. end;
  88. procedure tllvmraisenode.pass_generate_code;
  89. var
  90. currexceptlabel: tasmlabel;
  91. begin
  92. location_reset(location,LOC_VOID,OS_NO);
  93. currexceptlabel:=nil;
  94. { a reraise must raise the exception to the parent exception frame }
  95. if fc_catching_exceptions in flowcontrol then
  96. begin
  97. currexceptlabel:=tllvmprocinfo(current_procinfo).CurrExceptLabel;
  98. if tllvmprocinfo(current_procinfo).popexceptlabel(currexceptlabel) then
  99. exclude(flowcontrol,fc_catching_exceptions);
  100. end;
  101. hlcg.g_call_system_proc(current_asmdata.CurrAsmList,'fpc_reraise',[],nil).resetiftemp;
  102. if assigned(currexceptlabel) then
  103. begin
  104. tllvmprocinfo(current_procinfo).pushexceptlabel(currexceptlabel);
  105. include(flowcontrol,fc_catching_exceptions);
  106. end;
  107. end;
  108. begin
  109. clabelnode:=tllvmlabelnode;
  110. ctryexceptnode:=tllvmtryexceptnode;
  111. ctryfinallynode:=tllvmtryfinallynode;
  112. craisenode:=tllvmraisenode;
  113. end.