ncgbas.pas 14 KB

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