ncgbas.pas 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470
  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,cginfo,cgobj,tgobj,rgobj
  53. ;
  54. {*****************************************************************************
  55. TNOTHING
  56. *****************************************************************************}
  57. procedure tcgnothingnode.pass_2;
  58. begin
  59. location_reset(location,LOC_VOID,OS_NO);
  60. { avoid an abstract rte }
  61. end;
  62. {*****************************************************************************
  63. TSTATEMENTNODE
  64. *****************************************************************************}
  65. procedure tcgstatementnode.pass_2;
  66. var
  67. hp : tstatementnode;
  68. begin
  69. location_reset(location,LOC_VOID,OS_NO);
  70. hp:=self;
  71. while assigned(hp) do
  72. begin
  73. if assigned(hp.left) then
  74. begin
  75. {$ifndef newra}
  76. rg.cleartempgen;
  77. {$endif newra}
  78. secondpass(hp.left);
  79. { Compiler inserted blocks can return values }
  80. location_copy(hp.location,hp.left.location);
  81. end;
  82. hp:=tstatementnode(hp.right);
  83. end;
  84. end;
  85. {*****************************************************************************
  86. TASMNODE
  87. *****************************************************************************}
  88. procedure tcgasmnode.pass_2;
  89. procedure ReLabel(var p:tasmsymbol);
  90. begin
  91. { Only relabel local tasmlabels }
  92. if (p.defbind = AB_LOCAL) and
  93. (p is tasmlabel) then
  94. begin
  95. if not assigned(p.altsymbol) then
  96. objectlibrary.GenerateAltSymbol(p);
  97. p:=p.altsymbol;
  98. p.increfs;
  99. end;
  100. end;
  101. var
  102. hp,hp2 : tai;
  103. localfixup,parafixup,
  104. i : longint;
  105. skipnode : boolean;
  106. begin
  107. location_reset(location,LOC_VOID,OS_NO);
  108. if getposition then
  109. begin
  110. currenttai:=tai(exprasmlist.last);
  111. exit;
  112. end;
  113. if inlining_procedure then
  114. begin
  115. objectlibrary.CreateUsedAsmSymbolList;
  116. localfixup:=current_procinfo.procdef.localst.address_fixup;
  117. parafixup:=current_procinfo.procdef.parast.address_fixup;
  118. hp:=tai(p_asm.first);
  119. while assigned(hp) do
  120. begin
  121. hp2:=tai(hp.getcopy);
  122. skipnode:=false;
  123. case hp2.typ of
  124. ait_label :
  125. begin
  126. { regenerate the labels by setting altsymbol }
  127. ReLabel(tasmsymbol(tai_label(hp2).l));
  128. end;
  129. ait_const_rva,
  130. ait_const_symbol :
  131. begin
  132. ReLabel(tai_const_symbol(hp2).sym);
  133. end;
  134. ait_instruction :
  135. begin
  136. { remove cached insentry, because the new code can
  137. require an other less optimized instruction }
  138. {$ifdef i386}
  139. {$ifndef NOAG386BIN}
  140. taicpu(hp2).ResetPass1;
  141. {$endif}
  142. {$endif}
  143. { fixup the references }
  144. for i:=1 to taicpu(hp2).ops do
  145. begin
  146. with taicpu(hp2).oper[i-1] do
  147. begin
  148. case typ of
  149. top_ref :
  150. begin
  151. case ref^.options of
  152. ref_parafixup :
  153. ref^.offsetfixup:=parafixup;
  154. ref_localfixup :
  155. ref^.offsetfixup:=localfixup;
  156. end;
  157. if assigned(ref^.symbol) then
  158. ReLabel(ref^.symbol);
  159. end;
  160. top_symbol :
  161. begin
  162. ReLabel(sym);
  163. end;
  164. end;
  165. end;
  166. end;
  167. end;
  168. ait_marker :
  169. begin
  170. { it's not an assembler block anymore }
  171. if (tai_marker(hp2).kind in [AsmBlockStart, AsmBlockEnd]) then
  172. skipnode:=true;
  173. end;
  174. else
  175. end;
  176. if not skipnode then
  177. exprasmList.concat(hp2)
  178. else
  179. hp2.free;
  180. hp:=tai(hp.next);
  181. end;
  182. { restore used symbols }
  183. objectlibrary.UsedAsmSymbolListResetAltSym;
  184. objectlibrary.DestroyUsedAsmSymbolList;
  185. end
  186. else
  187. begin
  188. { if the routine is an inline routine, then we must hold a copy
  189. because it can be necessary for inlining later }
  190. if (current_procinfo.procdef.proccalloption=pocall_inline) then
  191. exprasmList.concatlistcopy(p_asm)
  192. else
  193. exprasmList.concatlist(p_asm);
  194. end;
  195. end;
  196. {*****************************************************************************
  197. TBLOCKNODE
  198. *****************************************************************************}
  199. procedure tcgblocknode.pass_2;
  200. var
  201. hp : tstatementnode;
  202. begin
  203. location_reset(location,LOC_VOID,OS_NO);
  204. { do second pass on left node }
  205. if assigned(left) then
  206. begin
  207. hp:=tstatementnode(left);
  208. while assigned(hp) do
  209. begin
  210. if assigned(hp.left) then
  211. begin
  212. {$ifndef newra}
  213. if nf_releasetemps in flags then
  214. rg.cleartempgen;
  215. {$endif newra}
  216. secondpass(hp.left);
  217. location_copy(hp.location,hp.left.location);
  218. end;
  219. location_copy(location,hp.location);
  220. hp:=tstatementnode(hp.right);
  221. end;
  222. end;
  223. end;
  224. {*****************************************************************************
  225. TTEMPCREATENODE
  226. *****************************************************************************}
  227. procedure tcgtempcreatenode.pass_2;
  228. begin
  229. location_reset(location,LOC_VOID,OS_NO);
  230. { if we're secondpassing the same tcgtempcreatenode twice, we have a bug }
  231. if tempinfo^.valid then
  232. internalerror(200108222);
  233. { get a (persistent) temp }
  234. tg.GetTemp(exprasmlist,size,tempinfo^.temptype,tempinfo^.ref);
  235. tempinfo^.valid := true;
  236. end;
  237. {*****************************************************************************
  238. TTEMPREFNODE
  239. *****************************************************************************}
  240. procedure tcgtemprefnode.pass_2;
  241. begin
  242. { check if the temp is valid }
  243. if not tempinfo^.valid then
  244. internalerror(200108231);
  245. { set the temp's location }
  246. location_reset(location,LOC_REFERENCE,def_cgsize(tempinfo^.restype.def));
  247. location.reference := tempinfo^.ref;
  248. inc(location.reference.offset,offset);
  249. end;
  250. {*****************************************************************************
  251. TTEMPDELETENODE
  252. *****************************************************************************}
  253. procedure tcgtempdeletenode.pass_2;
  254. begin
  255. location_reset(location,LOC_VOID,OS_NO);
  256. if release_to_normal then
  257. tg.ChangeTempType(exprasmlist,tempinfo^.ref,tt_normal)
  258. else
  259. tg.UnGetTemp(exprasmlist,tempinfo^.ref);
  260. end;
  261. begin
  262. cnothingnode:=tcgnothingnode;
  263. casmnode:=tcgasmnode;
  264. cstatementnode:=tcgstatementnode;
  265. cblocknode:=tcgblocknode;
  266. ctempcreatenode:=tcgtempcreatenode;
  267. ctemprefnode:=tcgtemprefnode;
  268. ctempdeletenode:=tcgtempdeletenode;
  269. end.
  270. {
  271. $Log$
  272. Revision 1.37 2003-06-13 21:19:30 peter
  273. * current_procdef removed, use current_procinfo.procdef instead
  274. Revision 1.36 2003/06/09 18:26:46 peter
  275. * remove temptype, use tempinfo.temptype instead
  276. Revision 1.35 2003/06/09 12:20:47 peter
  277. * getposition added to retrieve the the current tai item
  278. Revision 1.34 2003/05/17 13:30:08 jonas
  279. * changed tt_persistant to tt_persistent :)
  280. * tempcreatenode now doesn't accept a boolean anymore for persistent
  281. temps, but a ttemptype, so you can also create ansistring temps etc
  282. Revision 1.33 2003/04/27 11:21:33 peter
  283. * aktprocdef renamed to current_procinfo.procdef
  284. * procinfo renamed to current_procinfo
  285. * procinfo will now be stored in current_module so it can be
  286. cleaned up properly
  287. * gen_main_procsym changed to create_main_proc and release_main_proc
  288. to also generate a tprocinfo structure
  289. * fixed unit implicit initfinal
  290. Revision 1.32 2002/04/25 20:15:39 florian
  291. * block nodes within expressions shouldn't release the used registers,
  292. fixed using a flag till the new rg is ready
  293. Revision 1.31 2003/04/22 23:50:22 peter
  294. * firstpass uses expectloc
  295. * checks if there are differences between the expectloc and
  296. location.loc from secondpass in EXTDEBUG
  297. Revision 1.30 2003/04/17 07:50:24 daniel
  298. * Some work on interference graph construction
  299. Revision 1.29 2003/03/28 19:16:56 peter
  300. * generic constructor working for i386
  301. * remove fixed self register
  302. * esi added as address register for i386
  303. Revision 1.28 2002/11/27 15:33:19 peter
  304. * fixed relabeling to relabel only tasmlabel (formerly proclocal)
  305. Revision 1.27 2002/11/27 02:37:13 peter
  306. * case statement inlining added
  307. * fixed inlining of write()
  308. * switched statementnode left and right parts so the statements are
  309. processed in the correct order when getcopy is used. This is
  310. required for tempnodes
  311. Revision 1.26 2002/11/17 16:31:56 carl
  312. * memory optimization (3-4%) : cleanup of tai fields,
  313. cleanup of tdef and tsym fields.
  314. * make it work for m68k
  315. Revision 1.25 2002/11/15 16:29:30 peter
  316. * made tasmsymbol.refs private (merged)
  317. Revision 1.24 2002/11/15 01:58:51 peter
  318. * merged changes from 1.0.7 up to 04-11
  319. - -V option for generating bug report tracing
  320. - more tracing for option parsing
  321. - errors for cdecl and high()
  322. - win32 import stabs
  323. - win32 records<=8 are returned in eax:edx (turned off by default)
  324. - heaptrc update
  325. - more info for temp management in .s file with EXTDEBUG
  326. Revision 1.23 2002/08/23 16:14:48 peter
  327. * tempgen cleanup
  328. * tt_noreuse temp type added that will be used in genentrycode
  329. Revision 1.22 2002/08/11 14:32:26 peter
  330. * renamed current_library to objectlibrary
  331. Revision 1.21 2002/08/11 13:24:11 peter
  332. * saving of asmsymbols in ppu supported
  333. * asmsymbollist global is removed and moved into a new class
  334. tasmlibrarydata that will hold the info of a .a file which
  335. corresponds with a single module. Added librarydata to tmodule
  336. to keep the library info stored for the module. In the future the
  337. objectfiles will also be stored to the tasmlibrarydata class
  338. * all getlabel/newasmsymbol and friends are moved to the new class
  339. Revision 1.20 2002/07/01 18:46:22 peter
  340. * internal linker
  341. * reorganized aasm layer
  342. Revision 1.19 2002/05/18 13:34:09 peter
  343. * readded missing revisions
  344. Revision 1.18 2002/05/16 19:46:37 carl
  345. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  346. + try to fix temp allocation (still in ifdef)
  347. + generic constructor calls
  348. + start of tassembler / tmodulebase class cleanup
  349. Revision 1.16 2002/05/13 19:54:37 peter
  350. * removed n386ld and n386util units
  351. * maybe_save/maybe_restore added instead of the old maybe_push
  352. Revision 1.15 2002/05/12 16:53:07 peter
  353. * moved entry and exitcode to ncgutil and cgobj
  354. * foreach gets extra argument for passing local data to the
  355. iterator function
  356. * -CR checks also class typecasts at runtime by changing them
  357. into as
  358. * fixed compiler to cycle with the -CR option
  359. * fixed stabs with elf writer, finally the global variables can
  360. be watched
  361. * removed a lot of routines from cga unit and replaced them by
  362. calls to cgobj
  363. * u32bit-s32bit updates for and,or,xor nodes. When one element is
  364. u32bit then the other is typecasted also to u32bit without giving
  365. a rangecheck warning/error.
  366. * fixed pascal calling method with reversing also the high tree in
  367. the parast, detected by tcalcst3 test
  368. Revision 1.14 2002/04/23 19:16:34 peter
  369. * add pinline unit that inserts compiler supported functions using
  370. one or more statements
  371. * moved finalize and setlength from ninl to pinline
  372. Revision 1.13 2002/04/21 19:02:03 peter
  373. * removed newn and disposen nodes, the code is now directly
  374. inlined from pexpr
  375. * -an option that will write the secondpass nodes to the .s file, this
  376. requires EXTDEBUG define to actually write the info
  377. * fixed various internal errors and crashes due recent code changes
  378. Revision 1.12 2002/04/04 19:05:57 peter
  379. * removed unused units
  380. * use tlocation.size in cg.a_*loc*() routines
  381. Revision 1.11 2002/03/31 20:26:34 jonas
  382. + a_loadfpu_* and a_loadmm_* methods in tcg
  383. * register allocation is now handled by a class and is mostly processor
  384. independent (+rgobj.pas and i386/rgcpu.pas)
  385. * temp allocation is now handled by a class (+tgobj.pas, -i386\tgcpu.pas)
  386. * some small improvements and fixes to the optimizer
  387. * some register allocation fixes
  388. * some fpuvaroffset fixes in the unary minus node
  389. * push/popusedregisters is now called rg.save/restoreusedregisters and
  390. (for i386) uses temps instead of push/pop's when using -Op3 (that code is
  391. also better optimizable)
  392. * fixed and optimized register saving/restoring for new/dispose nodes
  393. * LOC_FPU locations now also require their "register" field to be set to
  394. R_ST, not R_ST0 (the latter is used for LOC_CFPUREGISTER locations only)
  395. - list field removed of the tnode class because it's not used currently
  396. and can cause hard-to-find bugs
  397. }