ncgbas.pas 16 KB

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