ncgld.pas 58 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 by Florian Klaempfl
  4. Generate assembler for nodes that handle loads and assignments which
  5. are 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. unit ncgld;
  20. {$i fpcdefs.inc}
  21. interface
  22. uses
  23. node,nld;
  24. type
  25. tcgloadnode = class(tloadnode)
  26. procedure pass_2;override;
  27. end;
  28. tcgassignmentnode = class(tassignmentnode)
  29. procedure pass_2;override;
  30. end;
  31. tcgarrayconstructornode = class(tarrayconstructornode)
  32. procedure pass_2;override;
  33. end;
  34. implementation
  35. uses
  36. cutils,
  37. systems,
  38. verbose,globtype,globals,
  39. symconst,symtype,symdef,symsym,symtable,defutil,paramgr,
  40. ncnv,ncon,nmem,nbas,
  41. aasmbase,aasmtai,aasmcpu,regvars,
  42. cgbase,pass_2,
  43. cpubase,cpuinfo,procinfo,
  44. tgobj,ncgutil,cgobj,rgobj,ncgbas;
  45. {*****************************************************************************
  46. SecondLoad
  47. *****************************************************************************}
  48. procedure tcgloadnode.pass_2;
  49. var
  50. r,hregister : tregister;
  51. supreg:Tsuperregister;
  52. symtabletype : tsymtabletype;
  53. href : treference;
  54. newsize : tcgsize;
  55. endrelocatelab,
  56. norelocatelab : tasmlabel;
  57. paraloc1 : tparalocation;
  58. begin
  59. { we don't know the size of all arrays }
  60. newsize:=def_cgsize(resulttype.def);
  61. location_reset(location,LOC_REFERENCE,newsize);
  62. case symtableentry.typ of
  63. absolutesym :
  64. begin
  65. { this is only for toasm and toaddr }
  66. if (tabsolutesym(symtableentry).abstyp=toaddr) then
  67. begin
  68. {$ifdef i386}
  69. if tabsolutesym(symtableentry).absseg then
  70. location.reference.segment:=NR_FS;
  71. {$endif i386}
  72. location.reference.offset:=tabsolutesym(symtableentry).fieldoffset;
  73. end
  74. else
  75. location.reference.symbol:=objectlibrary.newasmsymboldata(tabsolutesym(symtableentry).mangledname);
  76. end;
  77. constsym:
  78. begin
  79. if tconstsym(symtableentry).consttyp=constresourcestring then
  80. begin
  81. location_reset(location,LOC_CREFERENCE,OS_ADDR);
  82. location.reference.symbol:=objectlibrary.newasmsymboldata(tconstsym(symtableentry).owner.name^+'_RESOURCESTRINGLIST');
  83. location.reference.offset:=tconstsym(symtableentry).resstrindex*16+8;
  84. end
  85. else
  86. internalerror(22798);
  87. end;
  88. varsym :
  89. begin
  90. if (tvarsym(symtableentry).varspez=vs_const) then
  91. location_reset(location,LOC_CREFERENCE,newsize);
  92. symtabletype:=symtable.symtabletype;
  93. hregister:=NR_NO;
  94. { C variable }
  95. if (vo_is_C_var in tvarsym(symtableentry).varoptions) then
  96. begin
  97. location.reference.symbol:=objectlibrary.newasmsymboldata(tvarsym(symtableentry).mangledname);
  98. end
  99. { DLL variable }
  100. else if (vo_is_dll_var in tvarsym(symtableentry).varoptions) then
  101. begin
  102. hregister:=rg.getaddressregister(exprasmlist);
  103. location.reference.symbol:=objectlibrary.newasmsymboldata(tvarsym(symtableentry).mangledname);
  104. cg.a_load_ref_reg(exprasmlist,OS_ADDR,OS_ADDR,location.reference,hregister);
  105. reference_reset_base(location.reference,hregister,0);
  106. end
  107. { external variable }
  108. else if (vo_is_external in tvarsym(symtableentry).varoptions) then
  109. begin
  110. location.reference.symbol:=objectlibrary.newasmsymboldata(tvarsym(symtableentry).mangledname);
  111. end
  112. { thread variable }
  113. else if (vo_is_thread_var in tvarsym(symtableentry).varoptions) then
  114. begin
  115. {
  116. Thread var loading is optimized to first check if
  117. a relocate function is available. When the function
  118. is available it is called to retrieve the address.
  119. Otherwise the address is loaded with the symbol
  120. The code needs to be in the order to first handle the
  121. call and then the address load to be sure that the
  122. register that is used for returning is the same (PFV)
  123. }
  124. objectlibrary.getlabel(norelocatelab);
  125. objectlibrary.getlabel(endrelocatelab);
  126. { make sure hregister can't allocate the register necessary for the parameter }
  127. paraloc1:=paramanager.getintparaloc(pocall_default,1);
  128. hregister:=rg.getaddressregister(exprasmlist);
  129. reference_reset_symbol(href,objectlibrary.newasmsymboldata('FPC_THREADVAR_RELOCATE'),0);
  130. cg.a_load_ref_reg(exprasmlist,OS_ADDR,OS_ADDR,href,hregister);
  131. rg.ungetregisterint(exprasmlist,hregister);
  132. cg.a_cmp_const_reg_label(exprasmlist,OS_ADDR,OC_EQ,0,hregister,norelocatelab);
  133. { don't save the allocated register else the result will be destroyed later }
  134. reference_reset_symbol(href,objectlibrary.newasmsymboldata(tvarsym(symtableentry).mangledname),0);
  135. paramanager.allocparaloc(exprasmlist,paraloc1);
  136. cg.a_param_ref(exprasmlist,OS_ADDR,href,paraloc1);
  137. paramanager.freeparaloc(exprasmlist,paraloc1);
  138. r:=rg.getabtregisterint(exprasmlist,OS_ADDR);
  139. rg.ungetregisterint(exprasmlist,r);
  140. cg.a_load_reg_reg(exprasmlist,OS_ADDR,OS_ADDR,hregister,r);
  141. rg.allocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default));
  142. cg.a_call_reg(exprasmlist,r);
  143. rg.deallocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default));
  144. r:=rg.getexplicitregisterint(exprasmlist,NR_FUNCTION_RESULT_REG);
  145. rg.ungetregisterint(exprasmlist,r);
  146. hregister:=rg.getaddressregister(exprasmlist);
  147. cg.a_load_reg_reg(exprasmlist,OS_INT,OS_ADDR,r,hregister);
  148. cg.a_jmp_always(exprasmlist,endrelocatelab);
  149. cg.a_label(exprasmlist,norelocatelab);
  150. { no relocation needed, load the address of the variable only, the
  151. layout of a threadvar is (4 bytes pointer):
  152. 0 - Threadvar index
  153. 4 - Threadvar value in single threading }
  154. reference_reset_symbol(href,objectlibrary.newasmsymboldata(tvarsym(symtableentry).mangledname),POINTER_SIZE);
  155. cg.a_loadaddr_ref_reg(exprasmlist,href,hregister);
  156. cg.a_label(exprasmlist,endrelocatelab);
  157. location.reference.base:=hregister;
  158. end
  159. { nested variable }
  160. else if assigned(left) then
  161. begin
  162. if not(symtabletype in [localsymtable,parasymtable]) then
  163. internalerror(200309285);
  164. secondpass(left);
  165. if left.location.loc<>LOC_REGISTER then
  166. internalerror(200309286);
  167. hregister:=left.location.register;
  168. location.reference.base:=hregister;
  169. location.reference.offset:=tvarsym(symtableentry).localloc.reference.offset;
  170. end
  171. { normal variable }
  172. else
  173. begin
  174. { in case it is a register variable: }
  175. if tvarsym(symtableentry).localloc.loc=LOC_REGISTER then
  176. begin
  177. case getregtype(tvarsym(symtableentry).localloc.register) of
  178. R_FPUREGISTER :
  179. begin
  180. location_reset(location,LOC_CFPUREGISTER,def_cgsize(resulttype.def));
  181. location.register:=tvarsym(symtableentry).localloc.register;
  182. end;
  183. R_INTREGISTER :
  184. begin
  185. supreg:=getsupreg(Tvarsym(symtableentry).localloc.register);
  186. if (supreg in general_superregisters) and
  187. not (supreg in rg.regvar_loaded_int) then
  188. load_regvar(exprasmlist,tvarsym(symtableentry));
  189. location_reset(location,LOC_CREGISTER,def_cgsize(resulttype.def));
  190. location.register:=tvarsym(symtableentry).localloc.register;
  191. exclude(rg.unusedregsint,supreg);
  192. hregister := location.register;
  193. end;
  194. else
  195. internalerror(200301172);
  196. end;
  197. end
  198. else
  199. begin
  200. case symtabletype of
  201. localsymtable,
  202. parasymtable,
  203. inlinelocalsymtable,
  204. inlineparasymtable :
  205. begin
  206. if tvarsym(symtableentry).localloc.loc<>LOC_REFERENCE then
  207. internalerror(2003091816);
  208. location.reference.base:=tvarsym(symtableentry).localloc.reference.index;
  209. location.reference.offset:=tvarsym(symtableentry).localloc.reference.offset;
  210. end;
  211. globalsymtable,
  212. staticsymtable :
  213. begin
  214. location.reference.symbol:=objectlibrary.newasmsymboldata(tvarsym(symtableentry).mangledname);
  215. end;
  216. stt_exceptsymtable:
  217. begin
  218. if tvarsym(symtableentry).localloc.loc<>LOC_REFERENCE then
  219. internalerror(2003091817);
  220. location.reference.base:=tvarsym(symtableentry).localloc.reference.index;
  221. location.reference.offset:=tvarsym(symtableentry).localloc.reference.offset;
  222. end;
  223. else
  224. internalerror(200305102);
  225. end;
  226. end;
  227. end;
  228. { handle call by reference variables when they are not
  229. alreayd copied to local copies. Also ignore the reference
  230. when we need to load the self pointer for objects }
  231. if (symtabletype in [parasymtable,inlineparasymtable]) and
  232. not(vo_has_local_copy in tvarsym(symtableentry).varoptions) and
  233. not(nf_load_self_pointer in flags) and
  234. paramanager.push_addr_param(tvarsym(symtableentry).varspez,tvarsym(symtableentry).vartype.def,tprocdef(symtable.defowner).proccalloption) then
  235. begin
  236. if hregister=NR_NO then
  237. hregister:=rg.getaddressregister(exprasmlist);
  238. { we need to load only an address }
  239. location.size:=OS_ADDR;
  240. cg.a_load_loc_reg(exprasmlist,location.size,location,hregister);
  241. if tvarsym(symtableentry).varspez=vs_const then
  242. location_reset(location,LOC_CREFERENCE,newsize)
  243. else
  244. location_reset(location,LOC_REFERENCE,newsize);
  245. location.reference.base:=hregister;
  246. end;
  247. end;
  248. procsym:
  249. begin
  250. if assigned(left) then
  251. begin
  252. {
  253. THIS IS A TERRIBLE HACK!!!!!! WHICH WILL NOT WORK
  254. ON 64-BIT SYSTEMS: SINCE PROCSYM FOR METHODS
  255. CONSISTS OF TWO OS_ADDR, so you cannot set it
  256. to OS_64 - how to solve?? Carl
  257. }
  258. if (sizeof(aword) = 4) then
  259. location_reset(location,LOC_CREFERENCE,OS_64)
  260. else
  261. internalerror(20020520);
  262. tg.GetTemp(exprasmlist,2*POINTER_SIZE,tt_normal,location.reference);
  263. secondpass(left);
  264. { load class instance address }
  265. case left.location.loc of
  266. LOC_CREGISTER,
  267. LOC_REGISTER:
  268. begin
  269. { this is not possible for objects }
  270. if is_object(left.resulttype.def) then
  271. internalerror(200304234);
  272. hregister:=left.location.register;
  273. end;
  274. LOC_CREFERENCE,
  275. LOC_REFERENCE:
  276. begin
  277. location_release(exprasmlist,left.location);
  278. hregister:=rg.getaddressregister(exprasmlist);
  279. if is_class_or_interface(left.resulttype.def) then
  280. cg.a_load_ref_reg(exprasmlist,OS_ADDR,OS_ADDR,left.location.reference,hregister)
  281. else
  282. cg.a_loadaddr_ref_reg(exprasmlist,left.location.reference,hregister);
  283. location_freetemp(exprasmlist,left.location);
  284. end;
  285. else
  286. internalerror(26019);
  287. end;
  288. { store the class instance address }
  289. href:=location.reference;
  290. inc(href.offset,POINTER_SIZE);
  291. cg.a_load_reg_ref(exprasmlist,OS_ADDR,OS_ADDR,hregister,href);
  292. { virtual method ? }
  293. if (po_virtualmethod in procdef.procoptions) then
  294. begin
  295. { load vmt pointer }
  296. reference_reset_base(href,hregister,0);
  297. reference_release(exprasmlist,href);
  298. hregister:=rg.getaddressregister(exprasmlist);
  299. cg.a_load_ref_reg(exprasmlist,OS_ADDR,OS_ADDR,href,hregister);
  300. reference_reset_base(href,hregister,
  301. procdef._class.vmtmethodoffset(procdef.extnumber));
  302. reference_release(exprasmlist,href);
  303. { load method address }
  304. hregister:=rg.getaddressregister(exprasmlist);
  305. cg.a_load_ref_reg(exprasmlist,OS_ADDR,OS_ADDR,href,hregister);
  306. { ... and store it }
  307. cg.a_load_reg_ref(exprasmlist,OS_ADDR,OS_ADDR,hregister,location.reference);
  308. rg.ungetaddressregister(exprasmlist,hregister);
  309. end
  310. else
  311. begin
  312. { we don't use the hregister }
  313. rg.ungetregisterint(exprasmlist,hregister);
  314. { load address of the function }
  315. reference_reset_symbol(href,objectlibrary.newasmsymbol(procdef.mangledname),0);
  316. hregister:=rg.getaddressregister(exprasmlist);
  317. cg.a_loadaddr_ref_reg(exprasmlist,href,hregister);
  318. cg.a_load_reg_ref(exprasmlist,OS_ADDR,OS_ADDR,hregister,location.reference);
  319. rg.ungetregisterint(exprasmlist,hregister);
  320. end;
  321. end
  322. else
  323. begin
  324. {!!!!! Be aware, work on virtual methods too }
  325. location.reference.symbol:=objectlibrary.newasmsymbol(procdef.mangledname);
  326. end;
  327. end;
  328. typedconstsym :
  329. begin
  330. location.reference.symbol:=objectlibrary.newasmsymboldata(ttypedconstsym(symtableentry).mangledname);
  331. end;
  332. else internalerror(4);
  333. end;
  334. end;
  335. {*****************************************************************************
  336. SecondAssignment
  337. *****************************************************************************}
  338. procedure tcgassignmentnode.pass_2;
  339. var
  340. otlabel,hlabel,oflabel : tasmlabel;
  341. fputyp : tfloattype;
  342. href : treference;
  343. old_allow_multi_pass2,
  344. releaseright : boolean;
  345. cgsize : tcgsize;
  346. r:Tregister;
  347. begin
  348. location_reset(location,LOC_VOID,OS_NO);
  349. otlabel:=truelabel;
  350. oflabel:=falselabel;
  351. objectlibrary.getlabel(truelabel);
  352. objectlibrary.getlabel(falselabel);
  353. {
  354. in most cases we can process first the right node which contains
  355. the most complex code. But not when the result is in the flags, then
  356. loading the left node afterwards can destroy the flags.
  357. when the right node returns as LOC_JUMP then we will generate
  358. the following code:
  359. rightnode
  360. true:
  361. leftnode
  362. assign 1
  363. false:
  364. leftnode
  365. assign 0
  366. }
  367. { Try to determine which side to calculate first, }
  368. if (right.expectloc<>LOC_FLAGS) and
  369. ((right.expectloc=LOC_JUMP) or
  370. (right.nodetype=calln) or
  371. (right.registers32>=left.registers32)) then
  372. begin
  373. secondpass(right);
  374. { increment source reference counter, this is
  375. useless for string constants}
  376. if (right.resulttype.def.needs_inittable) and
  377. (right.nodetype<>stringconstn) then
  378. cg.g_incrrefcount(exprasmlist,right.resulttype.def,right.location.reference,false);
  379. if codegenerror then
  380. exit;
  381. { We skip the generation of the left node when it's a jump, see
  382. explanation above }
  383. if (right.location.loc<>LOC_JUMP) and
  384. not(nf_concat_string in flags) then
  385. begin
  386. { left can't be never a 64 bit LOC_REGISTER, so the 3. arg }
  387. { can be false }
  388. secondpass(left);
  389. { decrement destination reference counter }
  390. if (left.resulttype.def.needs_inittable) then
  391. cg.g_decrrefcount(exprasmlist,left.resulttype.def,left.location.reference,false);
  392. if codegenerror then
  393. exit;
  394. end;
  395. end
  396. else
  397. begin
  398. { calculate left sides }
  399. { don't do it yet if it's a crgister (JM) }
  400. if not(nf_concat_string in flags) then
  401. begin
  402. secondpass(left);
  403. { decrement destination reference counter }
  404. if (left.resulttype.def.needs_inittable) then
  405. cg.g_decrrefcount(exprasmlist,left.resulttype.def,left.location.reference,false);
  406. if codegenerror then
  407. exit;
  408. end;
  409. { left can't be never a 64 bit LOC_REGISTER, so the 3. arg }
  410. { can be false }
  411. secondpass(right);
  412. { increment source reference counter, this is
  413. useless for string constants}
  414. if (right.resulttype.def.needs_inittable) and
  415. (right.nodetype<>stringconstn) then
  416. cg.g_incrrefcount(exprasmlist,right.resulttype.def,right.location.reference,false);
  417. if codegenerror then
  418. exit;
  419. end;
  420. releaseright:=true;
  421. { optimize temp to temp copies }
  422. if (left.nodetype = temprefn) and
  423. { we may store certain temps in registers in the future, then this }
  424. { optimization will have to be adapted }
  425. (left.location.loc = LOC_REFERENCE) and
  426. (right.location.loc = LOC_REFERENCE) and
  427. tg.istemp(right.location.reference) and
  428. (tg.sizeoftemp(exprasmlist,right.location.reference) = tg.sizeoftemp(exprasmlist,left.location.reference)) then
  429. begin
  430. { in theory, we should also make sure the left temp type is }
  431. { already more or less of the same kind (ie. we must not }
  432. { assign an ansistring to a normaltemp). In practice, the }
  433. { assignment node will have already taken care of this for us }
  434. tcgtemprefnode(left).changelocation(right.location.reference);
  435. end
  436. { shortstring assignments are handled separately }
  437. else if is_shortstring(left.resulttype.def) then
  438. begin
  439. {
  440. we can get here only in the following situations
  441. for the right node:
  442. - empty constant string
  443. - char
  444. }
  445. { empty constant string }
  446. if (right.nodetype=stringconstn) and
  447. (tstringconstnode(right).len=0) then
  448. begin
  449. cg.a_load_const_ref(exprasmlist,OS_8,0,left.location.reference);
  450. end
  451. { char loading }
  452. else if is_char(right.resulttype.def) then
  453. begin
  454. if right.nodetype=ordconstn then
  455. begin
  456. if (target_info.endian = endian_little) then
  457. cg.a_load_const_ref(exprasmlist,OS_16,(tordconstnode(right).value shl 8) or 1,
  458. left.location.reference)
  459. else
  460. cg.a_load_const_ref(exprasmlist,OS_16,tordconstnode(right).value or (1 shl 8),
  461. left.location.reference);
  462. end
  463. else
  464. begin
  465. href:=left.location.reference;
  466. cg.a_load_const_ref(exprasmlist,OS_8,1,href);
  467. inc(href.offset,1);
  468. case right.location.loc of
  469. LOC_REGISTER,
  470. LOC_CREGISTER :
  471. begin
  472. r:=rg.makeregsize(right.location.register,OS_8);
  473. cg.a_load_reg_ref(exprasmlist,OS_8,OS_8,r,href);
  474. end;
  475. LOC_REFERENCE,
  476. LOC_CREFERENCE :
  477. cg.a_load_ref_ref(exprasmlist,OS_8,OS_8,right.location.reference,href);
  478. else
  479. internalerror(200205111);
  480. end;
  481. end;
  482. end
  483. else
  484. internalerror(200204249);
  485. end
  486. else
  487. begin
  488. case right.location.loc of
  489. LOC_CONSTANT :
  490. begin
  491. if right.location.size in [OS_64,OS_S64] then
  492. cg64.a_load64_const_loc(exprasmlist,
  493. right.location.valueqword,left.location)
  494. else
  495. cg.a_load_const_loc(exprasmlist,right.location.value,left.location);
  496. end;
  497. LOC_REFERENCE,
  498. LOC_CREFERENCE :
  499. begin
  500. case left.location.loc of
  501. LOC_CREGISTER :
  502. begin
  503. cgsize:=def_cgsize(left.resulttype.def);
  504. if cgsize in [OS_64,OS_S64] then
  505. begin
  506. cg64.a_load64_ref_reg(exprasmlist,
  507. right.location.reference,left.location.register64,false);
  508. location_release(exprasmlist,right.location);
  509. end
  510. else
  511. begin
  512. location_release(exprasmlist,right.location);
  513. cg.a_load_ref_reg(exprasmlist,cgsize,cgsize,
  514. right.location.reference,left.location.register);
  515. end;
  516. end;
  517. LOC_CFPUREGISTER :
  518. begin
  519. cg.a_loadfpu_ref_reg(exprasmlist,
  520. def_cgsize(right.resulttype.def),
  521. right.location.reference,
  522. left.location.register);
  523. end;
  524. LOC_REFERENCE,
  525. LOC_CREFERENCE :
  526. begin
  527. cg.g_concatcopy(exprasmlist,right.location.reference,
  528. left.location.reference,left.resulttype.def.size,true,false);
  529. { right.location is already released by concatcopy }
  530. releaseright:=false;
  531. end;
  532. else
  533. internalerror(200203284);
  534. end;
  535. end;
  536. {$ifdef SUPPORT_MMX}
  537. LOC_CMMXREGISTER,
  538. LOC_MMXREGISTER:
  539. begin
  540. if left.location.loc=LOC_CMMXREGISTER then
  541. cg.a_loadmm_reg_reg(exprasmlist,right.location.register,left.location.register)
  542. else
  543. cg.a_loadmm_reg_ref(exprasmlist,right.location.register,left.location.reference);
  544. end;
  545. {$endif SUPPORT_MMX}
  546. LOC_REGISTER,
  547. LOC_CREGISTER :
  548. begin
  549. cgsize:=def_cgsize(left.resulttype.def);
  550. if cgsize in [OS_64,OS_S64] then
  551. cg64.a_load64_reg_loc(exprasmlist,
  552. right.location.register64,left.location)
  553. else
  554. cg.a_load_reg_loc(exprasmlist,right.location.size,right.location.register,left.location);
  555. end;
  556. LOC_FPUREGISTER,LOC_CFPUREGISTER :
  557. begin
  558. if (left.resulttype.def.deftype=floatdef) then
  559. fputyp:=tfloatdef(left.resulttype.def).typ
  560. else
  561. if (right.resulttype.def.deftype=floatdef) then
  562. fputyp:=tfloatdef(right.resulttype.def).typ
  563. else
  564. if (right.nodetype=typeconvn) and
  565. (ttypeconvnode(right).left.resulttype.def.deftype=floatdef) then
  566. fputyp:=tfloatdef(ttypeconvnode(right).left.resulttype.def).typ
  567. else
  568. fputyp:=s32real;
  569. cg.a_loadfpu_reg_loc(exprasmlist,
  570. tfloat2tcgsize[fputyp],
  571. right.location.register,left.location);
  572. end;
  573. LOC_JUMP :
  574. begin
  575. cgsize:=def_cgsize(left.resulttype.def);
  576. objectlibrary.getlabel(hlabel);
  577. { generate the leftnode for the true case, and
  578. release the location }
  579. cg.a_label(exprasmlist,truelabel);
  580. secondpass(left);
  581. if codegenerror then
  582. exit;
  583. cg.a_load_const_loc(exprasmlist,1,left.location);
  584. location_release(exprasmlist,left.location);
  585. cg.a_jmp_always(exprasmlist,hlabel);
  586. { generate the leftnode for the false case }
  587. cg.a_label(exprasmlist,falselabel);
  588. old_allow_multi_pass2:=allow_multi_pass2;
  589. allow_multi_pass2:=true;
  590. secondpass(left);
  591. allow_multi_pass2:=old_allow_multi_pass2;
  592. if codegenerror then
  593. exit;
  594. cg.a_load_const_loc(exprasmlist,0,left.location);
  595. cg.a_label(exprasmlist,hlabel);
  596. end;
  597. {$ifdef cpuflags}
  598. LOC_FLAGS :
  599. begin
  600. {This can be a wordbool or longbool too, no?}
  601. if left.location.loc=LOC_CREGISTER then
  602. cg.g_flags2reg(exprasmlist,def_cgsize(left.resulttype.def),right.location.resflags,left.location.register)
  603. else
  604. begin
  605. if not(left.location.loc = LOC_REFERENCE) then
  606. internalerror(200203273);
  607. cg.g_flags2ref(exprasmlist,def_cgsize(left.resulttype.def),right.location.resflags,left.location.reference);
  608. end;
  609. end;
  610. {$endif cpuflags}
  611. end;
  612. end;
  613. if releaseright then
  614. location_release(exprasmlist,right.location);
  615. location_release(exprasmlist,left.location);
  616. truelabel:=otlabel;
  617. falselabel:=oflabel;
  618. end;
  619. {*****************************************************************************
  620. SecondArrayConstruct
  621. *****************************************************************************}
  622. const
  623. vtInteger = 0;
  624. vtBoolean = 1;
  625. vtChar = 2;
  626. vtExtended = 3;
  627. vtString = 4;
  628. vtPointer = 5;
  629. vtPChar = 6;
  630. vtObject = 7;
  631. vtClass = 8;
  632. vtWideChar = 9;
  633. vtPWideChar = 10;
  634. vtAnsiString = 11;
  635. vtCurrency = 12;
  636. vtVariant = 13;
  637. vtInterface = 14;
  638. vtWideString = 15;
  639. vtInt64 = 16;
  640. vtQWord = 17;
  641. procedure tcgarrayconstructornode.pass_2;
  642. var
  643. hp : tarrayconstructornode;
  644. href : treference;
  645. lt : tdef;
  646. vaddr : boolean;
  647. vtype : longint;
  648. freetemp,
  649. dovariant : boolean;
  650. elesize : longint;
  651. tmpreg : tregister;
  652. paraloc : tparalocation;
  653. procedure push_value(p:tnode);
  654. var
  655. {$ifdef i386}
  656. href : treference;
  657. tempreference : treference;
  658. sizetopush : longint;
  659. size : longint;
  660. {$endif i386}
  661. cgsize : tcgsize;
  662. begin
  663. { we've nothing to push when the size of the parameter is 0 }
  664. if p.resulttype.def.size=0 then
  665. exit;
  666. if p.location.loc in [LOC_FLAGS,LOC_JUMP] then
  667. internalerror(200309293);
  668. { Handle Floating point types differently }
  669. if p.resulttype.def.deftype=floatdef then
  670. begin
  671. location_release(exprasmlist,p.location);
  672. {$ifdef i386}
  673. case p.location.loc of
  674. LOC_FPUREGISTER,
  675. LOC_CFPUREGISTER:
  676. begin
  677. size:=align(tfloatdef(p.resulttype.def).size,std_param_align);
  678. inc(pushedparasize,size);
  679. cg.g_stackpointer_alloc(exprasmlist,size);
  680. reference_reset_base(href,NR_STACK_POINTER_REG,0);
  681. cg.a_loadfpu_reg_ref(exprasmlist,def_cgsize(p.resulttype.def),p.location.register,href);
  682. end;
  683. LOC_REFERENCE,
  684. LOC_CREFERENCE :
  685. begin
  686. sizetopush:=align(p.resulttype.def.size,std_param_align);
  687. tempreference:=p.location.reference;
  688. inc(tempreference.offset,sizetopush);
  689. while (sizetopush>0) do
  690. begin
  691. if sizetopush>=4 then
  692. begin
  693. cgsize:=OS_32;
  694. inc(pushedparasize,4);
  695. dec(tempreference.offset,4);
  696. dec(sizetopush,4);
  697. end
  698. else
  699. begin
  700. cgsize:=OS_16;
  701. inc(pushedparasize,2);
  702. dec(tempreference.offset,2);
  703. dec(sizetopush,2);
  704. end;
  705. cg.a_param_ref(exprasmlist,cgsize,tempreference,paraloc);
  706. end;
  707. end;
  708. else
  709. internalerror(200204243);
  710. end;
  711. {$else i386}
  712. case p.location.loc of
  713. LOC_FPUREGISTER,
  714. LOC_CFPUREGISTER:
  715. cg.a_paramfpu_reg(exprasmlist,def_cgsize(p.resulttype.def),p.location.register,paraloc);
  716. LOC_REFERENCE,
  717. LOC_CREFERENCE :
  718. cg.a_paramfpu_ref(exprasmlist,def_cgsize(p.resulttype.def),p.location.reference,paraloc)
  719. else
  720. internalerror(200204243);
  721. end;
  722. {$endif i386}
  723. end
  724. else
  725. begin
  726. { copy the value on the stack or use normal parameter push? }
  727. if paramanager.copy_value_on_stack(vs_value,p.resulttype.def,pocall_cdecl) then
  728. begin
  729. location_release(exprasmlist,p.location);
  730. if not (p.location.loc in [LOC_REFERENCE,LOC_CREFERENCE]) then
  731. internalerror(200204241);
  732. {$ifdef i386}
  733. { push on stack }
  734. size:=align(p.resulttype.def.size,std_param_align);
  735. inc(pushedparasize,size);
  736. cg.g_stackpointer_alloc(exprasmlist,size);
  737. reference_reset_base(href,NR_STACK_POINTER_REG,0);
  738. cg.g_concatcopy(exprasmlist,p.location.reference,href,size,false,false);
  739. {$else i386}
  740. cg.a_param_copy_ref(exprasmlist,p.resulttype.def.size,p.location.reference,paraloc);
  741. {$endif i386}
  742. end
  743. else
  744. begin
  745. case p.location.loc of
  746. LOC_CONSTANT,
  747. LOC_REGISTER,
  748. LOC_CREGISTER,
  749. LOC_REFERENCE,
  750. LOC_CREFERENCE :
  751. begin
  752. cgsize:=def_cgsize(p.resulttype.def);
  753. if cgsize in [OS_64,OS_S64] then
  754. begin
  755. inc(pushedparasize,8);
  756. cg64.a_param64_loc(exprasmlist,p.location,paraloc);
  757. location_release(exprasmlist,p.location);
  758. end
  759. else
  760. begin
  761. location_release(exprasmlist,p.location);
  762. inc(pushedparasize,std_param_align);
  763. cg.a_param_loc(exprasmlist,p.location,paraloc);
  764. end;
  765. end;
  766. else
  767. internalerror(200204241);
  768. end;
  769. end;
  770. end;
  771. end;
  772. begin
  773. dovariant:=(nf_forcevaria in flags) or tarraydef(resulttype.def).isvariant;
  774. if dovariant then
  775. elesize:=8
  776. else
  777. elesize:=tarraydef(resulttype.def).elesize;
  778. if nf_cargs in flags then
  779. begin
  780. location_reset(location,LOC_VOID,OS_NO);
  781. { Retrieve parameter location for push }
  782. paraloc:=paramanager.getintparaloc(pocall_cdecl,1);
  783. end
  784. else
  785. begin
  786. location_reset(location,LOC_CREFERENCE,OS_NO);
  787. fillchar(paraloc,sizeof(paraloc),0);
  788. { Allocate always a temp, also if no elements are required, to
  789. be sure that location is valid (PFV) }
  790. if tarraydef(resulttype.def).highrange=-1 then
  791. tg.GetTemp(exprasmlist,elesize,tt_normal,location.reference)
  792. else
  793. tg.GetTemp(exprasmlist,(tarraydef(resulttype.def).highrange+1)*elesize,tt_normal,location.reference);
  794. href:=location.reference;
  795. end;
  796. { Process nodes in array constructor }
  797. hp:=self;
  798. while assigned(hp) do
  799. begin
  800. if assigned(hp.left) then
  801. begin
  802. freetemp:=true;
  803. secondpass(hp.left);
  804. if codegenerror then
  805. exit;
  806. { Move flags and jump in register }
  807. if hp.left.location.loc in [LOC_FLAGS,LOC_JUMP] then
  808. location_force_reg(exprasmlist,hp.left.location,def_cgsize(hp.left.resulttype.def),false);
  809. if dovariant then
  810. begin
  811. { find the correct vtype value }
  812. vtype:=$ff;
  813. vaddr:=false;
  814. lt:=hp.left.resulttype.def;
  815. case lt.deftype of
  816. enumdef,
  817. orddef :
  818. begin
  819. if is_64bit(lt) then
  820. begin
  821. case torddef(lt).typ of
  822. s64bit:
  823. vtype:=vtInt64;
  824. u64bit:
  825. vtype:=vtQWord;
  826. end;
  827. if not(nf_cargs in flags) then
  828. begin
  829. freetemp:=false;
  830. vaddr:=true;
  831. end;
  832. end
  833. else if (lt.deftype=enumdef) or
  834. is_integer(lt) then
  835. vtype:=vtInteger
  836. else
  837. if is_boolean(lt) then
  838. vtype:=vtBoolean
  839. else
  840. if (lt.deftype=orddef) then
  841. begin
  842. case torddef(lt).typ of
  843. uchar:
  844. vtype:=vtChar;
  845. uwidechar:
  846. vtype:=vtWideChar;
  847. end;
  848. end;
  849. end;
  850. floatdef :
  851. begin
  852. vtype:=vtExtended;
  853. if not(nf_cargs in flags) then
  854. begin
  855. freetemp:=false;
  856. vaddr:=true;
  857. end;
  858. end;
  859. procvardef,
  860. pointerdef :
  861. begin
  862. if is_pchar(lt) then
  863. vtype:=vtPChar
  864. else
  865. vtype:=vtPointer;
  866. end;
  867. variantdef :
  868. begin
  869. vtype:=vtVariant;
  870. vaddr:=true;
  871. freetemp:=false;
  872. end;
  873. classrefdef :
  874. vtype:=vtClass;
  875. objectdef :
  876. vtype:=vtObject;
  877. stringdef :
  878. begin
  879. if is_shortstring(lt) then
  880. begin
  881. vtype:=vtString;
  882. vaddr:=true;
  883. freetemp:=false;
  884. end
  885. else
  886. if is_ansistring(lt) then
  887. begin
  888. vtype:=vtAnsiString;
  889. freetemp:=false;
  890. end
  891. else
  892. if is_widestring(lt) then
  893. begin
  894. vtype:=vtWideString;
  895. freetemp:=false;
  896. end;
  897. end;
  898. end;
  899. if vtype=$ff then
  900. internalerror(14357);
  901. { write C style pushes or an pascal array }
  902. if nf_cargs in flags then
  903. begin
  904. if vaddr then
  905. begin
  906. location_force_mem(exprasmlist,hp.left.location);
  907. location_release(exprasmlist,hp.left.location);
  908. cg.a_paramaddr_ref(exprasmlist,hp.left.location.reference,paraloc);
  909. if freetemp then
  910. location_freetemp(exprasmlist,hp.left.location);
  911. inc(pushedparasize,pointer_size);
  912. end
  913. else
  914. if vtype in [vtInt64,vtQword,vtExtended] then
  915. push_value(hp.left)
  916. else
  917. begin
  918. cg.a_param_loc(exprasmlist,hp.left.location,paraloc);
  919. inc(pushedparasize,pointer_size);
  920. end;
  921. end
  922. else
  923. begin
  924. { write changing field update href to the next element }
  925. inc(href.offset,4);
  926. if vaddr then
  927. begin
  928. location_force_mem(exprasmlist,hp.left.location);
  929. location_release(exprasmlist,hp.left.location);
  930. tmpreg:=rg.getaddressregister(exprasmlist);
  931. cg.a_loadaddr_ref_reg(exprasmlist,hp.left.location.reference,tmpreg);
  932. rg.ungetregisterint(exprasmlist,tmpreg);
  933. cg.a_load_reg_ref(exprasmlist,OS_ADDR,OS_ADDR,tmpreg,href);
  934. if freetemp then
  935. location_freetemp(exprasmlist,hp.left.location);
  936. end
  937. else
  938. begin
  939. location_release(exprasmlist,hp.left.location);
  940. cg.a_load_loc_ref(exprasmlist,OS_ADDR,hp.left.location,href);
  941. end;
  942. { update href to the vtype field and write it }
  943. dec(href.offset,4);
  944. cg.a_load_const_ref(exprasmlist, OS_INT,vtype,href);
  945. { goto next array element }
  946. inc(href.offset,8);
  947. end;
  948. end
  949. else
  950. { normal array constructor of the same type }
  951. begin
  952. if is_ansistring(left.resulttype.def) or
  953. is_widestring(left.resulttype.def) or
  954. (left.resulttype.def.deftype=variantdef) then
  955. freetemp:=false;
  956. case hp.left.location.loc of
  957. LOC_FPUREGISTER,
  958. LOC_CFPUREGISTER :
  959. begin
  960. location_release(exprasmlist,hp.left.location);
  961. cg.a_loadfpu_reg_ref(exprasmlist,hp.left.location.size,hp.left.location.register,href);
  962. end;
  963. LOC_REFERENCE,
  964. LOC_CREFERENCE :
  965. begin
  966. location_release(exprasmlist,hp.left.location);
  967. cg.g_concatcopy(exprasmlist,hp.left.location.reference,href,elesize,freetemp,false);
  968. end;
  969. else
  970. begin
  971. if hp.left.location.size in [OS_64,OS_S64] then
  972. begin
  973. cg64.a_load64_loc_ref(exprasmlist,hp.left.location,href);
  974. location_release(exprasmlist,hp.left.location);
  975. end
  976. else
  977. begin
  978. location_release(exprasmlist,hp.left.location);
  979. cg.a_load_loc_ref(exprasmlist,hp.left.location.size,hp.left.location,href);
  980. end;
  981. end;
  982. end;
  983. inc(href.offset,elesize);
  984. end;
  985. end;
  986. { load next entry }
  987. hp:=tarrayconstructornode(hp.right);
  988. end;
  989. end;
  990. begin
  991. cloadnode:=tcgloadnode;
  992. cassignmentnode:=tcgassignmentnode;
  993. carrayconstructornode:=tcgarrayconstructornode;
  994. end.
  995. {
  996. $Log$
  997. Revision 1.89 2003-10-01 20:34:48 peter
  998. * procinfo unit contains tprocinfo
  999. * cginfo renamed to cgbase
  1000. * moved cgmessage to verbose
  1001. * fixed ppc and sparc compiles
  1002. Revision 1.88 2003/09/29 20:58:56 peter
  1003. * optimized releasing of registers
  1004. Revision 1.87 2003/09/28 21:46:18 peter
  1005. * fix allocation of threadvar parameter
  1006. Revision 1.86 2003/09/28 17:55:03 peter
  1007. * parent framepointer changed to hidden parameter
  1008. * tloadparentfpnode added
  1009. Revision 1.85 2003/09/28 13:39:38 peter
  1010. * optimized releasing of registers
  1011. Revision 1.84 2003/09/25 21:27:31 peter
  1012. * rearranged threadvar code so the result register is the same
  1013. for the relocated and address loaded variables
  1014. Revision 1.83 2003/09/23 17:56:05 peter
  1015. * locals and paras are allocated in the code generation
  1016. * tvarsym.localloc contains the location of para/local when
  1017. generating code for the current procedure
  1018. Revision 1.82 2003/09/16 16:17:01 peter
  1019. * varspez in calls to push_addr_param
  1020. Revision 1.81 2003/09/14 12:57:10 peter
  1021. * save destroyed registers when calling threadvar helper
  1022. Revision 1.80 2003/09/10 08:31:47 marco
  1023. * Patch from Peter for paraloc
  1024. Revision 1.79 2003/09/03 15:55:00 peter
  1025. * NEWRA branch merged
  1026. Revision 1.78 2003/09/03 11:18:37 florian
  1027. * fixed arm concatcopy
  1028. + arm support in the common compiler sources added
  1029. * moved some generic cg code around
  1030. + tfputype added
  1031. * ...
  1032. Revision 1.77.2.2 2003/08/31 15:46:26 peter
  1033. * more updates for tregister
  1034. Revision 1.77.2.1 2003/08/29 17:28:59 peter
  1035. * next batch of updates
  1036. Revision 1.77 2003/08/20 20:13:08 daniel
  1037. * Fixed the fixed trouble
  1038. Revision 1.76 2003/08/20 20:11:24 daniel
  1039. * Fixed some R_NO trouble
  1040. Revision 1.75 2003/07/20 16:26:43 jonas
  1041. * fix for threadvars with -dnewra
  1042. Revision 1.74 2003/07/06 17:58:22 peter
  1043. * framepointer fixes for sparc
  1044. * parent framepointer code more generic
  1045. Revision 1.73 2003/07/06 15:25:54 jonas
  1046. * newra fix for threadvars
  1047. Revision 1.72 2003/06/15 15:13:12 jonas
  1048. * fixed register allocation for threadvar loads with newra
  1049. Revision 1.71 2003/06/13 21:19:30 peter
  1050. * current_procdef removed, use current_procinfo.procdef instead
  1051. Revision 1.70 2003/06/12 16:43:07 peter
  1052. * newra compiles for sparc
  1053. Revision 1.69 2003/06/09 16:41:52 jonas
  1054. * fixed regvar optimization for call_by_reference parameters (no need
  1055. to load address in another register)
  1056. Revision 1.68 2003/06/08 18:27:15 jonas
  1057. + ability to change the location of a ttempref node with changelocation()
  1058. method. Useful to use instead of copying the contents from one temp to
  1059. another
  1060. + some shortstring optimizations in tassignmentnode that avoid some
  1061. copying (required some shortstring optimizations to be moved from
  1062. resulttype to firstpass, because they work on callnodes and string
  1063. addnodes are only changed to callnodes in the firstpass)
  1064. * allow setting/changing the funcretnode of callnodes after the
  1065. resulttypepass has been done, funcretnode is now a property
  1066. (all of the above should have a quite big effect on callparatemp)
  1067. Revision 1.67 2003/06/07 18:57:04 jonas
  1068. + added freeintparaloc
  1069. * ppc get/freeintparaloc now check whether the parameter regs are
  1070. properly allocated/deallocated (and get an extra list para)
  1071. * ppc a_call_* now internalerrors if pi_do_call is not yet set
  1072. * fixed lot of missing pi_do_call's
  1073. Revision 1.66 2003/06/03 21:11:09 peter
  1074. * cg.a_load_* get a from and to size specifier
  1075. * makeregsize only accepts newregister
  1076. * i386 uses generic tcgnotnode,tcgunaryminus
  1077. Revision 1.65 2003/06/03 13:01:59 daniel
  1078. * Register allocator finished
  1079. Revision 1.64 2003/05/30 23:57:08 peter
  1080. * more sparc cleanup
  1081. * accumulator removed, splitted in function_return_reg (called) and
  1082. function_result_reg (caller)
  1083. Revision 1.63 2003/05/30 23:54:08 jonas
  1084. * forgot to commit, a_load_loc_reg change
  1085. Revision 1.62 2003/05/26 19:38:28 peter
  1086. * generic fpc_shorstr_concat
  1087. + fpc_shortstr_append_shortstr optimization
  1088. Revision 1.61 2003/05/24 11:47:27 jonas
  1089. * fixed framepointer storage: it's now always stored at r1+12, which is
  1090. a place in the link area reserved for compiler use.
  1091. Revision 1.60 2003/05/23 14:27:35 peter
  1092. * remove some unit dependencies
  1093. * current_procinfo changes to store more info
  1094. Revision 1.59 2003/05/15 18:58:53 peter
  1095. * removed selfpointer_offset, vmtpointer_offset
  1096. * tvarsym.adjusted_address
  1097. * address in localsymtable is now in the real direction
  1098. * removed some obsolete globals
  1099. Revision 1.58 2003/05/12 17:22:00 jonas
  1100. * fixed (last?) remaining -tvarsym(X).address to
  1101. tg.direction*tvarsym(X).address...
  1102. Revision 1.57 2003/05/11 21:37:03 peter
  1103. * moved implicit exception frame from ncgutil to psub
  1104. * constructor/destructor helpers moved from cobj/ncgutil to psub
  1105. Revision 1.56 2003/05/11 14:45:12 peter
  1106. * tloadnode does not support objectsymtable,withsymtable anymore
  1107. * withnode cleanup
  1108. * direct with rewritten to use temprefnode
  1109. Revision 1.55 2003/04/29 07:29:14 michael
  1110. + Patch from peter to fix wrong pushing of ansistring function results in open array
  1111. Revision 1.54 2003/04/27 11:21:33 peter
  1112. * aktprocdef renamed to current_procinfo.procdef
  1113. * procinfo renamed to current_procinfo
  1114. * procinfo will now be stored in current_module so it can be
  1115. cleaned up properly
  1116. * gen_main_procsym changed to create_main_proc and release_main_proc
  1117. to also generate a tprocinfo structure
  1118. * fixed unit implicit initfinal
  1119. Revision 1.53 2003/04/27 07:29:50 peter
  1120. * current_procinfo.procdef cleanup, current_procdef is now always nil when parsing
  1121. a new procdef declaration
  1122. * aktprocsym removed
  1123. * lexlevel removed, use symtable.symtablelevel instead
  1124. * implicit init/final code uses the normal genentry/genexit
  1125. * funcret state checking updated for new funcret handling
  1126. Revision 1.52 2003/04/25 20:59:33 peter
  1127. * removed funcretn,funcretsym, function result is now in varsym
  1128. and aliases for result and function name are added using absolutesym
  1129. * vs_hidden parameter for funcret passed in parameter
  1130. * vs_hidden fixes
  1131. * writenode changed to printnode and released from extdebug
  1132. * -vp option added to generate a tree.log with the nodetree
  1133. * nicer printnode for statements, callnode
  1134. Revision 1.51 2003/04/23 20:16:04 peter
  1135. + added currency support based on int64
  1136. + is_64bit for use in cg units instead of is_64bitint
  1137. * removed cgmessage from n386add, replace with internalerrors
  1138. Revision 1.50 2003/04/23 10:12:14 peter
  1139. * allow multi pass2 changed to global boolean instead of node flag
  1140. Revision 1.49 2003/04/22 23:50:22 peter
  1141. * firstpass uses expectloc
  1142. * checks if there are differences between the expectloc and
  1143. location.loc from secondpass in EXTDEBUG
  1144. Revision 1.48 2003/04/22 10:09:35 daniel
  1145. + Implemented the actual register allocator
  1146. + Scratch registers unavailable when new register allocator used
  1147. + maybe_save/maybe_restore unavailable when new register allocator used
  1148. Revision 1.47 2003/04/06 21:11:23 olle
  1149. * changed newasmsymbol to newasmsymboldata for data symbols
  1150. Revision 1.46 2003/03/28 19:16:56 peter
  1151. * generic constructor working for i386
  1152. * remove fixed self register
  1153. * esi added as address register for i386
  1154. Revision 1.45 2003/02/19 22:00:14 daniel
  1155. * Code generator converted to new register notation
  1156. - Horribily outdated todo.txt removed
  1157. Revision 1.44 2003/01/08 18:43:56 daniel
  1158. * Tregister changed into a record
  1159. Revision 1.43 2003/01/05 22:44:14 peter
  1160. * remove a lot of code to support typen in loadn-procsym
  1161. Revision 1.42 2002/12/20 18:13:46 peter
  1162. * fixes for fpu values in arrayconstructor
  1163. Revision 1.41 2002/11/27 20:04:39 peter
  1164. * cdecl array of const fixes
  1165. Revision 1.40 2002/11/25 17:43:18 peter
  1166. * splitted defbase in defutil,symutil,defcmp
  1167. * merged isconvertable and is_equal into compare_defs(_ext)
  1168. * made operator search faster by walking the list only once
  1169. Revision 1.39 2002/11/22 16:22:45 jonas
  1170. * fixed error in my previous commit (the size of the location of the
  1171. funcretnode must be based on the current resulttype of the node and not
  1172. the resulttype defined by the function; these can be different in case
  1173. of "absolute" declarations)
  1174. Revision 1.38 2002/11/18 17:31:54 peter
  1175. * pass proccalloption to ret_in_xxx and push_xxx functions
  1176. Revision 1.37 2002/11/15 21:16:39 jonas
  1177. * proper fix for tw2110, also fixes tb0416 (funcretnode of parent
  1178. function was handled wrong inside nested functions/procedures)
  1179. Revision 1.36 2002/11/15 01:58:51 peter
  1180. * merged changes from 1.0.7 up to 04-11
  1181. - -V option for generating bug report tracing
  1182. - more tracing for option parsing
  1183. - errors for cdecl and high()
  1184. - win32 import stabs
  1185. - win32 records<=8 are returned in eax:edx (turned off by default)
  1186. - heaptrc update
  1187. - more info for temp management in .s file with EXTDEBUG
  1188. Revision 1.35 2002/10/14 19:44:13 peter
  1189. * (hacked) new threadvar relocate code
  1190. Revision 1.34 2002/10/13 11:22:06 florian
  1191. * fixed threadvars
  1192. Revision 1.33 2002/10/03 21:32:02 carl
  1193. * bugfix for 2110 (without -Or), wrong checking was done in returntype
  1194. Revision 1.32 2002/09/30 07:00:46 florian
  1195. * fixes to common code to get the alpha compiler compiled applied
  1196. Revision 1.31 2002/09/26 15:02:05 florian
  1197. + support of passing variants to "array of const"
  1198. Revision 1.30 2002/09/17 18:54:02 jonas
  1199. * a_load_reg_reg() now has two size parameters: source and dest. This
  1200. allows some optimizations on architectures that don't encode the
  1201. register size in the register name.
  1202. Revision 1.29 2002/09/07 15:25:03 peter
  1203. * old logs removed and tabs fixed
  1204. Revision 1.28 2002/09/01 19:26:32 peter
  1205. * fixed register variable loading from parasymtable, the call by
  1206. reference code was moved wrong
  1207. Revision 1.27 2002/09/01 12:15:40 peter
  1208. * fixed loading of procvar of object when the object is initialized
  1209. with 0
  1210. Revision 1.26 2002/08/25 19:25:18 peter
  1211. * sym.insert_in_data removed
  1212. * symtable.insertvardata/insertconstdata added
  1213. * removed insert_in_data call from symtable.insert, it needs to be
  1214. called separatly. This allows to deref the address calculation
  1215. * procedures now calculate the parast addresses after the procedure
  1216. directives are parsed. This fixes the cdecl parast problem
  1217. * push_addr_param has an extra argument that specifies if cdecl is used
  1218. or not
  1219. Revision 1.25 2002/08/23 16:14:48 peter
  1220. * tempgen cleanup
  1221. * tt_noreuse temp type added that will be used in genentrycode
  1222. Revision 1.24 2002/08/17 09:23:35 florian
  1223. * first part of procinfo rewrite
  1224. Revision 1.23 2002/08/14 18:13:28 jonas
  1225. * adapted previous fix to Peter's asmsymbol patch
  1226. Revision 1.22 2002/08/14 18:00:42 jonas
  1227. * fixed tb0403
  1228. Revision 1.21 2002/08/13 21:40:56 florian
  1229. * more fixes for ppc calling conventions
  1230. Revision 1.20 2002/08/11 14:32:26 peter
  1231. * renamed current_library to objectlibrary
  1232. Revision 1.19 2002/08/11 13:24:12 peter
  1233. * saving of asmsymbols in ppu supported
  1234. * asmsymbollist global is removed and moved into a new class
  1235. tasmlibrarydata that will hold the info of a .a file which
  1236. corresponds with a single module. Added librarydata to tmodule
  1237. to keep the library info stored for the module. In the future the
  1238. objectfiles will also be stored to the tasmlibrarydata class
  1239. * all getlabel/newasmsymbol and friends are moved to the new class
  1240. Revision 1.18 2002/08/06 20:55:21 florian
  1241. * first part of ppc calling conventions fix
  1242. Revision 1.17 2002/07/28 09:25:37 carl
  1243. + correct size of parameter (64-bit portability)
  1244. Revision 1.16 2002/07/27 19:53:51 jonas
  1245. + generic implementation of tcg.g_flags2ref()
  1246. * tcg.flags2xxx() now also needs a size parameter
  1247. Revision 1.15 2002/07/20 11:57:54 florian
  1248. * types.pas renamed to defbase.pas because D6 contains a types
  1249. unit so this would conflicts if D6 programms are compiled
  1250. + Willamette/SSE2 instructions to assembler added
  1251. Revision 1.14 2002/07/16 09:17:44 florian
  1252. * threadvar relocation result wasn't handled properly, it could cause
  1253. a crash
  1254. Revision 1.13 2002/07/11 14:41:28 florian
  1255. * start of the new generic parameter handling
  1256. Revision 1.12 2002/07/07 09:52:32 florian
  1257. * powerpc target fixed, very simple units can be compiled
  1258. * some basic stuff for better callparanode handling, far from being finished
  1259. Revision 1.11 2002/07/01 18:46:23 peter
  1260. * internal linker
  1261. * reorganized aasm layer
  1262. Revision 1.10 2002/07/01 16:23:53 peter
  1263. * cg64 patch
  1264. * basics for currency
  1265. * asnode updates for class and interface (not finished)
  1266. Revision 1.9 2002/05/20 13:30:40 carl
  1267. * bugfix of hdisponen (base must be set, not index)
  1268. * more portability fixes
  1269. }