ncgld.pas 53 KB

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