ncgld.pas 52 KB

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