ncgld.pas 52 KB

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