ncgld.pas 52 KB

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