ncgld.pas 53 KB

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