ncgld.pas 56 KB

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