ncgld.pas 52 KB

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