ncgcon.pas 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 by Florian Klaempfl
  4. Generate assembler for constant nodes which are the same for
  5. 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 ncgcon;
  20. {$i fpcdefs.inc}
  21. interface
  22. uses
  23. node,ncon;
  24. type
  25. tcgrealconstnode = class(trealconstnode)
  26. procedure pass_2;override;
  27. end;
  28. tcgordconstnode = class(tordconstnode)
  29. procedure pass_2;override;
  30. end;
  31. tcgpointerconstnode = class(tpointerconstnode)
  32. procedure pass_2;override;
  33. end;
  34. tcgstringconstnode = class(tstringconstnode)
  35. procedure pass_2;override;
  36. end;
  37. tcgsetconstnode = class(tsetconstnode)
  38. procedure pass_2;override;
  39. end;
  40. tcgnilnode = class(tnilnode)
  41. procedure pass_2;override;
  42. end;
  43. tcgguidconstnode = class(tguidconstnode)
  44. procedure pass_2;override;
  45. end;
  46. implementation
  47. uses
  48. globtype,widestr,systems,
  49. verbose,globals,
  50. symconst,symdef,aasmbase,aasmtai,aasmcpu,defutil,
  51. cpuinfo,cpubase,
  52. cgbase,tgobj,rgobj
  53. {$ifdef delphi}
  54. ,dmisc
  55. {$endif}
  56. ;
  57. {*****************************************************************************
  58. TCGREALCONSTNODE
  59. *****************************************************************************}
  60. procedure tcgrealconstnode.pass_2;
  61. { I suppose the parser/pass_1 must make sure the generated real }
  62. { constants are actually supported by the target processor? (JM) }
  63. const
  64. floattype2ait:array[tfloattype] of taitype=
  65. (ait_real_32bit,ait_real_64bit,ait_real_80bit,ait_comp_64bit,ait_comp_64bit,ait_real_128bit);
  66. var
  67. hp1 : tai;
  68. lastlabel : tasmlabel;
  69. realait : taitype;
  70. begin
  71. location_reset(location,LOC_CREFERENCE,def_cgsize(resulttype.def));
  72. lastlabel:=nil;
  73. realait:=floattype2ait[tfloatdef(resulttype.def).typ];
  74. { const already used ? }
  75. if not assigned(lab_real) then
  76. begin
  77. { tries to find an old entry }
  78. hp1:=tai(Consts.first);
  79. while assigned(hp1) do
  80. begin
  81. if hp1.typ=ait_label then
  82. lastlabel:=tai_label(hp1).l
  83. else
  84. begin
  85. if (hp1.typ=realait) and (lastlabel<>nil) then
  86. begin
  87. if is_number_float(value_real) and
  88. (
  89. ((realait=ait_real_32bit) and (tai_real_32bit(hp1).value=value_real) and is_number_float(tai_real_32bit(hp1).value)) or
  90. ((realait=ait_real_64bit) and (tai_real_64bit(hp1).value=value_real) and is_number_float(tai_real_64bit(hp1).value)) or
  91. ((realait=ait_real_80bit) and (tai_real_80bit(hp1).value=value_real) and is_number_float(tai_real_80bit(hp1).value)) or
  92. {$ifdef cpufloat128}
  93. ((realait=ait_real_128bit) and (tai_real_128bit(hp1).value=value_real) and is_number_float(tai_real_128bit(hp1).value)) or
  94. {$endif cpufloat128}
  95. ((realait=ait_comp_64bit) and (tai_comp_64bit(hp1).value=value_real) and is_number_float(tai_comp_64bit(hp1).value))
  96. ) then
  97. begin
  98. { found! }
  99. lab_real:=lastlabel;
  100. break;
  101. end;
  102. end;
  103. lastlabel:=nil;
  104. end;
  105. hp1:=tai(hp1.next);
  106. end;
  107. { :-(, we must generate a new entry }
  108. if not assigned(lab_real) then
  109. begin
  110. objectlibrary.getdatalabel(lastlabel);
  111. lab_real:=lastlabel;
  112. if (cs_create_smart in aktmoduleswitches) then
  113. Consts.concat(Tai_cut.Create);
  114. consts.concat(tai_align.create(const_align(4)));
  115. Consts.concat(Tai_label.Create(lastlabel));
  116. case realait of
  117. ait_real_32bit :
  118. Consts.concat(Tai_real_32bit.Create(ts32real(value_real)));
  119. ait_real_64bit :
  120. Consts.concat(Tai_real_64bit.Create(ts64real(value_real)));
  121. ait_real_80bit :
  122. Consts.concat(Tai_real_80bit.Create(value_real));
  123. {$ifdef cpufloat128}
  124. ait_real_128bit :
  125. Consts.concat(Tai_real_128bit.Create(value_real));
  126. {$endif cpufloat128}
  127. {$ifdef ver1_0}
  128. ait_comp_64bit :
  129. Consts.concat(Tai_comp_64bit.Create(value_real));
  130. {$else ver1_0}
  131. { the round is necessary for native compilers where comp isn't a float }
  132. ait_comp_64bit :
  133. Consts.concat(Tai_comp_64bit.Create(round(value_real)));
  134. {$endif ver1_0}
  135. else
  136. internalerror(10120);
  137. end;
  138. end;
  139. end;
  140. location.reference.symbol:=lab_real;
  141. end;
  142. {*****************************************************************************
  143. TCGORDCONSTNODE
  144. *****************************************************************************}
  145. procedure tcgordconstnode.pass_2;
  146. begin
  147. location_reset(location,LOC_CONSTANT,def_cgsize(resulttype.def));
  148. location.valueqword:=TConstExprUInt(value);
  149. end;
  150. {*****************************************************************************
  151. TCGPOINTERCONSTNODE
  152. *****************************************************************************}
  153. procedure tcgpointerconstnode.pass_2;
  154. begin
  155. { an integer const. behaves as a memory reference }
  156. location_reset(location,LOC_CONSTANT,OS_ADDR);
  157. location.value:=AWord(value);
  158. end;
  159. {*****************************************************************************
  160. TCGSTRINGCONSTNODE
  161. *****************************************************************************}
  162. procedure tcgstringconstnode.pass_2;
  163. var
  164. hp1,hp2 : tai;
  165. l1,l2,
  166. lastlabel : tasmlabel;
  167. lastlabelhp : tai;
  168. pc : pchar;
  169. same_string : boolean;
  170. l,j,
  171. i,mylength : longint;
  172. begin
  173. { for empty ansistrings we could return a constant 0 }
  174. if (st_type in [st_ansistring,st_widestring]) and
  175. (len=0) then
  176. begin
  177. location_reset(location,LOC_CONSTANT,OS_ADDR);
  178. location.value:=0;
  179. exit;
  180. end;
  181. { return a constant reference in memory }
  182. location_reset(location,LOC_CREFERENCE,def_cgsize(resulttype.def));
  183. { const already used ? }
  184. lastlabel:=nil;
  185. lastlabelhp:=nil;
  186. if not assigned(lab_str) then
  187. begin
  188. if is_shortstring(resulttype.def) then
  189. mylength:=len+2
  190. else
  191. mylength:=len+1;
  192. { widestrings can't be reused yet }
  193. if not(is_widestring(resulttype.def)) then
  194. begin
  195. { tries to found an old entry }
  196. hp1:=tai(Consts.first);
  197. while assigned(hp1) do
  198. begin
  199. if hp1.typ=ait_label then
  200. begin
  201. lastlabel:=tai_label(hp1).l;
  202. lastlabelhp:=hp1;
  203. end
  204. else
  205. begin
  206. { when changing that code, be careful that }
  207. { you don't use typed consts, which are }
  208. { are also written to consts }
  209. { currently, this is no problem, because }
  210. { typed consts have no leading length or }
  211. { they have no trailing zero }
  212. if (hp1.typ=ait_string) and (lastlabel<>nil) and
  213. (tai_string(hp1).len=mylength) then
  214. begin
  215. same_string:=true;
  216. { if shortstring then check the length byte first and
  217. set the start index to 1 }
  218. case st_type of
  219. st_shortstring:
  220. begin
  221. if len=ord(tai_string(hp1).str[0]) then
  222. j:=1
  223. else
  224. same_string:=false;
  225. end;
  226. st_ansistring,
  227. st_widestring :
  228. begin
  229. { before the string the following sequence must be found:
  230. <label>
  231. constsymbol <datalabel>
  232. const32 <len>
  233. const32 <len>
  234. const32 -1
  235. we must then return <label> to reuse
  236. }
  237. hp2:=tai(lastlabelhp.previous);
  238. if assigned(hp2) and
  239. (hp2.typ=ait_const_32bit) and
  240. (tai_const(hp2).value=-1) and
  241. assigned(hp2.previous) and
  242. (tai(hp2.previous).typ=ait_const_32bit) and
  243. (tai_const(hp2.previous).value=len) and
  244. assigned(hp2.previous.previous) and
  245. (tai(hp2.previous.previous).typ=ait_const_32bit) and
  246. (tai_const(hp2.previous.previous).value=len) and
  247. assigned(hp2.previous.previous.previous) and
  248. (tai(hp2.previous.previous.previous).typ=ait_const_symbol) and
  249. assigned(hp2.previous.previous.previous.previous) and
  250. (tai(hp2.previous.previous.previous.previous).typ=ait_label) then
  251. begin
  252. lastlabel:=tai_label(hp2.previous.previous.previous.previous).l;
  253. j:=0;
  254. end
  255. else
  256. same_string:=false;
  257. end;
  258. else
  259. same_string:=false;
  260. end;
  261. { don't check if the length byte was already wrong }
  262. if same_string then
  263. begin
  264. for i:=0 to len do
  265. begin
  266. if tai_string(hp1).str[j]<>value_str[i] then
  267. begin
  268. same_string:=false;
  269. break;
  270. end;
  271. inc(j);
  272. end;
  273. end;
  274. { found ? }
  275. if same_string then
  276. begin
  277. lab_str:=lastlabel;
  278. break;
  279. end;
  280. end;
  281. lastlabel:=nil;
  282. end;
  283. hp1:=tai(hp1.next);
  284. end;
  285. end;
  286. { :-(, we must generate a new entry }
  287. if not assigned(lab_str) then
  288. begin
  289. objectlibrary.getdatalabel(lastlabel);
  290. lab_str:=lastlabel;
  291. if (cs_create_smart in aktmoduleswitches) then
  292. Consts.concat(Tai_cut.Create);
  293. consts.concat(tai_align.create(const_align(4)));
  294. Consts.concat(Tai_label.Create(lastlabel));
  295. { generate an ansi string ? }
  296. case st_type of
  297. st_ansistring:
  298. begin
  299. { an empty ansi string is nil! }
  300. if len=0 then
  301. Consts.concat(Tai_const.Create_32bit(0))
  302. else
  303. begin
  304. objectlibrary.getdatalabel(l1);
  305. objectlibrary.getdatalabel(l2);
  306. Consts.concat(Tai_label.Create(l2));
  307. Consts.concat(Tai_const_symbol.Create(l1));
  308. Consts.concat(Tai_const.Create_32bit(len));
  309. Consts.concat(Tai_const.Create_32bit(len));
  310. Consts.concat(Tai_const.Create_32bit(-1));
  311. Consts.concat(Tai_label.Create(l1));
  312. getmem(pc,len+2);
  313. move(value_str^,pc^,len);
  314. pc[len]:=#0;
  315. { to overcome this problem we set the length explicitly }
  316. { with the ending null char }
  317. Consts.concat(Tai_string.Create_length_pchar(pc,len+1));
  318. { return the offset of the real string }
  319. lab_str:=l2;
  320. end;
  321. end;
  322. st_widestring:
  323. begin
  324. { an empty wide string is nil! }
  325. if len=0 then
  326. Consts.concat(Tai_const.Create_32bit(0))
  327. else
  328. begin
  329. objectlibrary.getdatalabel(l1);
  330. objectlibrary.getdatalabel(l2);
  331. Consts.concat(Tai_label.Create(l2));
  332. Consts.concat(Tai_const_symbol.Create(l1));
  333. { we use always UTF-16 coding for constants }
  334. { at least for now }
  335. { Consts.concat(Tai_const.Create_8bit(2)); }
  336. Consts.concat(Tai_const.Create_32bit(len));
  337. Consts.concat(Tai_const.Create_32bit(len));
  338. Consts.concat(Tai_const.Create_32bit(-1));
  339. Consts.concat(Tai_label.Create(l1));
  340. for i:=0 to len-1 do
  341. Consts.concat(Tai_const.Create_16bit(pcompilerwidestring(value_str)^.data[i]));
  342. { terminating zero }
  343. Consts.concat(Tai_const.Create_16bit(0));
  344. { return the offset of the real string }
  345. lab_str:=l2;
  346. end;
  347. end;
  348. st_shortstring:
  349. begin
  350. { truncate strings larger than 255 chars }
  351. if len>255 then
  352. l:=255
  353. else
  354. l:=len;
  355. { also length and terminating zero }
  356. getmem(pc,l+3);
  357. move(value_str^,pc[1],l+1);
  358. pc[0]:=chr(l);
  359. { to overcome this problem we set the length explicitly }
  360. { with the ending null char }
  361. pc[l+1]:=#0;
  362. Consts.concat(Tai_string.Create_length_pchar(pc,l+2));
  363. end;
  364. end;
  365. end;
  366. end;
  367. location.reference.symbol:=lab_str;
  368. end;
  369. {*****************************************************************************
  370. TCGSETCONSTNODE
  371. *****************************************************************************}
  372. procedure tcgsetconstnode.pass_2;
  373. var
  374. hp1 : tai;
  375. lastlabel : tasmlabel;
  376. i : longint;
  377. neededtyp : taitype;
  378. indexadjust : longint;
  379. type
  380. setbytes=array[0..31] of byte;
  381. Psetbytes=^setbytes;
  382. begin
  383. { xor indexadjust with indexes in a set typecasted to an array of }
  384. { bytes to get the correct locations, also when endianess of source }
  385. { and destiantion differs (JM) }
  386. if (source_info.endian = target_info.endian) then
  387. indexadjust := 0
  388. else
  389. indexadjust := 3;
  390. { small sets are loaded as constants }
  391. if tsetdef(resulttype.def).settype=smallset then
  392. begin
  393. location_reset(location,LOC_CONSTANT,OS_32);
  394. location.value:=PAWord(value_set)^;
  395. exit;
  396. end;
  397. location_reset(location,LOC_CREFERENCE,OS_NO);
  398. neededtyp:=ait_const_8bit;
  399. lastlabel:=nil;
  400. { const already used ? }
  401. if not assigned(lab_set) then
  402. begin
  403. { tries to found an old entry }
  404. hp1:=tai(Consts.first);
  405. while assigned(hp1) do
  406. begin
  407. if hp1.typ=ait_label then
  408. lastlabel:=tai_label(hp1).l
  409. else
  410. begin
  411. if (lastlabel<>nil) and (hp1.typ=neededtyp) then
  412. begin
  413. if (hp1.typ=ait_const_8bit) then
  414. begin
  415. { compare normal set }
  416. i:=0;
  417. while assigned(hp1) and (i<32) do
  418. begin
  419. if tai_const(hp1).value<>Psetbytes(value_set)^[i xor indexadjust] then
  420. break;
  421. inc(i);
  422. hp1:=tai(hp1.next);
  423. end;
  424. if i=32 then
  425. begin
  426. { found! }
  427. lab_set:=lastlabel;
  428. break;
  429. end;
  430. { leave when the end of consts is reached, so no
  431. hp1.next is done }
  432. if not assigned(hp1) then
  433. break;
  434. end
  435. else
  436. begin
  437. { compare small set }
  438. if plongint(value_set)^=tai_const(hp1).value then
  439. begin
  440. { found! }
  441. lab_set:=lastlabel;
  442. break;
  443. end;
  444. end;
  445. end;
  446. lastlabel:=nil;
  447. end;
  448. hp1:=tai(hp1.next);
  449. end;
  450. { :-(, we must generate a new entry }
  451. if not assigned(lab_set) then
  452. begin
  453. objectlibrary.getdatalabel(lastlabel);
  454. lab_set:=lastlabel;
  455. if (cs_create_smart in aktmoduleswitches) then
  456. Consts.concat(Tai_cut.Create);
  457. consts.concat(tai_align.create(const_align(4)));
  458. Consts.concat(Tai_label.Create(lastlabel));
  459. { already handled at the start of this method?? (JM)
  460. if tsetdef(resulttype.def).settype=smallset then
  461. begin
  462. move(value_set^,i,sizeof(longint));
  463. Consts.concat(Tai_const.Create_32bit(i));
  464. end
  465. else
  466. }
  467. begin
  468. for i:=0 to 31 do
  469. Consts.concat(Tai_const.Create_8bit(Psetbytes(value_set)^[i xor indexadjust]));
  470. end;
  471. end;
  472. end;
  473. location.reference.symbol:=lab_set;
  474. end;
  475. {*****************************************************************************
  476. TCGNILNODE
  477. *****************************************************************************}
  478. procedure tcgnilnode.pass_2;
  479. begin
  480. location_reset(location,LOC_CONSTANT,OS_ADDR);
  481. location.value:=0;
  482. end;
  483. {*****************************************************************************
  484. TCGPOINTERCONSTNODE
  485. *****************************************************************************}
  486. procedure tcgguidconstnode.pass_2;
  487. var
  488. tmplabel : TAsmLabel;
  489. i : integer;
  490. begin
  491. location_reset(location,LOC_CREFERENCE,OS_NO);
  492. { label for GUID }
  493. objectlibrary.getdatalabel(tmplabel);
  494. consts.concat(tai_align.create(const_align(16)));
  495. consts.concat(Tai_label.Create(tmplabel));
  496. consts.concat(Tai_const.Create_32bit(value.D1));
  497. consts.concat(Tai_const.Create_16bit(value.D2));
  498. consts.concat(Tai_const.Create_16bit(value.D3));
  499. for i:=Low(value.D4) to High(value.D4) do
  500. consts.concat(Tai_const.Create_8bit(value.D4[i]));
  501. location.reference.symbol:=tmplabel;
  502. end;
  503. begin
  504. crealconstnode:=tcgrealconstnode;
  505. cordconstnode:=tcgordconstnode;
  506. cpointerconstnode:=tcgpointerconstnode;
  507. cstringconstnode:=tcgstringconstnode;
  508. csetconstnode:=tcgsetconstnode;
  509. cnilnode:=tcgnilnode;
  510. cguidconstnode:=tcgguidconstnode;
  511. end.
  512. {
  513. $Log$
  514. Revision 1.31 2003-10-01 20:34:48 peter
  515. * procinfo unit contains tprocinfo
  516. * cginfo renamed to cgbase
  517. * moved cgmessage to verbose
  518. * fixed ppc and sparc compiles
  519. Revision 1.30 2003/09/06 16:47:24 florian
  520. + support of NaN and Inf in the compiler as values of real constants
  521. Revision 1.29 2003/09/03 15:55:00 peter
  522. * NEWRA branch merged
  523. Revision 1.28 2003/05/01 12:24:22 jonas
  524. * fixed endian issues when writing out set constants
  525. Revision 1.27 2003/04/24 22:29:57 florian
  526. * fixed a lot of PowerPC related stuff
  527. Revision 1.26 2003/01/05 13:36:53 florian
  528. * x86-64 compiles
  529. + very basic support for float128 type (x86-64 only)
  530. Revision 1.25 2002/12/29 16:58:11 peter
  531. * write terminating 0 for widestring constants
  532. Revision 1.24 2002/12/07 14:10:21 carl
  533. * fix warnings by adding explicit typecasts
  534. Revision 1.23 2002/11/25 17:43:17 peter
  535. * splitted defbase in defutil,symutil,defcmp
  536. * merged isconvertable and is_equal into compare_defs(_ext)
  537. * made operator search faster by walking the list only once
  538. Revision 1.22 2002/11/09 15:36:50 carl
  539. * align all constants correctly (default of 4 size for real type constants)
  540. Revision 1.21 2002/10/06 21:01:50 peter
  541. * use tconstexpruint instead of qword
  542. Revision 1.20 2002/10/05 12:43:25 carl
  543. * fixes for Delphi 6 compilation
  544. (warning : Some features do not work under Delphi)
  545. Revision 1.19 2002/08/18 20:06:23 peter
  546. * inlining is now also allowed in interface
  547. * renamed write/load to ppuwrite/ppuload
  548. * tnode storing in ppu
  549. * nld,ncon,nbas are already updated for storing in ppu
  550. Revision 1.18 2002/08/11 14:32:26 peter
  551. * renamed current_library to objectlibrary
  552. Revision 1.17 2002/08/11 13:24:11 peter
  553. * saving of asmsymbols in ppu supported
  554. * asmsymbollist global is removed and moved into a new class
  555. tasmlibrarydata that will hold the info of a .a file which
  556. corresponds with a single module. Added librarydata to tmodule
  557. to keep the library info stored for the module. In the future the
  558. objectfiles will also be stored to the tasmlibrarydata class
  559. * all getlabel/newasmsymbol and friends are moved to the new class
  560. Revision 1.16 2002/08/10 17:15:06 jonas
  561. * endianess fix
  562. Revision 1.15 2002/07/23 12:34:30 daniel
  563. * Readded old set code. To use it define 'oldset'. Activated by default
  564. for ppc.
  565. Revision 1.14 2002/07/22 11:48:04 daniel
  566. * Sets are now internally sets.
  567. Revision 1.13 2002/07/20 11:57:53 florian
  568. * types.pas renamed to defbase.pas because D6 contains a types
  569. unit so this would conflicts if D6 programms are compiled
  570. + Willamette/SSE2 instructions to assembler added
  571. Revision 1.12 2002/07/01 18:46:22 peter
  572. * internal linker
  573. * reorganized aasm layer
  574. Revision 1.11 2002/07/01 16:23:53 peter
  575. * cg64 patch
  576. * basics for currency
  577. * asnode updates for class and interface (not finished)
  578. Revision 1.10 2002/05/18 13:34:09 peter
  579. * readded missing revisions
  580. Revision 1.9 2002/05/16 19:46:37 carl
  581. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  582. + try to fix temp allocation (still in ifdef)
  583. + generic constructor calls
  584. + start of tassembler / tmodulebase class cleanup
  585. Revision 1.7 2002/04/04 19:05:57 peter
  586. * removed unused units
  587. * use tlocation.size in cg.a_*loc*() routines
  588. Revision 1.6 2002/04/02 17:11:28 peter
  589. * tlocation,treference update
  590. * LOC_CONSTANT added for better constant handling
  591. * secondadd splitted in multiple routines
  592. * location_force_reg added for loading a location to a register
  593. of a specified size
  594. * secondassignment parses now first the right and then the left node
  595. (this is compatible with Kylix). This saves a lot of push/pop especially
  596. with string operations
  597. * adapted some routines to use the new cg methods
  598. Revision 1.5 2002/03/31 20:26:34 jonas
  599. + a_loadfpu_* and a_loadmm_* methods in tcg
  600. * register allocation is now handled by a class and is mostly processor
  601. independent (+rgobj.pas and i386/rgcpu.pas)
  602. * temp allocation is now handled by a class (+tgobj.pas, -i386\tgcpu.pas)
  603. * some small improvements and fixes to the optimizer
  604. * some register allocation fixes
  605. * some fpuvaroffset fixes in the unary minus node
  606. * push/popusedregisters is now called rg.save/restoreusedregisters and
  607. (for i386) uses temps instead of push/pop's when using -Op3 (that code is
  608. also better optimizable)
  609. * fixed and optimized register saving/restoring for new/dispose nodes
  610. * LOC_FPU locations now also require their "register" field to be set to
  611. R_ST, not R_ST0 (the latter is used for LOC_CFPUREGISTER locations only)
  612. - list field removed of the tnode class because it's not used currently
  613. and can cause hard-to-find bugs
  614. Revision 1.4 2002/02/26 09:12:39 jonas
  615. * fixed problem when compiling the compiler with Delphi (reported by
  616. "Luc Langlois" <[email protected]>) (lo/hi don't work as in FPC
  617. when used with int64's under Delphi)
  618. }