ncgcnv.pas 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653
  1. {
  2. $Id$
  3. Copyright (c) 2000-2002 by Florian Klaempfl
  4. Generate assembler for nodes that handle type conversions which are
  5. 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 ncgcnv;
  20. {$i fpcdefs.inc}
  21. interface
  22. uses
  23. node,ncnv,defbase;
  24. type
  25. tcgtypeconvnode = class(ttypeconvnode)
  26. procedure second_int_to_int;override;
  27. procedure second_cstring_to_pchar;override;
  28. procedure second_string_to_chararray;override;
  29. procedure second_array_to_pointer;override;
  30. procedure second_pointer_to_array;override;
  31. procedure second_char_to_string;override;
  32. procedure second_real_to_real;override;
  33. procedure second_cord_to_pointer;override;
  34. procedure second_proc_to_procvar;override;
  35. procedure second_bool_to_int;override;
  36. procedure second_bool_to_bool;override;
  37. procedure second_ansistring_to_pchar;override;
  38. procedure second_class_to_intf;override;
  39. procedure second_char_to_char;override;
  40. procedure second_nothing;override;
  41. {$ifdef TESTOBJEXT2}
  42. procedure checkobject;virtual;
  43. {$endif TESTOBJEXT2}
  44. procedure second_call_helper(c : tconverttype);virtual;abstract;
  45. procedure pass_2;override;
  46. end;
  47. tcgasnode = class(tasnode)
  48. procedure pass_2;override;
  49. end;
  50. implementation
  51. uses
  52. cutils,verbose,
  53. aasmbase,aasmtai,aasmcpu,symconst,symdef,paramgr,
  54. ncon,ncal,
  55. cpubase,cpuinfo,cpupara,
  56. pass_2,
  57. cginfo,cgbase,
  58. cgobj,cgcpu,
  59. ncgutil,
  60. tgobj,rgobj
  61. ;
  62. procedure tcgtypeconvnode.second_int_to_int;
  63. var
  64. newsize : tcgsize;
  65. begin
  66. newsize:=def_cgsize(resulttype.def);
  67. { insert range check if not explicit conversion }
  68. if not(nf_explizit in flags) then
  69. cg.g_rangecheck(exprasmlist,left,resulttype.def);
  70. { is the result size smaller ? }
  71. if resulttype.def.size<>left.resulttype.def.size then
  72. begin
  73. { reuse the left location by default }
  74. location_copy(location,left.location);
  75. location_force_reg(exprasmlist,location,newsize,false);
  76. end
  77. else
  78. begin
  79. { no special loading is required, reuse current location }
  80. location_copy(location,left.location);
  81. location.size:=newsize;
  82. end;
  83. end;
  84. procedure tcgtypeconvnode.second_cstring_to_pchar;
  85. var
  86. hr : treference;
  87. begin
  88. location_release(exprasmlist,left.location);
  89. location_reset(location,LOC_REGISTER,OS_ADDR);
  90. case tstringdef(left.resulttype.def).string_typ of
  91. st_shortstring :
  92. begin
  93. inc(left.location.reference.offset);
  94. location.register:=rg.getaddressregister(exprasmlist);
  95. cg.a_loadaddr_ref_reg(exprasmlist,left.location.reference,location.register);
  96. end;
  97. st_ansistring :
  98. begin
  99. if (left.nodetype=stringconstn) and
  100. (str_length(left)=0) then
  101. begin
  102. reference_reset(hr);
  103. hr.symbol:=objectlibrary.newasmsymbol('FPC_EMPTYCHAR');
  104. location.register:=rg.getaddressregister(exprasmlist);
  105. cg.a_loadaddr_ref_reg(exprasmlist,hr,location.register);
  106. end
  107. else
  108. begin
  109. location.register:=rg.getaddressregister(exprasmlist);
  110. cg.a_load_ref_reg(exprasmlist,OS_ADDR,left.location.reference,location.register);
  111. end;
  112. end;
  113. st_longstring:
  114. begin
  115. {!!!!!!!}
  116. internalerror(8888);
  117. end;
  118. st_widestring:
  119. begin
  120. if (left.nodetype=stringconstn) and
  121. (str_length(left)=0) then
  122. begin
  123. reference_reset(hr);
  124. hr.symbol:=objectlibrary.newasmsymbol('FPC_EMPTYCHAR');
  125. location.register:=rg.getaddressregister(exprasmlist);
  126. cg.a_loadaddr_ref_reg(exprasmlist,hr,location.register);
  127. end
  128. else
  129. begin
  130. location.register:=rg.getregisterint(exprasmlist);
  131. {$warning Todo: convert widestrings to ascii when typecasting them to pchars}
  132. cg.a_load_ref_reg(exprasmlist,OS_ADDR,left.location.reference,
  133. location.register);
  134. end;
  135. end;
  136. end;
  137. end;
  138. procedure tcgtypeconvnode.second_string_to_chararray;
  139. var
  140. arrsize: longint;
  141. begin
  142. with tarraydef(resulttype.def) do
  143. arrsize := highrange-lowrange+1;
  144. if (left.nodetype = stringconstn) and
  145. { left.length+1 since there's always a terminating #0 character (JM) }
  146. (tstringconstnode(left).len+1 >= arrsize) and
  147. (tstringdef(left.resulttype.def).string_typ=st_shortstring) then
  148. begin
  149. location_copy(location,left.location);
  150. inc(location.reference.offset);
  151. exit;
  152. end
  153. else
  154. { should be handled already in resulttype pass (JM) }
  155. internalerror(200108292);
  156. end;
  157. procedure tcgtypeconvnode.second_array_to_pointer;
  158. begin
  159. location_release(exprasmlist,left.location);
  160. location_reset(location,LOC_REGISTER,OS_ADDR);
  161. location.register:=rg.getaddressregister(exprasmlist);
  162. cg.a_loadaddr_ref_reg(exprasmlist,left.location.reference,location.register);
  163. end;
  164. procedure tcgtypeconvnode.second_pointer_to_array;
  165. begin
  166. location_reset(location,LOC_REFERENCE,OS_NO);
  167. case left.location.loc of
  168. LOC_REGISTER :
  169. begin
  170. if not rg.isaddressregister(left.location.register) then
  171. begin
  172. location_release(exprasmlist,left.location);
  173. location.reference.base:=rg.getaddressregister(exprasmlist);
  174. cg.a_load_reg_reg(exprasmlist,OS_ADDR,
  175. left.location.register,location.reference.base);
  176. end
  177. else
  178. location.reference.base := left.location.register;
  179. end;
  180. LOC_CREGISTER :
  181. begin
  182. location.reference.base:=rg.getregisterint(exprasmlist);
  183. cg.a_load_reg_reg(exprasmlist,OS_ADDR,left.location.register,
  184. location.reference.base);
  185. end;
  186. LOC_REFERENCE,
  187. LOC_CREFERENCE :
  188. begin
  189. location_release(exprasmlist,left.location);
  190. location.reference.base:=rg.getaddressregister(exprasmlist);
  191. cg.a_load_ref_reg(exprasmlist,OS_ADDR,left.location.reference,
  192. location.reference.base);
  193. end;
  194. else
  195. internalerror(2002032216);
  196. end;
  197. end;
  198. procedure tcgtypeconvnode.second_char_to_string;
  199. begin
  200. location_reset(location,LOC_REFERENCE,OS_NO);
  201. case tstringdef(resulttype.def).string_typ of
  202. st_shortstring :
  203. begin
  204. tg.gettempofsizereference(exprasmlist,256,location.reference);
  205. cg.a_load_loc_ref(exprasmlist,left.location,
  206. location.reference);
  207. location_release(exprasmlist,left.location);
  208. end;
  209. { the rest is removed in the resulttype pass and converted to compilerprocs }
  210. else
  211. internalerror(4179);
  212. end;
  213. end;
  214. procedure tcgtypeconvnode.second_real_to_real;
  215. begin
  216. location_reset(location,LOC_FPUREGISTER,def_cgsize(resulttype.def));
  217. case left.location.loc of
  218. LOC_FPUREGISTER,
  219. LOC_CFPUREGISTER:
  220. begin
  221. location_copy(location,left.location);
  222. location.size:=def_cgsize(resulttype.def);
  223. exit;
  224. end;
  225. LOC_CREFERENCE,
  226. LOC_REFERENCE:
  227. begin
  228. location_release(exprasmlist,left.location);
  229. location.register:=rg.getregisterfpu(exprasmlist);
  230. cg.a_loadfpu_loc_reg(exprasmlist,left.location,location.register);
  231. end;
  232. else
  233. internalerror(2002032215);
  234. end;
  235. end;
  236. procedure tcgtypeconvnode.second_cord_to_pointer;
  237. begin
  238. { this can't happen because constants are already processed in
  239. pass 1 }
  240. internalerror(47423985);
  241. end;
  242. procedure tcgtypeconvnode.second_proc_to_procvar;
  243. begin
  244. { method pointer ? }
  245. if assigned(tunarynode(left).left) then
  246. begin
  247. location_copy(location,left.location);
  248. end
  249. else
  250. begin
  251. location_release(exprasmlist,left.location);
  252. location_reset(location,LOC_REGISTER,OS_ADDR);
  253. location.register:=rg.getaddressregister(exprasmlist);
  254. cg.a_loadaddr_ref_reg(exprasmlist,left.location.reference,location.register);
  255. end;
  256. end;
  257. procedure tcgtypeconvnode.second_bool_to_int;
  258. var
  259. oldtruelabel,oldfalselabel : tasmlabel;
  260. begin
  261. oldtruelabel:=truelabel;
  262. oldfalselabel:=falselabel;
  263. objectlibrary.getlabel(truelabel);
  264. objectlibrary.getlabel(falselabel);
  265. secondpass(left);
  266. location_copy(location,left.location);
  267. { byte(boolean) or word(wordbool) or longint(longbool) must }
  268. { be accepted for var parameters }
  269. if not((nf_explizit in flags) and
  270. (left.resulttype.def.size=resulttype.def.size) and
  271. (left.location.loc in [LOC_REFERENCE,LOC_CREFERENCE,LOC_CREGISTER])) then
  272. location_force_reg(exprasmlist,location,def_cgsize(resulttype.def),false);
  273. truelabel:=oldtruelabel;
  274. falselabel:=oldfalselabel;
  275. end;
  276. procedure tcgtypeconvnode.second_bool_to_bool;
  277. begin
  278. { we can reuse the conversion already available
  279. in bool_to_int to resize the value. But when the
  280. size of the new boolean is smaller we need to calculate
  281. the value as is done in int_to_bool. This is needed because
  282. the bits that define the true status can be outside the limits
  283. of the new size and truncating the register can result in a 0
  284. value }
  285. if resulttype.def.size<left.resulttype.def.size then
  286. second_int_to_bool
  287. else
  288. second_bool_to_int;
  289. end;
  290. procedure tcgtypeconvnode.second_ansistring_to_pchar;
  291. var
  292. l1 : tasmlabel;
  293. hr : treference;
  294. hd : tobjectdef;
  295. begin
  296. location_reset(location,LOC_REGISTER,OS_ADDR);
  297. objectlibrary.getlabel(l1);
  298. case left.location.loc of
  299. LOC_CREGISTER,LOC_REGISTER:
  300. begin
  301. if not rg.isaddressregister(left.location.register) then
  302. begin
  303. location_release(exprasmlist,left.location);
  304. location.register:=rg.getaddressregister(exprasmlist);
  305. cg.a_load_reg_reg(exprasmlist,OS_ADDR,
  306. left.location.register,location.register);
  307. end
  308. else
  309. location.register := left.location.register;
  310. end;
  311. LOC_CREFERENCE,LOC_REFERENCE:
  312. begin
  313. location_release(exprasmlist,left.location);
  314. location.register:=rg.getaddressregister(exprasmlist);
  315. cg.a_load_ref_reg(exprasmlist,OS_32,left.location.reference,location.register);
  316. end;
  317. else
  318. internalerror(2002032214);
  319. end;
  320. cg.a_cmp_const_reg_label(exprasmlist,OS_32,OC_NE,0,location.register,l1);
  321. reference_reset(hr);
  322. hr.symbol:=objectlibrary.newasmsymbol('FPC_EMPTYCHAR');
  323. cg.a_loadaddr_ref_reg(exprasmlist,hr,location.register);
  324. cg.a_label(exprasmlist,l1);
  325. end;
  326. procedure tcgtypeconvnode.second_class_to_intf;
  327. var
  328. l1 : tasmlabel;
  329. hd : tobjectdef;
  330. begin
  331. location_reset(location,LOC_REGISTER,OS_ADDR);
  332. case left.location.loc of
  333. LOC_CREFERENCE,
  334. LOC_REFERENCE:
  335. begin
  336. location_release(exprasmlist,left.location);
  337. location.register:=rg.getregisterint(exprasmlist);
  338. cg.a_load_ref_reg(exprasmlist,OS_ADDR,left.location.reference,location.register);
  339. end;
  340. LOC_CREGISTER:
  341. begin
  342. location.register:=rg.getregisterint(exprasmlist);
  343. cg.a_load_reg_reg(exprasmlist,OS_ADDR,left.location.register,location.register);
  344. end;
  345. LOC_REGISTER:
  346. location.register:=left.location.register;
  347. else
  348. internalerror(121120001);
  349. end;
  350. objectlibrary.getlabel(l1);
  351. cg.a_cmp_const_reg_label(exprasmlist,OS_ADDR,OC_EQ,0,location.register,l1);
  352. hd:=tobjectdef(left.resulttype.def);
  353. while assigned(hd) do
  354. begin
  355. if hd.implementedinterfaces.searchintf(resulttype.def)<>-1 then
  356. begin
  357. cg.a_op_const_reg(exprasmlist,OP_ADD,aword(
  358. hd.implementedinterfaces.ioffsets(
  359. hd.implementedinterfaces.searchintf(
  360. resulttype.def))^),location.register);
  361. break;
  362. end;
  363. hd:=hd.childof;
  364. end;
  365. if hd=nil then
  366. internalerror(2002081301);
  367. cg.a_label(exprasmlist,l1);
  368. end;
  369. procedure tcgtypeconvnode.second_char_to_char;
  370. begin
  371. {$warning todo: add RTL routine for widechar-char conversion }
  372. { Quick hack to atleast generate 'working' code (PFV) }
  373. second_int_to_int;
  374. end;
  375. procedure tcgtypeconvnode.second_nothing;
  376. begin
  377. { we reuse the old value }
  378. location_copy(location,left.location);
  379. { Floats should never be returned as LOC_CONSTANT, do the
  380. moving to memory before the new size is set }
  381. if (resulttype.def.deftype=floatdef) and
  382. (location.loc=LOC_CONSTANT) then
  383. location_force_mem(exprasmlist,location);
  384. { but use the new size, but we don't know the size of all arrays }
  385. location.size:=def_cgsize(resulttype.def);
  386. end;
  387. {$ifdef TESTOBJEXT2}
  388. procedure tcgtypeconvnode.checkobject;
  389. begin
  390. { no checking by default }
  391. end;
  392. {$endif TESTOBJEXT2}
  393. procedure tcgtypeconvnode.pass_2;
  394. begin
  395. { the boolean routines can be called with LOC_JUMP and
  396. call secondpass themselves in the helper }
  397. if not(convtype in [tc_bool_2_int,tc_bool_2_bool,tc_int_2_bool]) then
  398. begin
  399. secondpass(left);
  400. if codegenerror then
  401. exit;
  402. end;
  403. second_call_helper(convtype);
  404. {$ifdef TESTOBJEXT2}
  405. { Check explicit conversions to objects pointers !! }
  406. if p^.explizit and
  407. (p^.resulttype.def.deftype=pointerdef) and
  408. (tpointerdef(p^.resulttype.def).definition.deftype=objectdef) and not
  409. (tobjectdef(tpointerdef(p^.resulttype.def).definition).isclass) and
  410. ((tobjectdef(tpointerdef(p^.resulttype.def).definition).options and oo_hasvmt)<>0) and
  411. (cs_check_range in aktlocalswitches) then
  412. checkobject;
  413. {$endif TESTOBJEXT2}
  414. end;
  415. procedure tcgasnode.pass_2;
  416. var
  417. pushed : tpushedsaved;
  418. begin
  419. if (right.nodetype=guidconstn) then
  420. begin
  421. {$warning need to push a third parameter}
  422. { instance to check }
  423. secondpass(left);
  424. rg.saveusedregisters(exprasmlist,pushed,all_registers);
  425. cg.a_param_loc(exprasmlist,left.location,paramanager.getintparaloc(2));
  426. { type information }
  427. secondpass(right);
  428. cg.a_paramaddr_ref(exprasmlist,right.location.reference,paramanager.getintparaloc(1));
  429. location_release(exprasmlist,right.location);
  430. { call helper }
  431. if is_class(left.resulttype.def) then
  432. cg.a_call_name(exprasmlist,'FPC_CLASS_AS_INTF')
  433. else
  434. cg.a_call_name(exprasmlist,'FPC_INTF_AS');
  435. cg.g_maybe_loadself(exprasmlist);
  436. rg.restoreusedregisters(exprasmlist,pushed);
  437. end
  438. else
  439. begin
  440. { instance to check }
  441. secondpass(left);
  442. rg.saveusedregisters(exprasmlist,pushed,all_registers);
  443. cg.a_param_loc(exprasmlist,left.location,paramanager.getintparaloc(2));
  444. { type information }
  445. secondpass(right);
  446. cg.a_param_loc(exprasmlist,right.location,paramanager.getintparaloc(1));
  447. location_release(exprasmlist,right.location);
  448. { call helper }
  449. cg.a_call_name(exprasmlist,'FPC_DO_AS');
  450. cg.g_maybe_loadself(exprasmlist);
  451. rg.restoreusedregisters(exprasmlist,pushed);
  452. end;
  453. location_copy(location,left.location);
  454. end;
  455. begin
  456. ctypeconvnode := tcgtypeconvnode;
  457. casnode := tcgasnode;
  458. end.
  459. {
  460. $Log$
  461. Revision 1.25 2002-08-13 18:01:52 carl
  462. * rename swatoperands to swapoperands
  463. + m68k first compilable version (still needs a lot of testing):
  464. assembler generator, system information , inline
  465. assembler reader.
  466. Revision 1.24 2002/08/12 20:39:17 florian
  467. * casting of classes to interface fixed when the interface was
  468. implemented by a parent class
  469. Revision 1.23 2002/08/11 14:32:26 peter
  470. * renamed current_library to objectlibrary
  471. Revision 1.22 2002/08/11 13:24:11 peter
  472. * saving of asmsymbols in ppu supported
  473. * asmsymbollist global is removed and moved into a new class
  474. tasmlibrarydata that will hold the info of a .a file which
  475. corresponds with a single module. Added librarydata to tmodule
  476. to keep the library info stored for the module. In the future the
  477. objectfiles will also be stored to the tasmlibrarydata class
  478. * all getlabel/newasmsymbol and friends are moved to the new class
  479. Revision 1.21 2002/07/20 11:57:53 florian
  480. * types.pas renamed to defbase.pas because D6 contains a types
  481. unit so this would conflicts if D6 programms are compiled
  482. + Willamette/SSE2 instructions to assembler added
  483. Revision 1.20 2002/07/11 14:41:28 florian
  484. * start of the new generic parameter handling
  485. Revision 1.19 2002/07/07 09:52:32 florian
  486. * powerpc target fixed, very simple units can be compiled
  487. * some basic stuff for better callparanode handling, far from being finished
  488. Revision 1.18 2002/07/04 20:43:01 florian
  489. * first x86-64 patches
  490. Revision 1.17 2002/07/01 18:46:22 peter
  491. * internal linker
  492. * reorganized aasm layer
  493. Revision 1.16 2002/07/01 16:23:53 peter
  494. * cg64 patch
  495. * basics for currency
  496. * asnode updates for class and interface (not finished)
  497. Revision 1.15 2002/05/18 13:34:09 peter
  498. * readded missing revisions
  499. Revision 1.14 2002/05/16 19:46:37 carl
  500. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  501. + try to fix temp allocation (still in ifdef)
  502. + generic constructor calls
  503. + start of tassembler / tmodulebase class cleanup
  504. Revision 1.12 2002/05/12 16:53:07 peter
  505. * moved entry and exitcode to ncgutil and cgobj
  506. * foreach gets extra argument for passing local data to the
  507. iterator function
  508. * -CR checks also class typecasts at runtime by changing them
  509. into as
  510. * fixed compiler to cycle with the -CR option
  511. * fixed stabs with elf writer, finally the global variables can
  512. be watched
  513. * removed a lot of routines from cga unit and replaced them by
  514. calls to cgobj
  515. * u32bit-s32bit updates for and,or,xor nodes. When one element is
  516. u32bit then the other is typecasted also to u32bit without giving
  517. a rangecheck warning/error.
  518. * fixed pascal calling method with reversing also the high tree in
  519. the parast, detected by tcalcst3 test
  520. Revision 1.11 2002/04/21 19:02:03 peter
  521. * removed newn and disposen nodes, the code is now directly
  522. inlined from pexpr
  523. * -an option that will write the secondpass nodes to the .s file, this
  524. requires EXTDEBUG define to actually write the info
  525. * fixed various internal errors and crashes due recent code changes
  526. Revision 1.10 2002/04/19 15:39:34 peter
  527. * removed some more routines from cga
  528. * moved location_force_reg/mem to ncgutil
  529. * moved arrayconstructnode secondpass to ncgld
  530. Revision 1.9 2002/04/15 19:44:19 peter
  531. * fixed stackcheck that would be called recursively when a stack
  532. error was found
  533. * generic changeregsize(reg,size) for i386 register resizing
  534. * removed some more routines from cga unit
  535. * fixed returnvalue handling
  536. * fixed default stacksize of linux and go32v2, 8kb was a bit small :-)
  537. Revision 1.8 2002/04/06 18:10:42 jonas
  538. * several powerpc-related additions and fixes
  539. Revision 1.7 2002/04/04 19:05:57 peter
  540. * removed unused units
  541. * use tlocation.size in cg.a_*loc*() routines
  542. Revision 1.6 2002/04/02 17:11:28 peter
  543. * tlocation,treference update
  544. * LOC_CONSTANT added for better constant handling
  545. * secondadd splitted in multiple routines
  546. * location_force_reg added for loading a location to a register
  547. of a specified size
  548. * secondassignment parses now first the right and then the left node
  549. (this is compatible with Kylix). This saves a lot of push/pop especially
  550. with string operations
  551. * adapted some routines to use the new cg methods
  552. Revision 1.5 2002/03/31 20:26:34 jonas
  553. + a_loadfpu_* and a_loadmm_* methods in tcg
  554. * register allocation is now handled by a class and is mostly processor
  555. independent (+rgobj.pas and i386/rgcpu.pas)
  556. * temp allocation is now handled by a class (+tgobj.pas, -i386\tgcpu.pas)
  557. * some small improvements and fixes to the optimizer
  558. * some register allocation fixes
  559. * some fpuvaroffset fixes in the unary minus node
  560. * push/popusedregisters is now called rg.save/restoreusedregisters and
  561. (for i386) uses temps instead of push/pop's when using -Op3 (that code is
  562. also better optimizable)
  563. * fixed and optimized register saving/restoring for new/dispose nodes
  564. * LOC_FPU locations now also require their "register" field to be set to
  565. R_ST, not R_ST0 (the latter is used for LOC_CFPUREGISTER locations only)
  566. - list field removed of the tnode class because it's not used currently
  567. and can cause hard-to-find bugs
  568. }