ncgbas.pas 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. {
  2. $Id$
  3. Copyright (c) 2000 by Florian Klaempfl
  4. This unit implements some basic nodes
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. ****************************************************************************
  17. }
  18. unit ncgbas;
  19. {$i defines.inc}
  20. interface
  21. uses
  22. node,nbas;
  23. type
  24. tcgnothingnode = class(tnothingnode)
  25. procedure pass_2;override;
  26. end;
  27. tcgasmnode = class(tasmnode)
  28. procedure pass_2;override;
  29. end;
  30. tcgstatementnode = class(tstatementnode)
  31. procedure pass_2;override;
  32. end;
  33. tcgblocknode = class(tblocknode)
  34. procedure pass_2;override;
  35. end;
  36. tcgtempcreatenode = class(ttempcreatenode)
  37. procedure pass_2;override;
  38. end;
  39. tcgtemprefnode = class(ttemprefnode)
  40. procedure pass_2;override;
  41. end;
  42. tcgtempdeletenode = class(ttempdeletenode)
  43. procedure pass_2;override;
  44. end;
  45. implementation
  46. uses
  47. globtype,systems,
  48. cutils,cclasses,verbose,globals,
  49. aasm,symconst,symsym,symtable,types,
  50. htypechk,
  51. cpubase,cpuasm,
  52. nflw,pass_2
  53. {$ifdef newcg}
  54. ,cgbase
  55. {$else newcg}
  56. ,hcodegen
  57. {$endif}
  58. {$ifdef i386}
  59. ,cgai386
  60. {$endif}
  61. ,tgcpu,temp_gen
  62. ;
  63. {*****************************************************************************
  64. TNOTHING
  65. *****************************************************************************}
  66. procedure tcgnothingnode.pass_2;
  67. begin
  68. { avoid an abstract rte }
  69. end;
  70. {*****************************************************************************
  71. TSTATEMENTNODE
  72. *****************************************************************************}
  73. procedure tcgstatementnode.pass_2;
  74. var
  75. hp : tnode;
  76. begin
  77. hp:=self;
  78. while assigned(hp) do
  79. begin
  80. if assigned(tstatementnode(hp).right) then
  81. begin
  82. cleartempgen;
  83. secondpass(tstatementnode(hp).right);
  84. end;
  85. hp:=tstatementnode(hp).left;
  86. end;
  87. end;
  88. {*****************************************************************************
  89. TASMNODE
  90. *****************************************************************************}
  91. procedure tcgasmnode.pass_2;
  92. procedure ReLabel(var p:tasmsymbol);
  93. begin
  94. if p.proclocal then
  95. begin
  96. if not assigned(p.altsymbol) then
  97. begin
  98. { generatealtsymbol will also increase the refs }
  99. p.GenerateAltSymbol;
  100. UsedAsmSymbolListInsert(p);
  101. end
  102. else
  103. begin
  104. { increase the refs, they will be decreased when the
  105. asmnode is destroyed }
  106. inc(p.refs);
  107. end;
  108. p:=p.altsymbol;
  109. end;
  110. end;
  111. var
  112. hp,hp2 : tai;
  113. localfixup,parafixup,
  114. i : longint;
  115. skipnode : boolean;
  116. begin
  117. if inlining_procedure then
  118. begin
  119. CreateUsedAsmSymbolList;
  120. localfixup:=aktprocsym.definition.localst.address_fixup;
  121. parafixup:=aktprocsym.definition.parast.address_fixup;
  122. hp:=tai(p_asm.first);
  123. while assigned(hp) do
  124. begin
  125. hp2:=tai(hp.getcopy);
  126. skipnode:=false;
  127. case hp2.typ of
  128. ait_label :
  129. begin
  130. { regenerate the labels by setting altsymbol }
  131. ReLabel(tasmsymbol(tai_label(hp2).l));
  132. end;
  133. ait_const_rva,
  134. ait_const_symbol :
  135. begin
  136. ReLabel(tai_const_symbol(hp2).sym);
  137. end;
  138. ait_instruction :
  139. begin
  140. { fixup the references }
  141. for i:=1 to taicpu(hp2).ops do
  142. begin
  143. with taicpu(hp2).oper[i-1] do
  144. begin
  145. case typ of
  146. top_ref :
  147. begin
  148. case ref^.options of
  149. ref_parafixup :
  150. ref^.offsetfixup:=parafixup;
  151. ref_localfixup :
  152. ref^.offsetfixup:=localfixup;
  153. end;
  154. if assigned(ref^.symbol) then
  155. ReLabel(ref^.symbol);
  156. end;
  157. top_symbol :
  158. begin
  159. ReLabel(sym);
  160. end;
  161. end;
  162. end;
  163. end;
  164. end;
  165. ait_marker :
  166. begin
  167. { it's not an assembler block anymore }
  168. if (tai_marker(hp2).kind in [AsmBlockStart, AsmBlockEnd]) then
  169. skipnode:=true;
  170. end;
  171. else
  172. end;
  173. if not skipnode then
  174. exprasmList.concat(hp2)
  175. else
  176. hp2.free;
  177. hp:=tai(hp.next);
  178. end;
  179. { restore used symbols }
  180. UsedAsmSymbolListResetAltSym;
  181. DestroyUsedAsmSymbolList;
  182. end
  183. else
  184. begin
  185. { if the routine is an inline routine, then we must hold a copy
  186. because it can be necessary for inlining later }
  187. if (pocall_inline in aktprocsym.definition.proccalloptions) then
  188. exprasmList.concatlistcopy(p_asm)
  189. else
  190. exprasmList.concatlist(p_asm);
  191. end;
  192. if not (nf_object_preserved in flags) then
  193. maybe_loadself;
  194. end;
  195. {*****************************************************************************
  196. TBLOCKNODE
  197. *****************************************************************************}
  198. procedure tcgblocknode.pass_2;
  199. begin
  200. { do second pass on left node }
  201. if assigned(left) then
  202. secondpass(left);
  203. end;
  204. {*****************************************************************************
  205. TTEMPCREATENODE
  206. *****************************************************************************}
  207. procedure tcgtempcreatenode.pass_2;
  208. begin
  209. { if we're secondpassing the same tcgtempcreatenode twice, we have a bug }
  210. if tempinfo^.valid then
  211. internalerror(200108222);
  212. { get a (persistent) temp }
  213. if persistent then
  214. gettempofsizereferencepersistant(size,tempinfo^.ref)
  215. else
  216. gettempofsizereference(size,tempinfo^.ref);
  217. tempinfo^.valid := true;
  218. end;
  219. {*****************************************************************************
  220. TTEMPREFNODE
  221. *****************************************************************************}
  222. procedure tcgtemprefnode.pass_2;
  223. begin
  224. { check if the temp is valid }
  225. if not tempinfo^.valid then
  226. internalerror(200108231);
  227. { set the temp's location }
  228. location.loc := LOC_REFERENCE;
  229. location.reference := tempinfo^.ref;
  230. end;
  231. {*****************************************************************************
  232. TTEMPDELETENODE
  233. *****************************************************************************}
  234. procedure tcgtempdeletenode.pass_2;
  235. begin
  236. ungetpersistanttempreference(tempinfo^.ref);
  237. end;
  238. begin
  239. cnothingnode:=tcgnothingnode;
  240. casmnode:=tcgasmnode;
  241. cstatementnode:=tcgstatementnode;
  242. cblocknode:=tcgblocknode;
  243. ctempcreatenode:=tcgtempcreatenode;
  244. ctemprefnode:=tcgtemprefnode;
  245. ctempdeletenode:=tcgtempdeletenode;
  246. end.
  247. {
  248. $Log$
  249. Revision 1.6 2001-08-24 13:47:27 jonas
  250. * moved "reverseparameters" from ninl.pas to ncal.pas
  251. + support for non-persistent temps in ttempcreatenode.create, for use
  252. with typeconversion nodes
  253. Revision 1.5 2001/08/23 14:28:35 jonas
  254. + tempcreate/ref/delete nodes (allows the use of temps in the
  255. resulttype and first pass)
  256. * made handling of read(ln)/write(ln) processor independent
  257. * moved processor independent handling for str and reset/rewrite-typed
  258. from firstpass to resulttype pass
  259. * changed names of helpers in text.inc to be generic for use as
  260. compilerprocs + added "iocheck" directive for most of them
  261. * reading of ordinals is done by procedures instead of functions
  262. because otherwise FPC_IOCHECK overwrote the result before it could
  263. be stored elsewhere (range checking still works)
  264. * compilerprocs can now be used in the system unit before they are
  265. implemented
  266. * added note to errore.msg that booleans can't be read using read/readln
  267. Revision 1.4 2001/06/02 19:22:15 peter
  268. * refs count for relabeled asmsymbols fixed
  269. Revision 1.3 2001/05/18 22:31:06 peter
  270. * tasmnode.pass_2 is independent of cpu, moved to ncgbas
  271. * include ncgbas for independent nodes
  272. Revision 1.2 2001/04/13 01:22:08 peter
  273. * symtable change to classes
  274. * range check generation and errors fixed, make cycle DEBUG=1 works
  275. * memory leaks fixed
  276. Revision 1.1 2000/10/14 10:14:50 peter
  277. * moehrendorf oct 2000 rewrite
  278. }