ncgld.pas 52 KB

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