ncgmem.pas 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 by Florian Klaempfl
  4. Generate assembler for memory related nodes which are
  5. the same for all (most?) processors
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2 of the License, or
  9. (at your option) any later version.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with this program; if not, write to the Free Software
  16. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. ****************************************************************************
  18. }
  19. { This unit generate assembler for memory related nodes.
  20. }
  21. unit ncgmem;
  22. {$i fpcdefs.inc}
  23. interface
  24. uses
  25. cgbase,cpuinfo,cpubase,
  26. node,nmem;
  27. type
  28. tcgloadvmtaddrnode = class(tloadvmtaddrnode)
  29. procedure pass_2;override;
  30. end;
  31. tcgloadparentfpnode = class(tloadparentfpnode)
  32. procedure pass_2;override;
  33. end;
  34. tcgaddrnode = class(taddrnode)
  35. procedure pass_2;override;
  36. end;
  37. tcgderefnode = class(tderefnode)
  38. procedure pass_2;override;
  39. end;
  40. tcgsubscriptnode = class(tsubscriptnode)
  41. procedure pass_2;override;
  42. end;
  43. tcgwithnode = class(twithnode)
  44. procedure pass_2;override;
  45. end;
  46. tcgvecnode = class(tvecnode)
  47. private
  48. procedure rangecheck_array;
  49. protected
  50. function get_mul_size : longint;
  51. {# This routine is used to calculate the address of the reference.
  52. On entry reg contains the index in the array,
  53. and l contains the size of each element in the array.
  54. This routine should update location.reference correctly,
  55. so it points to the correct address.
  56. }
  57. procedure update_reference_reg_mul(reg:tregister;l:aword);virtual;
  58. procedure second_wideansistring;virtual;
  59. procedure second_dynamicarray;virtual;
  60. public
  61. procedure pass_2;override;
  62. end;
  63. implementation
  64. uses
  65. {$ifdef delphi}
  66. sysutils,
  67. {$else}
  68. strings,
  69. {$endif}
  70. {$ifdef GDB}
  71. gdb,
  72. {$endif GDB}
  73. globtype,systems,
  74. cutils,verbose,globals,
  75. symconst,symdef,symsym,defutil,paramgr,
  76. aasmbase,aasmtai,
  77. procinfo,pass_2,
  78. pass_1,nld,ncon,nadd,
  79. cgobj,tgobj,ncgutil,symbase
  80. ;
  81. {*****************************************************************************
  82. TCGLOADVMTADDRNODE
  83. *****************************************************************************}
  84. procedure tcgloadvmtaddrnode.pass_2;
  85. var
  86. href : treference;
  87. begin
  88. location_reset(location,LOC_REGISTER,OS_ADDR);
  89. if (left.nodetype<>typen) then
  90. begin
  91. { left contains self, load vmt from self }
  92. secondpass(left);
  93. if is_object(left.resulttype.def) then
  94. begin
  95. case left.location.loc of
  96. LOC_CREFERENCE,
  97. LOC_REFERENCE:
  98. begin
  99. location_release(exprasmlist,left.location);
  100. reference_reset_base(href,cg.getaddressregister(exprasmlist),tobjectdef(left.resulttype.def).vmt_offset);
  101. cg.a_loadaddr_ref_reg(exprasmlist,left.location.reference,href.base);
  102. end;
  103. else
  104. internalerror(200305056);
  105. end;
  106. end
  107. else
  108. begin
  109. case left.location.loc of
  110. LOC_REGISTER:
  111. begin
  112. {$ifdef cpu_uses_separate_address_registers}
  113. if getregtype(left.location.register)<>R_ADDRESSREGISTER then
  114. begin
  115. location_release(exprasmlist,left.location);
  116. reference_reset_base(href,cg.getaddressregister(exprasmlist),tobjectdef(left.resulttype.def).vmt_offset);
  117. cg.a_load_reg_reg(exprasmlist,OS_ADDR,OS_ADDR,left.location.register,href.base);
  118. end
  119. else
  120. {$endif}
  121. reference_reset_base(href,left.location.register,tobjectdef(left.resulttype.def).vmt_offset);
  122. end;
  123. LOC_CREGISTER,
  124. LOC_CREFERENCE,
  125. LOC_REFERENCE:
  126. begin
  127. location_release(exprasmlist,left.location);
  128. reference_reset_base(href,cg.getaddressregister(exprasmlist),tobjectdef(left.resulttype.def).vmt_offset);
  129. cg.a_load_loc_reg(exprasmlist,OS_ADDR,left.location,href.base);
  130. end;
  131. else
  132. internalerror(200305057);
  133. end;
  134. end;
  135. reference_release(exprasmlist,href);
  136. location.register:=cg.getaddressregister(exprasmlist);
  137. cg.g_maybe_testself(exprasmlist,href.base);
  138. cg.a_load_ref_reg(exprasmlist,OS_ADDR,OS_ADDR,href,location.register);
  139. end
  140. else
  141. begin
  142. reference_reset_symbol(href,
  143. objectlibrary.newasmsymboldata(tobjectdef(tclassrefdef(resulttype.def).pointertype.def).vmt_mangledname),0);
  144. location.register:=cg.getaddressregister(exprasmlist);
  145. cg.a_loadaddr_ref_reg(exprasmlist,href,location.register);
  146. end;
  147. end;
  148. {*****************************************************************************
  149. TCGLOADPARENTFPNODE
  150. *****************************************************************************}
  151. procedure tcgloadparentfpnode.pass_2;
  152. var
  153. currpi : tprocinfo;
  154. hsym : tvarsym;
  155. href : treference;
  156. begin
  157. if (current_procinfo.procdef.parast.symtablelevel=parentpd.parast.symtablelevel) then
  158. begin
  159. location_reset(location,LOC_REGISTER,OS_ADDR);
  160. location.register:=current_procinfo.framepointer;
  161. end
  162. else
  163. begin
  164. currpi:=current_procinfo;
  165. location_reset(location,LOC_REGISTER,OS_ADDR);
  166. location.register:=cg.getaddressregister(exprasmlist);
  167. { load framepointer of current proc }
  168. hsym:=tvarsym(currpi.procdef.parast.search('parentfp'));
  169. if not assigned(hsym) then
  170. internalerror(200309281);
  171. case hsym.localloc.loc of
  172. LOC_REFERENCE :
  173. begin
  174. reference_reset_base(href,hsym.localloc.reference.index,hsym.localloc.reference.offset);
  175. cg.a_load_ref_reg(exprasmlist,OS_ADDR,OS_ADDR,href,location.register);
  176. end;
  177. LOC_REGISTER :
  178. cg.a_load_reg_reg(exprasmlist,OS_ADDR,OS_ADDR,hsym.localloc.register,location.register);
  179. end;
  180. { walk parents }
  181. while (currpi.procdef.owner.symtablelevel>parentpd.parast.symtablelevel) do
  182. begin
  183. hsym:=tvarsym(currpi.procdef.parast.search('parentfp'));
  184. if not assigned(hsym) then
  185. internalerror(200309282);
  186. if hsym.localloc.loc<>LOC_REFERENCE then
  187. internalerror(200309283);
  188. reference_reset_base(href,location.register,hsym.localloc.reference.offset);
  189. cg.a_load_ref_reg(exprasmlist,OS_ADDR,OS_ADDR,href,location.register);
  190. currpi:=currpi.parent;
  191. end;
  192. end;
  193. end;
  194. {*****************************************************************************
  195. TCGADDRNODE
  196. *****************************************************************************}
  197. procedure tcgaddrnode.pass_2;
  198. begin
  199. secondpass(left);
  200. { when loading procvar we do nothing with this node, so load the
  201. location of left }
  202. if nf_procvarload in flags then
  203. begin
  204. location_copy(location,left.location);
  205. exit;
  206. end;
  207. location_release(exprasmlist,left.location);
  208. location_reset(location,LOC_REGISTER,OS_ADDR);
  209. location.register:=cg.getaddressregister(exprasmlist);
  210. { @ on a procvar means returning an address to the procedure that
  211. is stored in it }
  212. if (m_tp_procvar in aktmodeswitches) and
  213. (left.nodetype=loadn) and
  214. (tloadnode(left).resulttype.def.deftype=procvardef) and
  215. assigned(tloadnode(left).symtableentry) and
  216. (tloadnode(left).symtableentry.typ=varsym) then
  217. cg.a_load_ref_reg(exprasmlist,OS_ADDR,OS_ADDR,left.location.reference,location.register)
  218. else
  219. cg.a_loadaddr_ref_reg(exprasmlist,left.location.reference,location.register);
  220. end;
  221. {*****************************************************************************
  222. TCGDEREFNODE
  223. *****************************************************************************}
  224. procedure tcgderefnode.pass_2;
  225. var
  226. paraloc1 : tparalocation;
  227. begin
  228. secondpass(left);
  229. location_reset(location,LOC_REFERENCE,def_cgsize(resulttype.def));
  230. case left.location.loc of
  231. LOC_REGISTER:
  232. begin
  233. {$ifdef cpu_uses_separate_address_registers}
  234. if getregtype(left.location.register)<>R_ADDRESSREGISTER then
  235. begin
  236. location_release(exprasmlist,left.location);
  237. location.reference.base := cg.getaddressregister(exprasmlist);
  238. cg.a_load_reg_reg(exprasmlist,OS_ADDR,OS_ADDR,left.location.register,
  239. location.reference.base);
  240. end
  241. else
  242. {$endif}
  243. location.reference.base := left.location.register;
  244. end;
  245. LOC_CREGISTER,
  246. LOC_CREFERENCE,
  247. LOC_REFERENCE:
  248. begin
  249. location_release(exprasmlist,left.location);
  250. location.reference.base:=cg.getaddressregister(exprasmlist);
  251. cg.a_load_loc_reg(exprasmlist,OS_ADDR,left.location,location.reference.base);
  252. end;
  253. end;
  254. if (cs_gdb_heaptrc in aktglobalswitches) and
  255. (cs_checkpointer in aktglobalswitches) and
  256. not(cs_compilesystem in aktmoduleswitches) and
  257. (not tpointerdef(left.resulttype.def).is_far) then
  258. begin
  259. paraloc1:=paramanager.getintparaloc(pocall_default,1);
  260. paramanager.allocparaloc(exprasmlist,paraloc1);
  261. cg.a_param_reg(exprasmlist, OS_ADDR,location.reference.base,paraloc1);
  262. paramanager.freeparaloc(exprasmlist,paraloc1);
  263. { FPC_CHECKPOINTER uses saveregisters }
  264. cg.a_call_name(exprasmlist,'FPC_CHECKPOINTER');
  265. end;
  266. end;
  267. {*****************************************************************************
  268. TCGSUBSCRIPTNODE
  269. *****************************************************************************}
  270. procedure tcgsubscriptnode.pass_2;
  271. var
  272. paraloc1 : tparalocation;
  273. begin
  274. secondpass(left);
  275. if codegenerror then
  276. exit;
  277. { classes and interfaces must be dereferenced implicit }
  278. if is_class_or_interface(left.resulttype.def) then
  279. begin
  280. location_reset(location,LOC_REFERENCE,def_cgsize(resulttype.def));
  281. case left.location.loc of
  282. LOC_CREGISTER,
  283. LOC_REGISTER:
  284. begin
  285. {$ifdef cpu_uses_separate_address_registers}
  286. if getregtype(left.location.register)<>R_ADDRESSREGISTER then
  287. begin
  288. location_release(exprasmlist,left.location);
  289. location.reference.base:=rg.getaddressregister(exprasmlist);
  290. cg.a_load_reg_reg(exprasmlist,OS_ADDR,OS_ADDR,
  291. left.location.register,location.reference.base);
  292. end
  293. else
  294. {$endif}
  295. location.reference.base := left.location.register;
  296. end;
  297. LOC_CREFERENCE,
  298. LOC_REFERENCE:
  299. begin
  300. location_release(exprasmlist,left.location);
  301. location.reference.base:=cg.getaddressregister(exprasmlist);
  302. cg.a_load_loc_reg(exprasmlist,OS_ADDR,left.location,location.reference.base);
  303. end;
  304. end;
  305. { implicit deferencing }
  306. if (cs_gdb_heaptrc in aktglobalswitches) and
  307. (cs_checkpointer in aktglobalswitches) and
  308. not(cs_compilesystem in aktmoduleswitches) then
  309. begin
  310. paraloc1:=paramanager.getintparaloc(pocall_default,1);
  311. paramanager.allocparaloc(exprasmlist,paraloc1);
  312. cg.a_param_reg(exprasmlist, OS_ADDR,location.reference.base,paraloc1);
  313. paramanager.freeparaloc(exprasmlist,paraloc1);
  314. { FPC_CHECKPOINTER uses saveregisters }
  315. cg.a_call_name(exprasmlist,'FPC_CHECKPOINTER');
  316. end;
  317. end
  318. else if is_interfacecom(left.resulttype.def) then
  319. begin
  320. tg.GetTempTyped(exprasmlist,left.resulttype.def,tt_normal,location.reference);
  321. cg.a_load_loc_ref(exprasmlist,OS_ADDR,left.location,location.reference);
  322. { implicit deferencing also for interfaces }
  323. if (cs_gdb_heaptrc in aktglobalswitches) and
  324. (cs_checkpointer in aktglobalswitches) and
  325. not(cs_compilesystem in aktmoduleswitches) then
  326. begin
  327. paraloc1:=paramanager.getintparaloc(pocall_default,1);
  328. paramanager.allocparaloc(exprasmlist,paraloc1);
  329. cg.a_param_reg(exprasmlist, OS_ADDR,location.reference.base,paraloc1);
  330. paramanager.freeparaloc(exprasmlist,paraloc1);
  331. { FPC_CHECKPOINTER uses saveregisters }
  332. cg.a_call_name(exprasmlist,'FPC_CHECKPOINTER');
  333. end;
  334. end
  335. else
  336. location_copy(location,left.location);
  337. inc(location.reference.offset,vs.fieldoffset);
  338. { also update the size of the location }
  339. location.size:=def_cgsize(resulttype.def);
  340. end;
  341. {*****************************************************************************
  342. TCGWITHNODE
  343. *****************************************************************************}
  344. procedure tcgwithnode.pass_2;
  345. {$ifdef GDB}
  346. const
  347. withlevel : longint = 0;
  348. var
  349. withstartlabel,withendlabel : tasmlabel;
  350. pp : pchar;
  351. mangled_length : longint;
  352. refnode : tnode;
  353. {$endif GDB}
  354. begin
  355. location_reset(location,LOC_VOID,OS_NO);
  356. {$ifdef GDB}
  357. if (cs_debuginfo in aktmoduleswitches) then
  358. begin
  359. { load reference }
  360. if (withrefnode.nodetype=derefn) and
  361. (tderefnode(withrefnode).left.nodetype=temprefn) then
  362. refnode:=tderefnode(withrefnode).left
  363. else
  364. refnode:=withrefnode;
  365. secondpass(refnode);
  366. location_release(exprasmlist,refnode.location);
  367. location_freetemp(exprasmlist,refnode.location);
  368. if not(refnode.location.loc in [LOC_REFERENCE,LOC_CREFERENCE]) then
  369. internalerror(2003092810);
  370. inc(withlevel);
  371. objectlibrary.getaddrlabel(withstartlabel);
  372. objectlibrary.getaddrlabel(withendlabel);
  373. cg.a_label(exprasmlist,withstartlabel);
  374. withdebugList.concat(Tai_stabs.Create(strpnew(
  375. '"with'+tostr(withlevel)+':'+tostr(symtablestack.getnewtypecount)+
  376. '=*'+tstoreddef(left.resulttype.def).numberstring+'",'+
  377. tostr(N_LSYM)+',0,0,'+tostr(refnode.location.reference.offset))));
  378. mangled_length:=length(current_procinfo.procdef.mangledname);
  379. getmem(pp,mangled_length+50);
  380. strpcopy(pp,'192,0,0,'+withstartlabel.name);
  381. if (target_info.use_function_relative_addresses) then
  382. begin
  383. strpcopy(strend(pp),'-');
  384. strpcopy(strend(pp),current_procinfo.procdef.mangledname);
  385. end;
  386. withdebugList.concat(Tai_stabn.Create(strnew(pp)));
  387. end;
  388. {$endif GDB}
  389. if assigned(left) then
  390. secondpass(left);
  391. {$ifdef GDB}
  392. if (cs_debuginfo in aktmoduleswitches) then
  393. begin
  394. cg.a_label(exprasmlist,withendlabel);
  395. strpcopy(pp,'224,0,0,'+withendlabel.name);
  396. if (target_info.use_function_relative_addresses) then
  397. begin
  398. strpcopy(strend(pp),'-');
  399. strpcopy(strend(pp),current_procinfo.procdef.mangledname);
  400. end;
  401. withdebugList.concat(Tai_stabn.Create(strnew(pp)));
  402. freemem(pp,mangled_length+50);
  403. dec(withlevel);
  404. end;
  405. {$endif GDB}
  406. end;
  407. {*****************************************************************************
  408. TCGVECNODE
  409. *****************************************************************************}
  410. function tcgvecnode.get_mul_size : longint;
  411. begin
  412. if nf_memindex in flags then
  413. get_mul_size:=1
  414. else
  415. begin
  416. if (left.resulttype.def.deftype=arraydef) then
  417. get_mul_size:=tarraydef(left.resulttype.def).elesize
  418. else
  419. get_mul_size:=resulttype.def.size;
  420. end
  421. end;
  422. procedure tcgvecnode.update_reference_reg_mul(reg:tregister;l:aword);
  423. var
  424. hreg: tregister;
  425. begin
  426. if location.reference.base=NR_NO then
  427. begin
  428. cg.a_op_const_reg(exprasmlist,OP_IMUL,OS_ADDR,l,reg);
  429. location.reference.base:=reg;
  430. end
  431. else if location.reference.index=NR_NO then
  432. begin
  433. cg.a_op_const_reg(exprasmlist,OP_IMUL,OS_ADDR,l,reg);
  434. location.reference.index:=reg;
  435. end
  436. else
  437. begin
  438. cg.ungetreference(exprasmlist,location.reference);
  439. hreg := cg.getaddressregister(exprasmlist);
  440. cg.a_loadaddr_ref_reg(exprasmlist,location.reference,hreg);
  441. reference_reset_base(location.reference,hreg,0);
  442. { insert new index register }
  443. cg.a_op_const_reg(exprasmlist,OP_IMUL,OS_ADDR,l,reg);
  444. location.reference.index:=reg;
  445. end;
  446. end;
  447. procedure tcgvecnode.second_wideansistring;
  448. begin
  449. end;
  450. procedure tcgvecnode.second_dynamicarray;
  451. begin
  452. end;
  453. procedure tcgvecnode.rangecheck_array;
  454. var
  455. freereg : boolean;
  456. hightree : tnode;
  457. poslabel,
  458. neglabel : tasmlabel;
  459. hreg : tregister;
  460. paraloc1,paraloc2 : tparalocation;
  461. begin
  462. if is_open_array(left.resulttype.def) or
  463. is_array_of_const(left.resulttype.def) then
  464. begin
  465. { cdecl functions don't have high() so we can not check the range }
  466. if not(current_procinfo.procdef.proccalloption in [pocall_cdecl,pocall_cppdecl]) then
  467. begin
  468. { Get high value }
  469. hightree:=load_high_value_node(tvarsym(tloadnode(left).symtableentry));
  470. { it must be available }
  471. if not assigned(hightree) then
  472. internalerror(200212201);
  473. firstpass(hightree);
  474. secondpass(hightree);
  475. { generate compares }
  476. freereg:=false;
  477. if (right.location.loc in [LOC_REGISTER,LOC_CREGISTER]) then
  478. hreg:=right.location.register
  479. else
  480. begin
  481. hreg:=cg.getintregister(exprasmlist,OS_INT);
  482. freereg:=true;
  483. cg.a_load_loc_reg(exprasmlist,OS_INT,right.location,hreg);
  484. end;
  485. objectlibrary.getlabel(neglabel);
  486. objectlibrary.getlabel(poslabel);
  487. cg.a_cmp_const_reg_label(exprasmlist,OS_INT,OC_LT,0,hreg,poslabel);
  488. location_release(exprasmlist,hightree.location);
  489. cg.a_cmp_loc_reg_label(exprasmlist,OS_INT,OC_BE,hightree.location,hreg,neglabel);
  490. if freereg then
  491. cg.ungetregister(exprasmlist,hreg);
  492. cg.a_label(exprasmlist,poslabel);
  493. cg.a_call_name(exprasmlist,'FPC_RANGEERROR');
  494. cg.a_label(exprasmlist,neglabel);
  495. { release hightree }
  496. hightree.free;
  497. end;
  498. end
  499. else
  500. if is_dynamic_array(left.resulttype.def) then
  501. begin
  502. paraloc1:=paramanager.getintparaloc(pocall_default,1);
  503. paraloc2:=paramanager.getintparaloc(pocall_default,2);
  504. paramanager.allocparaloc(exprasmlist,paraloc2);
  505. cg.a_param_loc(exprasmlist,right.location,paraloc2);
  506. paramanager.allocparaloc(exprasmlist,paraloc1);
  507. cg.a_param_loc(exprasmlist,left.location,paraloc1);
  508. paramanager.freeparaloc(exprasmlist,paraloc1);
  509. paramanager.freeparaloc(exprasmlist,paraloc2);
  510. cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
  511. cg.a_call_name(exprasmlist,'FPC_DYNARRAY_RANGECHECK');
  512. cg.deallocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
  513. end
  514. else
  515. cg.g_rangecheck(exprasmlist,right.location,right.resulttype.def,left.resulttype.def);
  516. end;
  517. procedure tcgvecnode.pass_2;
  518. var
  519. extraoffset : longint;
  520. t : tnode;
  521. href : treference;
  522. otl,ofl : tasmlabel;
  523. newsize : tcgsize;
  524. mulsize: longint;
  525. isjump : boolean;
  526. paraloc1,paraloc2 : tparalocation;
  527. begin
  528. mulsize := get_mul_size;
  529. newsize:=def_cgsize(resulttype.def);
  530. secondpass(left);
  531. if left.location.loc=LOC_CREFERENCE then
  532. location_reset(location,LOC_CREFERENCE,newsize)
  533. else
  534. location_reset(location,LOC_REFERENCE,newsize);
  535. { an ansistring needs to be dereferenced }
  536. if is_ansistring(left.resulttype.def) or
  537. is_widestring(left.resulttype.def) then
  538. begin
  539. if nf_callunique in flags then
  540. internalerror(200304236);
  541. case left.location.loc of
  542. LOC_REGISTER,
  543. LOC_CREGISTER :
  544. location.reference.base:=left.location.register;
  545. LOC_CREFERENCE,
  546. LOC_REFERENCE :
  547. begin
  548. location_release(exprasmlist,left.location);
  549. location.reference.base:=cg.getaddressregister(exprasmlist);
  550. cg.a_load_ref_reg(exprasmlist,OS_ADDR,OS_ADDR,left.location.reference,location.reference.base);
  551. end;
  552. else
  553. internalerror(2002032218);
  554. end;
  555. { check for a zero length string,
  556. we can use the ansistring routine here }
  557. if (cs_check_range in aktlocalswitches) then
  558. begin
  559. paraloc1:=paramanager.getintparaloc(pocall_default,1);
  560. paramanager.allocparaloc(exprasmlist,paraloc1);
  561. cg.a_param_reg(exprasmlist,OS_ADDR,location.reference.base,paraloc1);
  562. paramanager.freeparaloc(exprasmlist,paraloc1);
  563. cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
  564. cg.a_call_name(exprasmlist,'FPC_'+upper(tstringdef(left.resulttype.def).stringtypname)+'_CHECKZERO');
  565. cg.deallocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
  566. end;
  567. { in ansistrings/widestrings S[1] is p<w>char(S)[0] !! }
  568. if is_ansistring(left.resulttype.def) then
  569. dec(location.reference.offset)
  570. else
  571. dec(location.reference.offset,2);
  572. end
  573. else if is_dynamic_array(left.resulttype.def) then
  574. begin
  575. case left.location.loc of
  576. LOC_REGISTER,
  577. LOC_CREGISTER :
  578. location.reference.base:=left.location.register;
  579. LOC_REFERENCE,
  580. LOC_CREFERENCE :
  581. begin
  582. location_release(exprasmlist,left.location);
  583. location.reference.base:=cg.getaddressregister(exprasmlist);
  584. cg.a_load_ref_reg(exprasmlist,OS_ADDR,OS_ADDR,
  585. left.location.reference,location.reference.base);
  586. end;
  587. else
  588. internalerror(2002032219);
  589. end;
  590. end
  591. else
  592. location_copy(location,left.location);
  593. { offset can only differ from 0 if arraydef }
  594. if (left.resulttype.def.deftype=arraydef) and
  595. not(is_dynamic_array(left.resulttype.def)) then
  596. dec(location.reference.offset,mulsize*tarraydef(left.resulttype.def).lowrange);
  597. if right.nodetype=ordconstn then
  598. begin
  599. { offset can only differ from 0 if arraydef }
  600. case left.resulttype.def.deftype of
  601. arraydef :
  602. begin
  603. if not(is_open_array(left.resulttype.def)) and
  604. not(is_array_of_const(left.resulttype.def)) and
  605. not(is_dynamic_array(left.resulttype.def)) then
  606. begin
  607. if (tordconstnode(right).value>tarraydef(left.resulttype.def).highrange) or
  608. (tordconstnode(right).value<tarraydef(left.resulttype.def).lowrange) then
  609. begin
  610. { this should be caught in the resulttypepass! (JM) }
  611. if (cs_check_range in aktlocalswitches) then
  612. CGMessage(parser_e_range_check_error)
  613. else
  614. CGMessage(parser_w_range_check_error);
  615. end;
  616. end
  617. else
  618. begin
  619. { range checking for open and dynamic arrays needs
  620. runtime code }
  621. secondpass(right);
  622. if (cs_check_range in aktlocalswitches) then
  623. rangecheck_array;
  624. end;
  625. end;
  626. stringdef :
  627. begin
  628. if (cs_check_range in aktlocalswitches) then
  629. begin
  630. case tstringdef(left.resulttype.def).string_typ of
  631. { it's the same for ansi- and wide strings }
  632. st_widestring,
  633. st_ansistring:
  634. begin
  635. paraloc1:=paramanager.getintparaloc(pocall_default,1);
  636. paraloc2:=paramanager.getintparaloc(pocall_default,2);
  637. paramanager.allocparaloc(exprasmlist,paraloc2);
  638. cg.a_param_const(exprasmlist,OS_INT,tordconstnode(right).value,paraloc2);
  639. href:=location.reference;
  640. dec(href.offset,7);
  641. paramanager.allocparaloc(exprasmlist,paraloc1);
  642. cg.a_param_ref(exprasmlist,OS_INT,href,paraloc1);
  643. paramanager.freeparaloc(exprasmlist,paraloc1);
  644. paramanager.freeparaloc(exprasmlist,paraloc2);
  645. cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
  646. cg.a_call_name(exprasmlist,'FPC_'+upper(tstringdef(left.resulttype.def).stringtypname)+'_RANGECHECK');
  647. cg.deallocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
  648. end;
  649. st_shortstring:
  650. begin
  651. {!!!!!!!!!!!!!!!!!}
  652. end;
  653. st_longstring:
  654. begin
  655. {!!!!!!!!!!!!!!!!!}
  656. end;
  657. end;
  658. end;
  659. end;
  660. end;
  661. inc(location.reference.offset,
  662. mulsize*tordconstnode(right).value);
  663. end
  664. else
  665. { not nodetype=ordconstn }
  666. begin
  667. if (cs_regvars in aktglobalswitches) and
  668. { if we do range checking, we don't }
  669. { need that fancy code (it would be }
  670. { buggy) }
  671. not(cs_check_range in aktlocalswitches) and
  672. (left.resulttype.def.deftype=arraydef) then
  673. begin
  674. extraoffset:=0;
  675. if (right.nodetype=addn) then
  676. begin
  677. if taddnode(right).right.nodetype=ordconstn then
  678. begin
  679. extraoffset:=tordconstnode(taddnode(right).right).value;
  680. t:=taddnode(right).left;
  681. { First pass processed this with the assumption }
  682. { that there was an add node which may require an }
  683. { extra register. Fake it or die with IE10 (JM) }
  684. t.registers32 := taddnode(right).registers32;
  685. taddnode(right).left:=nil;
  686. right.free;
  687. right:=t;
  688. end
  689. else if taddnode(right).left.nodetype=ordconstn then
  690. begin
  691. extraoffset:=tordconstnode(taddnode(right).left).value;
  692. t:=taddnode(right).right;
  693. t.registers32 := right.registers32;
  694. taddnode(right).right:=nil;
  695. right.free;
  696. right:=t;
  697. end;
  698. end
  699. else if (right.nodetype=subn) then
  700. begin
  701. if taddnode(right).right.nodetype=ordconstn then
  702. begin
  703. extraoffset:=-tordconstnode(taddnode(right).right).value;
  704. t:=taddnode(right).left;
  705. t.registers32 := right.registers32;
  706. taddnode(right).left:=nil;
  707. right.free;
  708. right:=t;
  709. end
  710. { You also have to negate right.right in this case! I can't add an
  711. unaryminusn without causing a crash, so I've disabled it (JM)
  712. else if right.left.nodetype=ordconstn then
  713. begin
  714. extraoffset:=right.left.value;
  715. t:=right.right;
  716. t^.registers32 := right.registers32;
  717. putnode(right);
  718. putnode(right.left);
  719. right:=t;
  720. end;}
  721. end;
  722. inc(location.reference.offset,
  723. mulsize*extraoffset);
  724. end;
  725. { calculate from left to right }
  726. if not(location.loc in [LOC_CREFERENCE,LOC_REFERENCE]) then
  727. internalerror(200304237);
  728. isjump:=(right.location.loc=LOC_JUMP);
  729. if isjump then
  730. begin
  731. otl:=truelabel;
  732. objectlibrary.getlabel(truelabel);
  733. ofl:=falselabel;
  734. objectlibrary.getlabel(falselabel);
  735. end;
  736. secondpass(right);
  737. if cs_check_range in aktlocalswitches then
  738. begin
  739. if left.resulttype.def.deftype=arraydef then
  740. rangecheck_array;
  741. end;
  742. { if mulsize = 1, we won't have to modify the index }
  743. location_force_reg(exprasmlist,right.location,OS_32,mulsize = 1);
  744. if isjump then
  745. begin
  746. truelabel:=otl;
  747. falselabel:=ofl;
  748. end;
  749. { produce possible range check code: }
  750. if cs_check_range in aktlocalswitches then
  751. begin
  752. if left.resulttype.def.deftype=arraydef then
  753. begin
  754. { done defore (PM) }
  755. end
  756. else if (left.resulttype.def.deftype=stringdef) then
  757. begin
  758. case tstringdef(left.resulttype.def).string_typ of
  759. { it's the same for ansi- and wide strings }
  760. st_widestring,
  761. st_ansistring:
  762. begin
  763. paraloc1:=paramanager.getintparaloc(pocall_default,1);
  764. paraloc2:=paramanager.getintparaloc(pocall_default,2);
  765. paramanager.allocparaloc(exprasmlist,paraloc2);
  766. cg.a_param_reg(exprasmlist,OS_INT,right.location.register,paraloc2);
  767. href:=location.reference;
  768. dec(href.offset,7);
  769. paramanager.allocparaloc(exprasmlist,paraloc1);
  770. cg.a_param_ref(exprasmlist,OS_INT,href,paraloc1);
  771. paramanager.freeparaloc(exprasmlist,paraloc1);
  772. paramanager.freeparaloc(exprasmlist,paraloc2);
  773. cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
  774. cg.a_call_name(exprasmlist,'FPC_'+upper(tstringdef(left.resulttype.def).stringtypname)+'_RANGECHECK');
  775. cg.deallocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
  776. end;
  777. st_shortstring:
  778. begin
  779. {!!!!!!!!!!!!!!!!!}
  780. end;
  781. st_longstring:
  782. begin
  783. {!!!!!!!!!!!!!!!!!}
  784. end;
  785. end;
  786. end;
  787. end;
  788. { insert the register and the multiplication factor in the
  789. reference }
  790. update_reference_reg_mul(right.location.register,mulsize);
  791. end;
  792. location.size:=newsize;
  793. end;
  794. begin
  795. cloadvmtaddrnode:=tcgloadvmtaddrnode;
  796. cloadparentfpnode:=tcgloadparentfpnode;
  797. caddrnode:=tcgaddrnode;
  798. cderefnode:=tcgderefnode;
  799. csubscriptnode:=tcgsubscriptnode;
  800. cwithnode:=tcgwithnode;
  801. cvecnode:=tcgvecnode;
  802. end.
  803. {
  804. $Log$
  805. Revision 1.80 2003-11-04 15:35:13 peter
  806. * fix for referencecounted temps
  807. Revision 1.79 2003/10/10 17:48:13 peter
  808. * old trgobj moved to x86/rgcpu and renamed to trgx86fpu
  809. * tregisteralloctor renamed to trgobj
  810. * removed rgobj from a lot of units
  811. * moved location_* and reference_* to cgobj
  812. * first things for mmx register allocation
  813. Revision 1.78 2003/10/09 21:31:37 daniel
  814. * Register allocator splitted, ans abstract now
  815. Revision 1.77 2003/10/01 20:34:48 peter
  816. * procinfo unit contains tprocinfo
  817. * cginfo renamed to cgbase
  818. * moved cgmessage to verbose
  819. * fixed ppc and sparc compiles
  820. Revision 1.76 2003/09/29 20:58:56 peter
  821. * optimized releasing of registers
  822. Revision 1.75 2003/09/28 21:45:52 peter
  823. * fix register leak in with debug
  824. Revision 1.74 2003/09/28 17:55:03 peter
  825. * parent framepointer changed to hidden parameter
  826. * tloadparentfpnode added
  827. Revision 1.73 2003/09/23 17:56:05 peter
  828. * locals and paras are allocated in the code generation
  829. * tvarsym.localloc contains the location of para/local when
  830. generating code for the current procedure
  831. Revision 1.72 2003/09/10 08:31:47 marco
  832. * Patch from Peter for paraloc
  833. Revision 1.71 2003/09/07 22:09:35 peter
  834. * preparations for different default calling conventions
  835. * various RA fixes
  836. Revision 1.70 2003/09/03 15:55:00 peter
  837. * NEWRA branch merged
  838. Revision 1.69.2.1 2003/08/29 17:28:59 peter
  839. * next batch of updates
  840. Revision 1.69 2003/08/10 17:25:23 peter
  841. * fixed some reported bugs
  842. Revision 1.68 2003/08/09 18:56:54 daniel
  843. * cs_regalloc renamed to cs_regvars to avoid confusion with register
  844. allocator
  845. * Some preventive changes to i386 spillinh code
  846. Revision 1.67 2003/07/23 11:01:14 jonas
  847. * several rg.allocexplicitregistersint/rg.deallocexplicitregistersint
  848. pairs round calls to helpers
  849. Revision 1.66 2003/07/06 21:50:33 jonas
  850. * fixed ppc compilation problems and changed VOLATILE_REGISTERS for x86
  851. so that it doesn't include ebp and esp anymore
  852. Revision 1.65 2003/07/06 15:31:20 daniel
  853. * Fixed register allocator. *Lots* of fixes.
  854. Revision 1.64 2003/06/17 19:24:08 jonas
  855. * fixed conversion of fpc_*str_unique to compilerproc
  856. Revision 1.63 2003/06/17 16:34:44 jonas
  857. * lots of newra fixes (need getfuncretparaloc implementation for i386)!
  858. * renamed all_intregisters to paramanager.get_volatile_registers_int(pocall_default) and made it
  859. processor dependent
  860. Revision 1.62 2003/06/13 21:19:30 peter
  861. * current_procdef removed, use current_procinfo.procdef instead
  862. Revision 1.61 2003/06/09 16:45:41 jonas
  863. * fixed update_reference_reg_mul() so that it won't modify CREGISTERs
  864. in a reference
  865. * cache value of get_mul_size()
  866. * if get_mul_size = 1, the index can be a CREGISTER since it won't be
  867. modified
  868. Revision 1.60 2003/06/07 18:57:04 jonas
  869. + added freeintparaloc
  870. * ppc get/freeintparaloc now check whether the parameter regs are
  871. properly allocated/deallocated (and get an extra list para)
  872. * ppc a_call_* now internalerrors if pi_do_call is not yet set
  873. * fixed lot of missing pi_do_call's
  874. Revision 1.59 2003/06/03 21:11:09 peter
  875. * cg.a_load_* get a from and to size specifier
  876. * makeregsize only accepts newregister
  877. * i386 uses generic tcgnotnode,tcgunaryminus
  878. Revision 1.58 2003/06/03 13:01:59 daniel
  879. * Register allocator finished
  880. Revision 1.57 2003/06/02 22:35:45 florian
  881. * better handling of CREGISTER in subscript nodes
  882. Revision 1.56 2003/06/01 21:38:06 peter
  883. * getregisterfpu size parameter added
  884. * op_const_reg size parameter added
  885. * sparc updates
  886. Revision 1.55 2003/05/30 23:49:18 jonas
  887. * a_load_loc_reg now has an extra size parameter for the destination
  888. register (properly fixes what I worked around in revision 1.106 of
  889. ncgutil.pas)
  890. Revision 1.54 2003/05/15 16:10:37 florian
  891. * fixed getintparaloc call for ansi- and widestring range checking
  892. Revision 1.53 2003/05/11 21:37:03 peter
  893. * moved implicit exception frame from ncgutil to psub
  894. * constructor/destructor helpers moved from cobj/ncgutil to psub
  895. Revision 1.52 2003/05/11 14:45:12 peter
  896. * tloadnode does not support objectsymtable,withsymtable anymore
  897. * withnode cleanup
  898. * direct with rewritten to use temprefnode
  899. Revision 1.51 2003/05/09 17:47:02 peter
  900. * self moved to hidden parameter
  901. * removed hdisposen,hnewn,selfn
  902. Revision 1.50 2003/05/07 09:16:23 mazen
  903. - non used units removed from uses clause
  904. Revision 1.49 2003/04/27 11:21:33 peter
  905. * aktprocdef renamed to current_procinfo.procdef
  906. * procinfo renamed to current_procinfo
  907. * procinfo will now be stored in current_module so it can be
  908. cleaned up properly
  909. * gen_main_procsym changed to create_main_proc and release_main_proc
  910. to also generate a tprocinfo structure
  911. * fixed unit implicit initfinal
  912. Revision 1.48 2003/04/22 23:50:22 peter
  913. * firstpass uses expectloc
  914. * checks if there are differences between the expectloc and
  915. location.loc from secondpass in EXTDEBUG
  916. Revision 1.47 2003/04/22 13:47:08 peter
  917. * fixed C style array of const
  918. * fixed C array passing
  919. * fixed left to right with high parameters
  920. Revision 1.46 2003/04/22 10:09:35 daniel
  921. + Implemented the actual register allocator
  922. + Scratch registers unavailable when new register allocator used
  923. + maybe_save/maybe_restore unavailable when new register allocator used
  924. Revision 1.45 2003/04/06 21:11:23 olle
  925. * changed newasmsymbol to newasmsymboldata for data symbols
  926. Revision 1.44 2003/03/28 19:16:56 peter
  927. * generic constructor working for i386
  928. * remove fixed self register
  929. * esi added as address register for i386
  930. Revision 1.43 2003/03/12 22:43:38 jonas
  931. * more powerpc and generic fixes related to the new register allocator
  932. Revision 1.42 2003/02/19 22:00:14 daniel
  933. * Code generator converted to new register notation
  934. - Horribily outdated todo.txt removed
  935. Revision 1.41 2003/01/30 21:46:57 peter
  936. * self fixes for static methods (merged)
  937. Revision 1.40 2003/01/08 18:43:56 daniel
  938. * Tregister changed into a record
  939. Revision 1.39 2002/12/20 18:13:19 peter
  940. * no rangecheck for openarrays with cdecl
  941. Revision 1.38 2002/12/17 22:19:33 peter
  942. * fixed pushing of records>8 bytes with stdcall
  943. * simplified hightree loading
  944. Revision 1.37 2002/12/08 13:39:03 carl
  945. + some documentation added
  946. Revision 1.36 2002/12/07 14:14:19 carl
  947. * bugfix on invalid typecast
  948. Revision 1.35 2002/11/25 17:43:18 peter
  949. * splitted defbase in defutil,symutil,defcmp
  950. * merged isconvertable and is_equal into compare_defs(_ext)
  951. * made operator search faster by walking the list only once
  952. Revision 1.34 2002/11/24 18:19:20 carl
  953. + checkpointer for interfaces also
  954. Revision 1.33 2002/11/23 22:50:06 carl
  955. * some small speed optimizations
  956. + added several new warnings/hints
  957. Revision 1.32 2002/11/15 01:58:51 peter
  958. * merged changes from 1.0.7 up to 04-11
  959. - -V option for generating bug report tracing
  960. - more tracing for option parsing
  961. - errors for cdecl and high()
  962. - win32 import stabs
  963. - win32 records<=8 are returned in eax:edx (turned off by default)
  964. - heaptrc update
  965. - more info for temp management in .s file with EXTDEBUG
  966. Revision 1.31 2002/10/09 20:24:47 florian
  967. + range checking for dyn. arrays
  968. Revision 1.30 2002/10/07 21:30:45 peter
  969. * rangecheck for open arrays added
  970. Revision 1.29 2002/10/05 12:43:25 carl
  971. * fixes for Delphi 6 compilation
  972. (warning : Some features do not work under Delphi)
  973. Revision 1.28 2002/09/17 18:54:02 jonas
  974. * a_load_reg_reg() now has two size parameters: source and dest. This
  975. allows some optimizations on architectures that don't encode the
  976. register size in the register name.
  977. Revision 1.27 2002/09/07 15:25:03 peter
  978. * old logs removed and tabs fixed
  979. Revision 1.26 2002/09/01 18:46:01 peter
  980. * fixed generic tcgvecnode
  981. * move code that updates a reference with index register and multiplier
  982. to separate method so it can be overriden for scaled indexing
  983. * i386 uses generic tcgvecnode
  984. Revision 1.25 2002/08/23 16:14:48 peter
  985. * tempgen cleanup
  986. * tt_noreuse temp type added that will be used in genentrycode
  987. Revision 1.24 2002/08/15 08:13:54 carl
  988. - a_load_sym_ofs_reg removed
  989. * loadvmt now calls loadaddr_ref_reg instead
  990. Revision 1.23 2002/08/11 14:32:26 peter
  991. * renamed current_library to objectlibrary
  992. Revision 1.22 2002/08/11 13:24:12 peter
  993. * saving of asmsymbols in ppu supported
  994. * asmsymbollist global is removed and moved into a new class
  995. tasmlibrarydata that will hold the info of a .a file which
  996. corresponds with a single module. Added librarydata to tmodule
  997. to keep the library info stored for the module. In the future the
  998. objectfiles will also be stored to the tasmlibrarydata class
  999. * all getlabel/newasmsymbol and friends are moved to the new class
  1000. Revision 1.21 2002/08/11 11:36:57 jonas
  1001. * always first try to use base and only then index
  1002. Revision 1.20 2002/08/11 06:14:40 florian
  1003. * fixed powerpc compilation problems
  1004. Revision 1.19 2002/08/10 14:46:29 carl
  1005. + moved target_cpu_string to cpuinfo
  1006. * renamed asmmode enum.
  1007. * assembler reader has now less ifdef's
  1008. * move from nppcmem.pas -> ncgmem.pas vec. node.
  1009. Revision 1.18 2002/07/28 21:34:31 florian
  1010. * more powerpc fixes
  1011. + dummy tcgvecnode
  1012. Revision 1.17 2002/07/11 14:41:28 florian
  1013. * start of the new generic parameter handling
  1014. Revision 1.16 2002/07/07 09:52:32 florian
  1015. * powerpc target fixed, very simple units can be compiled
  1016. * some basic stuff for better callparanode handling, far from being finished
  1017. Revision 1.15 2002/07/01 18:46:23 peter
  1018. * internal linker
  1019. * reorganized aasm layer
  1020. Revision 1.14 2002/07/01 16:23:53 peter
  1021. * cg64 patch
  1022. * basics for currency
  1023. * asnode updates for class and interface (not finished)
  1024. Revision 1.13 2002/05/20 13:30:40 carl
  1025. * bugfix of hdisponen (base must be set, not index)
  1026. * more portability fixes
  1027. Revision 1.12 2002/05/18 13:34:09 peter
  1028. * readded missing revisions
  1029. Revision 1.11 2002/05/16 19:46:37 carl
  1030. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  1031. + try to fix temp allocation (still in ifdef)
  1032. + generic constructor calls
  1033. + start of tassembler / tmodulebase class cleanup
  1034. Revision 1.9 2002/05/12 16:53:07 peter
  1035. * moved entry and exitcode to ncgutil and cgobj
  1036. * foreach gets extra argument for passing local data to the
  1037. iterator function
  1038. * -CR checks also class typecasts at runtime by changing them
  1039. into as
  1040. * fixed compiler to cycle with the -CR option
  1041. * fixed stabs with elf writer, finally the global variables can
  1042. be watched
  1043. * removed a lot of routines from cga unit and replaced them by
  1044. calls to cgobj
  1045. * u32bit-s32bit updates for and,or,xor nodes. When one element is
  1046. u32bit then the other is typecasted also to u32bit without giving
  1047. a rangecheck warning/error.
  1048. * fixed pascal calling method with reversing also the high tree in
  1049. the parast, detected by tcalcst3 test
  1050. Revision 1.8 2002/04/20 21:32:23 carl
  1051. + generic FPC_CHECKPOINTER
  1052. + first parameter offset in stack now portable
  1053. * rename some constants
  1054. + move some cpu stuff to other units
  1055. - remove unused constents
  1056. * fix stacksize for some targets
  1057. * fix generic size problems which depend now on EXTEND_SIZE constant
  1058. Revision 1.7 2002/04/15 18:58:47 carl
  1059. + target_info.size_of_pointer -> pointer_Size
  1060. Revision 1.6 2002/04/04 19:05:57 peter
  1061. * removed unused units
  1062. * use tlocation.size in cg.a_*loc*() routines
  1063. }