ncgbas.pas 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382
  1. {
  2. $Id$
  3. Copyright (c) 2000-2002 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 fpcdefs.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,verbose,globals,
  49. aasmbase,aasmtai,aasmcpu,symsym,
  50. cpubase,
  51. nflw,pass_2,
  52. cgbase,cgobj,tgobj,rgobj
  53. ;
  54. {*****************************************************************************
  55. TNOTHING
  56. *****************************************************************************}
  57. procedure tcgnothingnode.pass_2;
  58. begin
  59. { avoid an abstract rte }
  60. end;
  61. {*****************************************************************************
  62. TSTATEMENTNODE
  63. *****************************************************************************}
  64. procedure tcgstatementnode.pass_2;
  65. var
  66. hp : tnode;
  67. begin
  68. hp:=self;
  69. while assigned(hp) do
  70. begin
  71. if assigned(tstatementnode(hp).right) then
  72. begin
  73. rg.cleartempgen;
  74. secondpass(tstatementnode(hp).right);
  75. { Compiler inserted blocks can return values }
  76. location_copy(location,tstatementnode(hp).right.location);
  77. end;
  78. hp:=tstatementnode(hp).left;
  79. end;
  80. end;
  81. {*****************************************************************************
  82. TASMNODE
  83. *****************************************************************************}
  84. procedure tcgasmnode.pass_2;
  85. procedure ReLabel(var p:tasmsymbol);
  86. begin
  87. if p.proclocal then
  88. begin
  89. if not assigned(p.altsymbol) then
  90. begin
  91. { generatealtsymbol will also increase the refs }
  92. objectlibrary.GenerateAltSymbol(p);
  93. end
  94. else
  95. begin
  96. { increase the refs, they will be decreased when the
  97. asmnode is destroyed }
  98. inc(p.refs);
  99. end;
  100. p:=p.altsymbol;
  101. end;
  102. end;
  103. var
  104. hp,hp2 : tai;
  105. localfixup,parafixup,
  106. i : longint;
  107. skipnode : boolean;
  108. begin
  109. if inlining_procedure then
  110. begin
  111. objectlibrary.CreateUsedAsmSymbolList;
  112. localfixup:=aktprocdef.localst.address_fixup;
  113. parafixup:=aktprocdef.parast.address_fixup;
  114. hp:=tai(p_asm.first);
  115. while assigned(hp) do
  116. begin
  117. hp2:=tai(hp.getcopy);
  118. skipnode:=false;
  119. case hp2.typ of
  120. ait_label :
  121. begin
  122. { regenerate the labels by setting altsymbol }
  123. ReLabel(tasmsymbol(tai_label(hp2).l));
  124. end;
  125. ait_const_rva,
  126. ait_const_symbol :
  127. begin
  128. ReLabel(tai_const_symbol(hp2).sym);
  129. end;
  130. ait_instruction :
  131. begin
  132. { remove cached insentry, because the new code can
  133. require an other less optimized instruction }
  134. {$ifdef i386}
  135. {$ifndef NOAG386BIN}
  136. taicpu(hp2).ResetPass1;
  137. {$endif}
  138. {$endif}
  139. { fixup the references }
  140. for i:=1 to taicpu(hp2).ops do
  141. begin
  142. with taicpu(hp2).oper[i-1] do
  143. begin
  144. case typ of
  145. top_ref :
  146. begin
  147. case ref^.options of
  148. ref_parafixup :
  149. ref^.offsetfixup:=parafixup;
  150. ref_localfixup :
  151. ref^.offsetfixup:=localfixup;
  152. end;
  153. if assigned(ref^.symbol) then
  154. ReLabel(ref^.symbol);
  155. end;
  156. top_symbol :
  157. begin
  158. ReLabel(sym);
  159. end;
  160. end;
  161. end;
  162. end;
  163. end;
  164. ait_marker :
  165. begin
  166. { it's not an assembler block anymore }
  167. if (tai_marker(hp2).kind in [AsmBlockStart, AsmBlockEnd]) then
  168. skipnode:=true;
  169. end;
  170. else
  171. end;
  172. if not skipnode then
  173. exprasmList.concat(hp2)
  174. else
  175. hp2.free;
  176. hp:=tai(hp.next);
  177. end;
  178. { restore used symbols }
  179. objectlibrary.UsedAsmSymbolListResetAltSym;
  180. objectlibrary.DestroyUsedAsmSymbolList;
  181. end
  182. else
  183. begin
  184. { if the routine is an inline routine, then we must hold a copy
  185. because it can be necessary for inlining later }
  186. if (aktprocdef.proccalloption=pocall_inline) then
  187. exprasmList.concatlistcopy(p_asm)
  188. else
  189. exprasmList.concatlist(p_asm);
  190. end;
  191. if not (nf_object_preserved in flags) then
  192. cg.g_maybe_loadself(exprasmlist);
  193. end;
  194. {*****************************************************************************
  195. TBLOCKNODE
  196. *****************************************************************************}
  197. procedure tcgblocknode.pass_2;
  198. begin
  199. { do second pass on left node }
  200. if assigned(left) then
  201. begin
  202. secondpass(left);
  203. { Compiler inserted blocks can return values }
  204. location_copy(location,left.location);
  205. end;
  206. end;
  207. {*****************************************************************************
  208. TTEMPCREATENODE
  209. *****************************************************************************}
  210. procedure tcgtempcreatenode.pass_2;
  211. var
  212. temptype : ttemptype;
  213. begin
  214. { if we're secondpassing the same tcgtempcreatenode twice, we have a bug }
  215. if tempinfo^.valid then
  216. internalerror(200108222);
  217. { get a (persistent) temp }
  218. if persistent then
  219. temptype:=tt_persistant
  220. else
  221. temptype:=tt_normal;
  222. tg.GetTemp(exprasmlist,size,temptype,tempinfo^.ref);
  223. tempinfo^.valid := true;
  224. end;
  225. {*****************************************************************************
  226. TTEMPREFNODE
  227. *****************************************************************************}
  228. procedure tcgtemprefnode.pass_2;
  229. begin
  230. { check if the temp is valid }
  231. if not tempinfo^.valid then
  232. internalerror(200108231);
  233. { set the temp's location }
  234. location_reset(location,LOC_REFERENCE,def_cgsize(tempinfo^.restype.def));
  235. location.reference := tempinfo^.ref;
  236. inc(location.reference.offset,offset);
  237. end;
  238. {*****************************************************************************
  239. TTEMPDELETENODE
  240. *****************************************************************************}
  241. procedure tcgtempdeletenode.pass_2;
  242. begin
  243. if release_to_normal then
  244. tg.ChangeTempType(tempinfo^.ref,tt_normal)
  245. else
  246. tg.UnGetTemp(exprasmlist,tempinfo^.ref);
  247. end;
  248. begin
  249. cnothingnode:=tcgnothingnode;
  250. casmnode:=tcgasmnode;
  251. cstatementnode:=tcgstatementnode;
  252. cblocknode:=tcgblocknode;
  253. ctempcreatenode:=tcgtempcreatenode;
  254. ctemprefnode:=tcgtemprefnode;
  255. ctempdeletenode:=tcgtempdeletenode;
  256. end.
  257. {
  258. $Log$
  259. Revision 1.23 2002-08-23 16:14:48 peter
  260. * tempgen cleanup
  261. * tt_noreuse temp type added that will be used in genentrycode
  262. Revision 1.22 2002/08/11 14:32:26 peter
  263. * renamed current_library to objectlibrary
  264. Revision 1.21 2002/08/11 13:24:11 peter
  265. * saving of asmsymbols in ppu supported
  266. * asmsymbollist global is removed and moved into a new class
  267. tasmlibrarydata that will hold the info of a .a file which
  268. corresponds with a single module. Added librarydata to tmodule
  269. to keep the library info stored for the module. In the future the
  270. objectfiles will also be stored to the tasmlibrarydata class
  271. * all getlabel/newasmsymbol and friends are moved to the new class
  272. Revision 1.20 2002/07/01 18:46:22 peter
  273. * internal linker
  274. * reorganized aasm layer
  275. Revision 1.19 2002/05/18 13:34:09 peter
  276. * readded missing revisions
  277. Revision 1.18 2002/05/16 19:46:37 carl
  278. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  279. + try to fix temp allocation (still in ifdef)
  280. + generic constructor calls
  281. + start of tassembler / tmodulebase class cleanup
  282. Revision 1.16 2002/05/13 19:54:37 peter
  283. * removed n386ld and n386util units
  284. * maybe_save/maybe_restore added instead of the old maybe_push
  285. Revision 1.15 2002/05/12 16:53:07 peter
  286. * moved entry and exitcode to ncgutil and cgobj
  287. * foreach gets extra argument for passing local data to the
  288. iterator function
  289. * -CR checks also class typecasts at runtime by changing them
  290. into as
  291. * fixed compiler to cycle with the -CR option
  292. * fixed stabs with elf writer, finally the global variables can
  293. be watched
  294. * removed a lot of routines from cga unit and replaced them by
  295. calls to cgobj
  296. * u32bit-s32bit updates for and,or,xor nodes. When one element is
  297. u32bit then the other is typecasted also to u32bit without giving
  298. a rangecheck warning/error.
  299. * fixed pascal calling method with reversing also the high tree in
  300. the parast, detected by tcalcst3 test
  301. Revision 1.14 2002/04/23 19:16:34 peter
  302. * add pinline unit that inserts compiler supported functions using
  303. one or more statements
  304. * moved finalize and setlength from ninl to pinline
  305. Revision 1.13 2002/04/21 19:02:03 peter
  306. * removed newn and disposen nodes, the code is now directly
  307. inlined from pexpr
  308. * -an option that will write the secondpass nodes to the .s file, this
  309. requires EXTDEBUG define to actually write the info
  310. * fixed various internal errors and crashes due recent code changes
  311. Revision 1.12 2002/04/04 19:05:57 peter
  312. * removed unused units
  313. * use tlocation.size in cg.a_*loc*() routines
  314. Revision 1.11 2002/03/31 20:26:34 jonas
  315. + a_loadfpu_* and a_loadmm_* methods in tcg
  316. * register allocation is now handled by a class and is mostly processor
  317. independent (+rgobj.pas and i386/rgcpu.pas)
  318. * temp allocation is now handled by a class (+tgobj.pas, -i386\tgcpu.pas)
  319. * some small improvements and fixes to the optimizer
  320. * some register allocation fixes
  321. * some fpuvaroffset fixes in the unary minus node
  322. * push/popusedregisters is now called rg.save/restoreusedregisters and
  323. (for i386) uses temps instead of push/pop's when using -Op3 (that code is
  324. also better optimizable)
  325. * fixed and optimized register saving/restoring for new/dispose nodes
  326. * LOC_FPU locations now also require their "register" field to be set to
  327. R_ST, not R_ST0 (the latter is used for LOC_CFPUREGISTER locations only)
  328. - list field removed of the tnode class because it's not used currently
  329. and can cause hard-to-find bugs
  330. }