ncgld.pas 52 KB

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