ncgld.pas 54 KB

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