ncgmem.pas 50 KB

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