ncgcon.pas 27 KB

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