n386cnv.pas 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 by Florian Klaempfl
  4. Generate i386 assembler for type converting nodes
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. ****************************************************************************
  17. }
  18. unit n386cnv;
  19. {$i fpcdefs.inc}
  20. interface
  21. uses
  22. node,ncgcnv,defutil,defcmp;
  23. type
  24. ti386typeconvnode = class(tcgtypeconvnode)
  25. protected
  26. { procedure second_int_to_int;override; }
  27. { procedure second_string_to_string;override; }
  28. { procedure second_cstring_to_pchar;override; }
  29. { procedure second_string_to_chararray;override; }
  30. { procedure second_array_to_pointer;override; }
  31. { procedure second_pointer_to_array;override; }
  32. { procedure second_chararray_to_string;override; }
  33. { procedure second_char_to_string;override; }
  34. function first_int_to_real: tnode; override;
  35. procedure second_int_to_real;override;
  36. { procedure second_real_to_real;override; }
  37. { procedure second_cord_to_pointer;override; }
  38. { procedure second_proc_to_procvar;override; }
  39. { procedure second_bool_to_int;override; }
  40. procedure second_int_to_bool;override;
  41. { procedure second_load_smallset;override; }
  42. { procedure second_ansistring_to_pchar;override; }
  43. { procedure second_pchar_to_string;override; }
  44. { procedure second_class_to_intf;override; }
  45. { procedure second_char_to_char;override; }
  46. {$ifdef TESTOBJEXT2}
  47. procedure checkobject;override;
  48. {$endif TESTOBJEXT2}
  49. procedure second_call_helper(c : tconverttype);override;
  50. end;
  51. implementation
  52. uses
  53. verbose,systems,
  54. symconst,symdef,aasmbase,aasmtai,aasmcpu,
  55. cginfo,cgbase,pass_2,
  56. ncon,ncal,ncnv,
  57. cpubase,
  58. cgobj,cga,tgobj,rgobj,rgcpu,ncgutil;
  59. {*****************************************************************************
  60. SecondTypeConv
  61. *****************************************************************************}
  62. function ti386typeconvnode.first_int_to_real : tnode;
  63. begin
  64. first_int_to_real:=nil;
  65. if registersfpu<1 then
  66. registersfpu:=1;
  67. location.loc:=LOC_FPUREGISTER;
  68. end;
  69. procedure ti386typeconvnode.second_int_to_real;
  70. var
  71. href : treference;
  72. hregister : tregister;
  73. l1,l2 : tasmlabel;
  74. freereg : boolean;
  75. r:Tregister;
  76. begin
  77. location_reset(location,LOC_FPUREGISTER,def_cgsize(resulttype.def));
  78. hregister.enum:=R_NO;
  79. freereg:=false;
  80. { for u32bit a solution is to push $0 and to load a comp }
  81. { does this first, it destroys maybe EDI }
  82. if torddef(left.resulttype.def).typ=u32bit then
  83. exprasmlist.concat(taicpu.op_const(A_PUSH,S_L,0));
  84. case left.location.loc of
  85. LOC_REGISTER,
  86. LOC_CREGISTER :
  87. begin
  88. case left.location.size of
  89. OS_64,OS_S64 :
  90. begin
  91. exprasmlist.concat(taicpu.op_reg(A_PUSH,S_L,left.location.registerhigh));
  92. hregister:=left.location.registerlow;
  93. end;
  94. OS_32,OS_S32 :
  95. hregister:=left.location.register;
  96. else
  97. begin
  98. hregister:=cg.get_scratch_reg_int(exprasmlist,OS_32);
  99. freereg:=true;
  100. cg.a_load_reg_reg(exprasmlist,left.location.size,OS_32,left.location.register,hregister);
  101. end;
  102. end;
  103. end;
  104. LOC_REFERENCE,
  105. LOC_CREFERENCE :
  106. begin
  107. hregister:=cg.get_scratch_reg_int(exprasmlist,OS_INT);
  108. freereg:=true;
  109. if left.location.size in [OS_64,OS_S64] then
  110. begin
  111. href:=left.location.reference;
  112. inc(href.offset,4);
  113. cg.a_load_ref_reg(exprasmlist,OS_32,href,hregister);
  114. exprasmlist.concat(taicpu.op_reg(A_PUSH,S_L,hregister));
  115. cg.a_load_ref_reg(exprasmlist,OS_32,left.location.reference,hregister);
  116. end
  117. else
  118. cg.a_load_ref_reg(exprasmlist,left.location.size,left.location.reference,hregister);
  119. end;
  120. else
  121. internalerror(2002032218);
  122. end;
  123. location_release(exprasmlist,left.location);
  124. location_freetemp(exprasmlist,left.location);
  125. { for 64 bit integers, the high dword is already pushed }
  126. exprasmlist.concat(taicpu.op_reg(A_PUSH,S_L,hregister));
  127. if freereg then
  128. cg.free_scratch_reg(exprasmlist,hregister);
  129. r.enum:=R_ESP;
  130. reference_reset_base(href,r,0);
  131. case torddef(left.resulttype.def).typ of
  132. u32bit:
  133. begin
  134. r.enum:=R_ESP;
  135. emit_ref(A_FILD,S_IQ,href);
  136. emit_const_reg(A_ADD,S_L,8,r);
  137. end;
  138. s64bit:
  139. begin
  140. r.enum:=R_ESP;
  141. emit_ref(A_FILD,S_IQ,href);
  142. emit_const_reg(A_ADD,S_L,8,r);
  143. end;
  144. u64bit:
  145. begin
  146. { unsigned 64 bit ints are harder to handle: }
  147. { we load bits 0..62 and then check bit 63: }
  148. { if it is 1 then we add $80000000 000000000 }
  149. { as double }
  150. r.enum:=R_INTREGISTER;
  151. r.number:=NR_EDI;
  152. inc(href.offset,4);
  153. rg.getexplicitregisterint(exprasmlist,NR_EDI);
  154. emit_ref_reg(A_MOV,S_L,href,r);
  155. r.enum:=R_ESP;
  156. reference_reset_base(href,r,4);
  157. emit_const_ref(A_AND,S_L,$7fffffff,href);
  158. r.enum:=R_INTREGISTER;
  159. r.number:=NR_EDI;
  160. emit_const_reg(A_TEST,S_L,longint($80000000),r);
  161. rg.ungetregisterint(exprasmlist,r);
  162. r.enum:=R_ESP;
  163. reference_reset_base(href,r,0);
  164. emit_ref(A_FILD,S_IQ,href);
  165. objectlibrary.getdatalabel(l1);
  166. objectlibrary.getlabel(l2);
  167. emitjmp(C_Z,l2);
  168. Consts.concat(Tai_label.Create(l1));
  169. { I got this constant from a test progtram (FK) }
  170. Consts.concat(Tai_const.Create_32bit(0));
  171. Consts.concat(Tai_const.Create_32bit(1138753536));
  172. reference_reset_symbol(href,l1,0);
  173. emit_ref(A_FADD,S_FL,href);
  174. cg.a_label(exprasmlist,l2);
  175. emit_const_reg(A_ADD,S_L,8,r);
  176. end
  177. else
  178. begin
  179. emit_ref(A_FILD,S_IL,href);
  180. rg.getexplicitregisterint(exprasmlist,NR_EDI);
  181. r.enum:=R_INTREGISTER;
  182. r.number:=NR_EDI;
  183. emit_reg(A_POP,S_L,r);
  184. rg.ungetregisterint(exprasmlist,r);
  185. end;
  186. end;
  187. inc(trgcpu(rg).fpuvaroffset);
  188. location.register.enum:=R_ST;
  189. end;
  190. procedure ti386typeconvnode.second_int_to_bool;
  191. var
  192. hregister : tregister;
  193. pref : treference;
  194. resflags : tresflags;
  195. hlabel,oldtruelabel,oldfalselabel : tasmlabel;
  196. begin
  197. oldtruelabel:=truelabel;
  198. oldfalselabel:=falselabel;
  199. objectlibrary.getlabel(truelabel);
  200. objectlibrary.getlabel(falselabel);
  201. secondpass(left);
  202. if codegenerror then
  203. exit;
  204. { byte(boolean) or word(wordbool) or longint(longbool) must }
  205. { be accepted for var parameters }
  206. if (nf_explizit in flags) and
  207. (left.resulttype.def.size=resulttype.def.size) and
  208. (left.location.loc in [LOC_REFERENCE,LOC_CREFERENCE,LOC_CREGISTER]) then
  209. begin
  210. location_copy(location,left.location);
  211. truelabel:=oldtruelabel;
  212. falselabel:=oldfalselabel;
  213. exit;
  214. end;
  215. { Load left node into flag F_NE/F_E }
  216. resflags:=F_NE;
  217. location_release(exprasmlist,left.location);
  218. case left.location.loc of
  219. LOC_CREFERENCE,
  220. LOC_REFERENCE :
  221. begin
  222. if left.location.size in [OS_64,OS_S64] then
  223. begin
  224. hregister:=rg.getregisterint(exprasmlist,OS_INT);
  225. emit_ref_reg(A_MOV,S_L,left.location.reference,hregister);
  226. pref:=left.location.reference;
  227. inc(pref.offset,4);
  228. emit_ref_reg(A_OR,S_L,pref,hregister);
  229. end
  230. else
  231. begin
  232. location_force_reg(exprasmlist,left.location,left.location.size,true);
  233. cg.a_op_reg_reg(exprasmlist,OP_OR,left.location.size,left.location.register,left.location.register);
  234. end;
  235. end;
  236. LOC_FLAGS :
  237. begin
  238. resflags:=left.location.resflags;
  239. end;
  240. LOC_REGISTER,LOC_CREGISTER :
  241. begin
  242. if left.location.size in [OS_64,OS_S64] then
  243. begin
  244. hregister:=cg.get_scratch_reg_int(exprasmlist,OS_32);
  245. cg.a_load_reg_reg(exprasmlist,OS_32,OS_32,left.location.registerlow,hregister);
  246. cg.a_op_reg_reg(exprasmlist,OP_OR,OS_32,left.location.registerhigh,hregister);
  247. cg.free_scratch_reg(exprasmlist,hregister);
  248. end
  249. else
  250. cg.a_op_reg_reg(exprasmlist,OP_OR,left.location.size,left.location.register,left.location.register);
  251. end;
  252. LOC_JUMP :
  253. begin
  254. hregister:=rg.getregisterint(exprasmlist,OS_INT);
  255. objectlibrary.getlabel(hlabel);
  256. cg.a_label(exprasmlist,truelabel);
  257. cg.a_load_const_reg(exprasmlist,OS_INT,1,hregister);
  258. cg.a_jmp_always(exprasmlist,hlabel);
  259. cg.a_label(exprasmlist,falselabel);
  260. cg.a_load_const_reg(exprasmlist,OS_INT,0,hregister);
  261. cg.a_label(exprasmlist,hlabel);
  262. cg.a_op_reg_reg(exprasmlist,OP_OR,OS_INT,hregister,hregister);
  263. end;
  264. else
  265. internalerror(10062);
  266. end;
  267. { load flags to register }
  268. location_reset(location,LOC_REGISTER,def_cgsize(resulttype.def));
  269. location.register:=def_getreg(resulttype.def);
  270. cg.g_flags2reg(exprasmlist,location.size,resflags,location.register);
  271. truelabel:=oldtruelabel;
  272. falselabel:=oldfalselabel;
  273. end;
  274. {$ifdef TESTOBJEXT2}
  275. procedure ti386typeconvnode.checkobject;
  276. var
  277. r : preference;
  278. nillabel : plabel;
  279. begin
  280. new(r);
  281. reset_reference(r^);
  282. if p^.location.loc in [LOC_REGISTER,LOC_CREGISTER] then
  283. r^.base:=p^.location.register
  284. else
  285. begin
  286. rg.getexplicitregisterint(exprasmlist,R_EDI);
  287. emit_mov_loc_reg(p^.location,R_EDI);
  288. r^.base:=R_EDI;
  289. end;
  290. { NIL must be accepted !! }
  291. emit_reg_reg(A_OR,S_L,r^.base,r^.base);
  292. rg.ungetregisterint(exprasmlist,R_EDI);
  293. objectlibrary.getlabel(nillabel);
  294. emitjmp(C_E,nillabel);
  295. { this is one point where we need vmt_offset (PM) }
  296. r^.offset:= tobjectdef(tpointerdef(p^.resulttype.def).definition).vmt_offset;
  297. rg.getexplicitregisterint(exprasmlist,R_EDI);
  298. emit_ref_reg(A_MOV,S_L,r,R_EDI);
  299. emit_sym(A_PUSH,S_L,
  300. objectlibrary.newasmsymbol(tobjectdef(tpointerdef(p^.resulttype.def).definition).vmt_mangledname));
  301. emit_reg(A_PUSH,S_L,R_EDI);
  302. rg.ungetregister32(exprasmlist,R_EDI);
  303. emitcall('FPC_CHECK_OBJECT_EXT');
  304. emitlab(nillabel);
  305. end;
  306. {$endif TESTOBJEXT2}
  307. procedure ti386typeconvnode.second_call_helper(c : tconverttype);
  308. {$ifdef fpc}
  309. const
  310. secondconvert : array[tconverttype] of pointer = (
  311. {$ifdef fpc}@{$endif}second_nothing, {equal}
  312. {$ifdef fpc}@{$endif}second_nothing, {not_possible}
  313. {$ifdef fpc}@{$endif}second_nothing, {second_string_to_string, handled in resulttype pass }
  314. {$ifdef fpc}@{$endif}second_char_to_string,
  315. {$ifdef fpc}@{$endif}second_nothing, {char_to_charray}
  316. {$ifdef fpc}@{$endif}second_nothing, { pchar_to_string, handled in resulttype pass }
  317. {$ifdef fpc}@{$endif}second_nothing, {cchar_to_pchar}
  318. {$ifdef fpc}@{$endif}second_cstring_to_pchar,
  319. {$ifdef fpc}@{$endif}second_ansistring_to_pchar,
  320. {$ifdef fpc}@{$endif}second_string_to_chararray,
  321. {$ifdef fpc}@{$endif}second_nothing, { chararray_to_string, handled in resulttype pass }
  322. {$ifdef fpc}@{$endif}second_array_to_pointer,
  323. {$ifdef fpc}@{$endif}second_pointer_to_array,
  324. {$ifdef fpc}@{$endif}second_int_to_int,
  325. {$ifdef fpc}@{$endif}second_int_to_bool,
  326. {$ifdef fpc}@{$endif}second_bool_to_bool,
  327. {$ifdef fpc}@{$endif}second_bool_to_int,
  328. {$ifdef fpc}@{$endif}second_real_to_real,
  329. {$ifdef fpc}@{$endif}second_int_to_real,
  330. {$ifdef fpc}@{$endif}second_proc_to_procvar,
  331. {$ifdef fpc}@{$endif}second_nothing, { arrayconstructor_to_set }
  332. {$ifdef fpc}@{$endif}second_nothing, { second_load_smallset, handled in first pass }
  333. {$ifdef fpc}@{$endif}second_cord_to_pointer,
  334. {$ifdef fpc}@{$endif}second_nothing, { interface 2 string }
  335. {$ifdef fpc}@{$endif}second_nothing, { interface 2 guid }
  336. {$ifdef fpc}@{$endif}second_class_to_intf,
  337. {$ifdef fpc}@{$endif}second_char_to_char,
  338. {$ifdef fpc}@{$endif}second_nothing, { normal_2_smallset }
  339. {$ifdef fpc}@{$endif}second_nothing, { dynarray_2_openarray }
  340. {$ifdef fpc}@{$endif}second_nothing, { pwchar_2_string }
  341. {$ifdef fpc}@{$endif}second_nothing, { variant_2_dynarray }
  342. {$ifdef fpc}@{$endif}second_nothing { dynarray_2_variant}
  343. );
  344. type
  345. tprocedureofobject = procedure of object;
  346. var
  347. r : packed record
  348. proc : pointer;
  349. obj : pointer;
  350. end;
  351. begin
  352. { this is a little bit dirty but it works }
  353. { and should be quite portable too }
  354. r.proc:=secondconvert[c];
  355. r.obj:=self;
  356. tprocedureofobject(r){$ifdef FPC}();{$endif FPC}
  357. end;
  358. {$else}
  359. begin
  360. case c of
  361. tc_equal,
  362. tc_not_possible,
  363. tc_string_2_string : second_nothing;
  364. tc_char_2_string : second_char_to_string;
  365. tc_char_2_chararray : second_nothing;
  366. tc_pchar_2_string : second_nothing;
  367. tc_cchar_2_pchar : second_nothing;
  368. tc_cstring_2_pchar : second_cstring_to_pchar;
  369. tc_ansistring_2_pchar : second_ansistring_to_pchar;
  370. tc_string_2_chararray : second_string_to_chararray;
  371. tc_chararray_2_string : second_nothing;
  372. tc_array_2_pointer : second_array_to_pointer;
  373. tc_pointer_2_array : second_pointer_to_array;
  374. tc_int_2_int : second_int_to_int;
  375. tc_int_2_bool : second_int_to_bool;
  376. tc_bool_2_bool : second_bool_to_bool;
  377. tc_bool_2_int : second_bool_to_int;
  378. tc_real_2_real : second_real_to_real;
  379. tc_int_2_real : second_int_to_real;
  380. tc_proc_2_procvar : second_proc_to_procvar;
  381. tc_arrayconstructor_2_set : second_nothing;
  382. tc_load_smallset : second_nothing;
  383. tc_cord_2_pointer : second_cord_to_pointer;
  384. tc_intf_2_string : second_nothing;
  385. tc_intf_2_guid : second_nothing;
  386. tc_class_2_intf : second_class_to_intf;
  387. tc_char_2_char : second_char_to_char;
  388. tc_normal_2_smallset : second_nothing;
  389. tc_dynarray_2_openarray : second_nothing;
  390. tc_pwchar_2_string : second_nothing;
  391. tc_variant_2_dynarray : second_nothing;
  392. tc_dynarray_2_variant : second_nothing;
  393. else internalerror(2002101101);
  394. end;
  395. end;
  396. {$endif}
  397. begin
  398. ctypeconvnode:=ti386typeconvnode;
  399. end.
  400. {
  401. $Log$
  402. Revision 1.56 2003-02-19 22:00:15 daniel
  403. * Code generator converted to new register notation
  404. - Horribily outdated todo.txt removed
  405. Revision 1.55 2003/01/13 18:37:44 daniel
  406. * Work on register conversion
  407. Revision 1.54 2003/01/08 18:43:57 daniel
  408. * Tregister changed into a record
  409. Revision 1.53 2002/12/05 14:27:42 florian
  410. * some variant <-> dyn. array stuff
  411. Revision 1.52 2002/11/25 17:43:26 peter
  412. * splitted defbase in defutil,symutil,defcmp
  413. * merged isconvertable and is_equal into compare_defs(_ext)
  414. * made operator search faster by walking the list only once
  415. Revision 1.51 2002/10/10 16:14:54 florian
  416. * fixed to reflect last tconvtype change
  417. Revision 1.50 2002/10/05 12:43:29 carl
  418. * fixes for Delphi 6 compilation
  419. (warning : Some features do not work under Delphi)
  420. Revision 1.49 2002/09/17 18:54:03 jonas
  421. * a_load_reg_reg() now has two size parameters: source and dest. This
  422. allows some optimizations on architectures that don't encode the
  423. register size in the register name.
  424. Revision 1.48 2002/08/14 19:19:14 carl
  425. * first_int_to_real moved to i386 (other one is generic)
  426. Revision 1.47 2002/08/11 14:32:30 peter
  427. * renamed current_library to objectlibrary
  428. Revision 1.46 2002/08/11 13:24:16 peter
  429. * saving of asmsymbols in ppu supported
  430. * asmsymbollist global is removed and moved into a new class
  431. tasmlibrarydata that will hold the info of a .a file which
  432. corresponds with a single module. Added librarydata to tmodule
  433. to keep the library info stored for the module. In the future the
  434. objectfiles will also be stored to the tasmlibrarydata class
  435. * all getlabel/newasmsymbol and friends are moved to the new class
  436. Revision 1.45 2002/07/27 19:53:51 jonas
  437. + generic implementation of tcg.g_flags2ref()
  438. * tcg.flags2xxx() now also needs a size parameter
  439. Revision 1.44 2002/07/20 11:58:01 florian
  440. * types.pas renamed to defbase.pas because D6 contains a types
  441. unit so this would conflicts if D6 programms are compiled
  442. + Willamette/SSE2 instructions to assembler added
  443. Revision 1.43 2002/07/01 18:46:31 peter
  444. * internal linker
  445. * reorganized aasm layer
  446. Revision 1.42 2002/05/20 13:30:40 carl
  447. * bugfix of hdisponen (base must be set, not index)
  448. * more portability fixes
  449. Revision 1.41 2002/05/18 13:34:24 peter
  450. * readded missing revisions
  451. Revision 1.40 2002/05/16 19:46:51 carl
  452. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  453. + try to fix temp allocation (still in ifdef)
  454. + generic constructor calls
  455. + start of tassembler / tmodulebase class cleanup
  456. Revision 1.38 2002/05/12 16:53:17 peter
  457. * moved entry and exitcode to ncgutil and cgobj
  458. * foreach gets extra argument for passing local data to the
  459. iterator function
  460. * -CR checks also class typecasts at runtime by changing them
  461. into as
  462. * fixed compiler to cycle with the -CR option
  463. * fixed stabs with elf writer, finally the global variables can
  464. be watched
  465. * removed a lot of routines from cga unit and replaced them by
  466. calls to cgobj
  467. * u32bit-s32bit updates for and,or,xor nodes. When one element is
  468. u32bit then the other is typecasted also to u32bit without giving
  469. a rangecheck warning/error.
  470. * fixed pascal calling method with reversing also the high tree in
  471. the parast, detected by tcalcst3 test
  472. Revision 1.37 2002/04/21 19:02:07 peter
  473. * removed newn and disposen nodes, the code is now directly
  474. inlined from pexpr
  475. * -an option that will write the secondpass nodes to the .s file, this
  476. requires EXTDEBUG define to actually write the info
  477. * fixed various internal errors and crashes due recent code changes
  478. Revision 1.36 2002/04/21 15:35:23 carl
  479. * changeregsize -> rg.makeregsize
  480. Revision 1.35 2002/04/19 15:39:35 peter
  481. * removed some more routines from cga
  482. * moved location_force_reg/mem to ncgutil
  483. * moved arrayconstructnode secondpass to ncgld
  484. Revision 1.34 2002/04/15 19:44:21 peter
  485. * fixed stackcheck that would be called recursively when a stack
  486. error was found
  487. * generic changeregsize(reg,size) for i386 register resizing
  488. * removed some more routines from cga unit
  489. * fixed returnvalue handling
  490. * fixed default stacksize of linux and go32v2, 8kb was a bit small :-)
  491. Revision 1.33 2002/04/04 19:06:10 peter
  492. * removed unused units
  493. * use tlocation.size in cg.a_*loc*() routines
  494. Revision 1.32 2002/04/02 17:11:36 peter
  495. * tlocation,treference update
  496. * LOC_CONSTANT added for better constant handling
  497. * secondadd splitted in multiple routines
  498. * location_force_reg added for loading a location to a register
  499. of a specified size
  500. * secondassignment parses now first the right and then the left node
  501. (this is compatible with Kylix). This saves a lot of push/pop especially
  502. with string operations
  503. * adapted some routines to use the new cg methods
  504. Revision 1.31 2002/03/31 20:26:38 jonas
  505. + a_loadfpu_* and a_loadmm_* methods in tcg
  506. * register allocation is now handled by a class and is mostly processor
  507. independent (+rgobj.pas and i386/rgcpu.pas)
  508. * temp allocation is now handled by a class (+tgobj.pas, -i386\tgcpu.pas)
  509. * some small improvements and fixes to the optimizer
  510. * some register allocation fixes
  511. * some fpuvaroffset fixes in the unary minus node
  512. * push/popusedregisters is now called rg.save/restoreusedregisters and
  513. (for i386) uses temps instead of push/pop's when using -Op3 (that code is
  514. also better optimizable)
  515. * fixed and optimized register saving/restoring for new/dispose nodes
  516. * LOC_FPU locations now also require their "register" field to be set to
  517. R_ST, not R_ST0 (the latter is used for LOC_CFPUREGISTER locations only)
  518. - list field removed of the tnode class because it's not used currently
  519. and can cause hard-to-find bugs
  520. Revision 1.30 2002/03/04 19:10:13 peter
  521. * removed compiler warnings
  522. }