ncgbas.pas 14 KB

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