ncgld.pas 52 KB

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