ncgmem.pas 49 KB

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