n386cnv.pas 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618
  1. {
  2. $Id$
  3. Copyright (c) 1998-2000 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 defines.inc}
  20. interface
  21. uses
  22. node,ncnv,ncgcnv,types;
  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. procedure second_int_to_real;override;
  35. { procedure second_real_to_real;override; }
  36. { procedure second_cord_to_pointer;override; }
  37. { procedure second_proc_to_procvar;override; }
  38. { procedure second_bool_to_int;override; }
  39. procedure second_int_to_bool;override;
  40. { procedure second_load_smallset;override; }
  41. { procedure second_ansistring_to_pchar;override; }
  42. { procedure second_pchar_to_string;override; }
  43. { procedure second_class_to_intf;override; }
  44. { procedure second_char_to_char;override; }
  45. procedure pass_2;override;
  46. procedure second_call_helper(c : tconverttype);
  47. end;
  48. implementation
  49. uses
  50. verbose,systems,
  51. symconst,symdef,aasm,
  52. cgbase,temp_gen,pass_2,
  53. ncon,ncal,
  54. cpubase,
  55. cgobj,cga,tgcpu,n386util;
  56. {*****************************************************************************
  57. SecondTypeConv
  58. *****************************************************************************}
  59. procedure ti386typeconvnode.second_int_to_int;
  60. var
  61. op : tasmop;
  62. opsize : topsize;
  63. hregister,
  64. hregister2 : tregister;
  65. begin
  66. { insert range check if not explicit conversion }
  67. if not(nf_explizit in flags) then
  68. cg.g_rangecheck(exprasmlist,left,resulttype.def);
  69. { is the result size smaller ? }
  70. if resulttype.def.size<left.resulttype.def.size then
  71. begin
  72. { only need to set the new size of a register }
  73. if (left.location.loc in [LOC_REGISTER,LOC_CREGISTER]) then
  74. begin
  75. case resulttype.def.size of
  76. 1 : location.register:=makereg8(left.location.register);
  77. 2 : location.register:=makereg16(left.location.register);
  78. 4 : location.register:=makereg32(left.location.register);
  79. end;
  80. { we can release the upper register }
  81. if is_64bitint(left.resulttype.def) then
  82. ungetregister32(left.location.registerhigh);
  83. end;
  84. end
  85. { is the result size bigger ? }
  86. else if resulttype.def.size>left.resulttype.def.size then
  87. begin
  88. { remove reference }
  89. if not(left.location.loc in [LOC_REGISTER,LOC_CREGISTER]) then
  90. begin
  91. del_reference(left.location.reference);
  92. { we can do this here as we need no temp inside }
  93. ungetiftemp(left.location.reference);
  94. end;
  95. { get op and opsize, handle separate for constants, because
  96. movz doesn't support constant values }
  97. if (left.location.loc=LOC_MEM) and (left.location.reference.is_immediate) then
  98. begin
  99. if is_64bitint(resulttype.def) then
  100. opsize:=S_L
  101. else
  102. opsize:=def_opsize(resulttype.def);
  103. op:=A_MOV;
  104. end
  105. else
  106. begin
  107. opsize:=def2def_opsize(left.resulttype.def,resulttype.def);
  108. if opsize in [S_B,S_W,S_L] then
  109. op:=A_MOV
  110. else
  111. if is_signed(left.resulttype.def) then
  112. op:=A_MOVSX
  113. else
  114. op:=A_MOVZX;
  115. end;
  116. { load the register we need }
  117. if left.location.loc<>LOC_REGISTER then
  118. hregister:=getregisterint
  119. else
  120. hregister:=left.location.register;
  121. { set the correct register size and location }
  122. clear_location(location);
  123. location.loc:=LOC_REGISTER;
  124. { do we need a second register for a 64 bit type ? }
  125. if is_64bitint(resulttype.def) then
  126. begin
  127. hregister2:=getregisterint;
  128. location.registerhigh:=hregister2;
  129. end;
  130. case resulttype.def.size of
  131. 1:
  132. location.register:=makereg8(hregister);
  133. 2:
  134. location.register:=makereg16(hregister);
  135. 4,8:
  136. location.register:=makereg32(hregister);
  137. end;
  138. { insert the assembler code }
  139. if left.location.loc in [LOC_CREGISTER,LOC_REGISTER] then
  140. emit_reg_reg(op,opsize,left.location.register,location.register)
  141. else
  142. emit_ref_reg(op,opsize,
  143. newreference(left.location.reference),location.register);
  144. { do we need a sign extension for int64? }
  145. if is_64bitint(resulttype.def) then
  146. { special case for constants (JM) }
  147. if is_constintnode(left) then
  148. begin
  149. if tordconstnode(left).value >= 0 then
  150. emit_reg_reg(A_XOR,S_L,
  151. hregister2,hregister2)
  152. else
  153. emit_const_reg(A_MOV,S_L,longint($ffffffff),hregister2);
  154. end
  155. else
  156. begin
  157. if (torddef(resulttype.def).typ=s64bit) and
  158. is_signed(left.resulttype.def) then
  159. begin
  160. emit_reg_reg(A_MOV,S_L,location.register,hregister2);
  161. emit_const_reg(A_SAR,S_L,31,hregister2);
  162. end
  163. else
  164. emit_reg_reg(A_XOR,S_L,hregister2,hregister2);
  165. end;
  166. end;
  167. end;
  168. procedure ti386typeconvnode.second_int_to_real;
  169. var
  170. r : preference;
  171. hregister : tregister;
  172. l1,l2 : tasmlabel;
  173. begin
  174. { for u32bit a solution is to push $0 and to load a comp }
  175. { does this first, it destroys maybe EDI }
  176. hregister:=R_EDI;
  177. if torddef(left.resulttype.def).typ=u32bit then
  178. push_int(0);
  179. if (left.location.loc=LOC_REGISTER) or
  180. (left.location.loc=LOC_CREGISTER) then
  181. begin
  182. if not (torddef(left.resulttype.def).typ in [u32bit,s32bit,u64bit,s64bit]) then
  183. getexplicitregister32(R_EDI);
  184. case torddef(left.resulttype.def).typ of
  185. s8bit : emit_reg_reg(A_MOVSX,S_BL,left.location.register,R_EDI);
  186. u8bit : emit_reg_reg(A_MOVZX,S_BL,left.location.register,R_EDI);
  187. s16bit : emit_reg_reg(A_MOVSX,S_WL,left.location.register,R_EDI);
  188. u16bit : emit_reg_reg(A_MOVZX,S_WL,left.location.register,R_EDI);
  189. u32bit,s32bit:
  190. hregister:=left.location.register;
  191. u64bit,s64bit:
  192. begin
  193. emit_reg(A_PUSH,S_L,left.location.registerhigh);
  194. hregister:=left.location.registerlow;
  195. end;
  196. end;
  197. ungetregister(left.location.register);
  198. end
  199. else
  200. begin
  201. r:=newreference(left.location.reference);
  202. getexplicitregister32(R_EDI);
  203. case torddef(left.resulttype.def).typ of
  204. s8bit:
  205. emit_ref_reg(A_MOVSX,S_BL,r,R_EDI);
  206. u8bit:
  207. emit_ref_reg(A_MOVZX,S_BL,r,R_EDI);
  208. s16bit:
  209. emit_ref_reg(A_MOVSX,S_WL,r,R_EDI);
  210. u16bit:
  211. emit_ref_reg(A_MOVZX,S_WL,r,R_EDI);
  212. u32bit,s32bit:
  213. emit_ref_reg(A_MOV,S_L,r,R_EDI);
  214. u64bit,s64bit:
  215. begin
  216. inc(r^.offset,4);
  217. emit_ref_reg(A_MOV,S_L,r,R_EDI);
  218. emit_reg(A_PUSH,S_L,R_EDI);
  219. r:=newreference(left.location.reference);
  220. emit_ref_reg(A_MOV,S_L,r,R_EDI);
  221. end;
  222. end;
  223. del_reference(left.location.reference);
  224. ungetiftemp(left.location.reference);
  225. end;
  226. { for 64 bit integers, the high dword is already pushed }
  227. emit_reg(A_PUSH,S_L,hregister);
  228. if hregister = R_EDI then
  229. ungetregister32(R_EDI);
  230. r:=new_reference(R_ESP,0);
  231. case torddef(left.resulttype.def).typ of
  232. u32bit:
  233. begin
  234. emit_ref(A_FILD,S_IQ,r);
  235. emit_const_reg(A_ADD,S_L,8,R_ESP);
  236. end;
  237. s64bit:
  238. begin
  239. emit_ref(A_FILD,S_IQ,r);
  240. emit_const_reg(A_ADD,S_L,8,R_ESP);
  241. end;
  242. u64bit:
  243. begin
  244. { unsigned 64 bit ints are harder to handle: }
  245. { we load bits 0..62 and then check bit 63: }
  246. { if it is 1 then we add $80000000 000000000 }
  247. { as double }
  248. inc(r^.offset,4);
  249. getexplicitregister32(R_EDI);
  250. emit_ref_reg(A_MOV,S_L,r,R_EDI);
  251. r:=new_reference(R_ESP,4);
  252. emit_const_ref(A_AND,S_L,$7fffffff,r);
  253. emit_const_reg(A_TEST,S_L,longint($80000000),R_EDI);
  254. ungetregister32(R_EDI);
  255. r:=new_reference(R_ESP,0);
  256. emit_ref(A_FILD,S_IQ,r);
  257. getdatalabel(l1);
  258. getlabel(l2);
  259. emitjmp(C_Z,l2);
  260. Consts.concat(Tai_label.Create(l1));
  261. { I got this constant from a test progtram (FK) }
  262. Consts.concat(Tai_const.Create_32bit(0));
  263. Consts.concat(Tai_const.Create_32bit(1138753536));
  264. r:=new_reference(R_NO,0);
  265. r^.symbol:=l1;
  266. emit_ref(A_FADD,S_FL,r);
  267. emitlab(l2);
  268. emit_const_reg(A_ADD,S_L,8,R_ESP);
  269. end
  270. else
  271. begin
  272. emit_ref(A_FILD,S_IL,r);
  273. getexplicitregister32(R_EDI);
  274. emit_reg(A_POP,S_L,R_EDI);
  275. ungetregister32(R_EDI);
  276. end;
  277. end;
  278. inc(fpuvaroffset);
  279. clear_location(location);
  280. location.loc:=LOC_FPU;
  281. end;
  282. procedure ti386typeconvnode.second_int_to_bool;
  283. var
  284. hregister : tregister;
  285. resflags : tresflags;
  286. opsize : topsize;
  287. pref : preference;
  288. begin
  289. clear_location(location);
  290. { byte(boolean) or word(wordbool) or longint(longbool) must }
  291. { be accepted for var parameters }
  292. if (nf_explizit in flags) and
  293. (left.resulttype.def.size=resulttype.def.size) and
  294. (left.location.loc in [LOC_REFERENCE,LOC_MEM,LOC_CREGISTER]) then
  295. begin
  296. set_location(location,left.location);
  297. exit;
  298. end;
  299. location.loc:=LOC_REGISTER;
  300. del_location(left.location);
  301. opsize:=def_opsize(left.resulttype.def);
  302. case left.location.loc of
  303. LOC_MEM,LOC_REFERENCE :
  304. begin
  305. if is_64bitint(left.resulttype.def) then
  306. begin
  307. hregister:=getregisterint;
  308. emit_ref_reg(A_MOV,opsize,
  309. newreference(left.location.reference),hregister);
  310. pref:=newreference(left.location.reference);
  311. inc(pref^.offset,4);
  312. emit_reg_ref(A_OR,opsize,
  313. hregister,pref);
  314. end
  315. else
  316. begin
  317. hregister:=def_getreg(left.resulttype.def);
  318. emit_ref_reg(A_MOV,opsize,
  319. newreference(left.location.reference),hregister);
  320. emit_reg_reg(A_OR,opsize,hregister,hregister);
  321. end;
  322. resflags:=F_NE;
  323. end;
  324. LOC_FLAGS :
  325. begin
  326. hregister:=getregisterint;
  327. resflags:=left.location.resflags;
  328. end;
  329. LOC_REGISTER,LOC_CREGISTER :
  330. begin
  331. hregister:=left.location.register;
  332. emit_reg_reg(A_OR,opsize,hregister,hregister);
  333. resflags:=F_NE;
  334. end;
  335. else
  336. internalerror(10062);
  337. end;
  338. case resulttype.def.size of
  339. 1 : location.register:=makereg8(hregister);
  340. 2 : location.register:=makereg16(hregister);
  341. 4 : location.register:=makereg32(hregister);
  342. else
  343. internalerror(10064);
  344. end;
  345. emit_flag2reg(resflags,location.register);
  346. end;
  347. {****************************************************************************
  348. TI386TYPECONVNODE
  349. ****************************************************************************}
  350. procedure ti386typeconvnode.second_call_helper(c : tconverttype);
  351. const
  352. secondconvert : array[tconverttype] of pointer = (
  353. @second_nothing, {equal}
  354. @second_nothing, {not_possible}
  355. @second_nothing, {second_string_to_string, handled in resulttype pass }
  356. @second_char_to_string,
  357. @second_nothing, {char_to_charray}
  358. @second_nothing, { pchar_to_string, handled in resulttype pass }
  359. @second_nothing, {cchar_to_pchar}
  360. @second_cstring_to_pchar,
  361. @second_ansistring_to_pchar,
  362. @second_string_to_chararray,
  363. @second_nothing, { chararray_to_string, handled in resulttype pass }
  364. @second_array_to_pointer,
  365. @second_pointer_to_array,
  366. @second_int_to_int,
  367. @second_int_to_bool,
  368. @second_bool_to_int, { bool_to_bool }
  369. @second_bool_to_int,
  370. @second_real_to_real,
  371. @second_int_to_real,
  372. @second_proc_to_procvar,
  373. @second_nothing, { arrayconstructor_to_set }
  374. @second_nothing, { second_load_smallset, handled in first pass }
  375. @second_cord_to_pointer,
  376. @second_nothing, { interface 2 string }
  377. @second_nothing, { interface 2 guid }
  378. @second_class_to_intf,
  379. @second_char_to_char,
  380. @second_nothing, { normal_2_smallset }
  381. @second_nothing { dynarray_2_openarray }
  382. );
  383. type
  384. tprocedureofobject = procedure of object;
  385. var
  386. r : packed record
  387. proc : pointer;
  388. obj : pointer;
  389. end;
  390. begin
  391. { this is a little bit dirty but it works }
  392. { and should be quite portable too }
  393. r.proc:=secondconvert[c];
  394. r.obj:=self;
  395. tprocedureofobject(r){$ifdef FPC}();{$endif FPC}
  396. end;
  397. procedure ti386typeconvnode.pass_2;
  398. {$ifdef TESTOBJEXT2}
  399. var
  400. r : preference;
  401. nillabel : plabel;
  402. {$endif TESTOBJEXT2}
  403. begin
  404. { this isn't good coding, I think tc_bool_2_int, shouldn't be }
  405. { type conversion (FK) }
  406. if not(convtype in [tc_bool_2_int,tc_bool_2_bool]) then
  407. begin
  408. secondpass(left);
  409. set_location(location,left.location);
  410. if codegenerror then
  411. exit;
  412. end;
  413. second_call_helper(convtype);
  414. {$ifdef TESTOBJEXT2}
  415. { Check explicit conversions to objects pointers !! }
  416. if p^.explizit and
  417. (p^.resulttype.def.deftype=pointerdef) and
  418. (tpointerdef(p^.resulttype.def).definition.deftype=objectdef) and not
  419. (tobjectdef(tpointerdef(p^.resulttype.def).definition).isclass) and
  420. ((tobjectdef(tpointerdef(p^.resulttype.def).definition).options and oo_hasvmt)<>0) and
  421. (cs_check_range in aktlocalswitches) then
  422. begin
  423. new(r);
  424. reset_reference(r^);
  425. if p^.location.loc in [LOC_REGISTER,LOC_CREGISTER] then
  426. r^.base:=p^.location.register
  427. else
  428. begin
  429. getexplicitregister32(R_EDI);
  430. emit_mov_loc_reg(p^.location,R_EDI);
  431. r^.base:=R_EDI;
  432. end;
  433. { NIL must be accepted !! }
  434. emit_reg_reg(A_OR,S_L,r^.base,r^.base);
  435. ungetregister32(R_EDI);
  436. getlabel(nillabel);
  437. emitjmp(C_E,nillabel);
  438. { this is one point where we need vmt_offset (PM) }
  439. r^.offset:= tobjectdef(tpointerdef(p^.resulttype.def).definition).vmt_offset;
  440. getexplicitregister32(R_EDI);
  441. emit_ref_reg(A_MOV,S_L,r,R_EDI);
  442. emit_sym(A_PUSH,S_L,
  443. newasmsymbol(tobjectdef(tpointerdef(p^.resulttype.def).definition).vmt_mangledname));
  444. emit_reg(A_PUSH,S_L,R_EDI);
  445. ungetregister32(R_EDI);
  446. emitcall('FPC_CHECK_OBJECT_EXT');
  447. emitlab(nillabel);
  448. end;
  449. {$endif TESTOBJEXT2}
  450. end;
  451. begin
  452. ctypeconvnode:=ti386typeconvnode;
  453. end.
  454. {
  455. $Log$
  456. Revision 1.29 2001-12-30 17:24:46 jonas
  457. * range checking is now processor independent (part in cgobj, part in cg64f32) and should work correctly again (it needed some changes after the changes of the low and high of tordef's to int64) * maketojumpbool() is now processor independent (in ncgutil) * getregister32 is now called getregisterint
  458. Revision 1.28 2001/12/11 08:14:17 jonas
  459. * part of my fix for dynarray -> open array conversion, forgot to
  460. commit yesterday :(
  461. Revision 1.27 2001/11/02 23:24:12 jonas
  462. * fixed web bug 1665 (allow char to chararray type conversion) ("merged")
  463. Revision 1.26 2001/09/30 21:28:34 peter
  464. * int64->boolean fixed
  465. Revision 1.25 2001/09/30 16:12:47 jonas
  466. - removed unnecessary i386 pass_2 of as- and isnode and added dummy generic ones
  467. Revision 1.24 2001/09/29 21:32:47 jonas
  468. * almost all second pass typeconvnode helpers are now processor independent
  469. * fixed converting boolean to int64/qword
  470. * fixed register allocation bugs which could cause internalerror 10
  471. * isnode and asnode are completely processor indepent now as well
  472. * fpc_do_as now returns its class argument (necessary to be able to use it
  473. properly with compilerproc)
  474. Revision 1.23 2001/09/03 13:27:42 jonas
  475. * compilerproc implementation of set addition/substraction/...
  476. * changed the declaration of some set helpers somewhat to accomodate the
  477. above change
  478. * i386 still uses the old code for comparisons of sets, because its
  479. helpers return the results in the flags
  480. * dummy tc_normal_2_small_set type conversion because I need the original
  481. resulttype of the set add nodes
  482. NOTE: you have to start a cycle with 1.0.5!
  483. Revision 1.22 2001/08/29 19:49:03 jonas
  484. * some fixes in compilerprocs for chararray to string conversions
  485. * conversion from string to chararray is now also done via compilerprocs
  486. Revision 1.21 2001/08/28 13:24:47 jonas
  487. + compilerproc implementation of most string-related type conversions
  488. - removed all code from the compiler which has been replaced by
  489. compilerproc implementations (using {$ifdef hascompilerproc} is not
  490. necessary in the compiler)
  491. Revision 1.20 2001/08/26 13:36:57 florian
  492. * some cg reorganisation
  493. * some PPC updates
  494. Revision 1.19 2001/08/01 21:44:59 peter
  495. * fixed empty pwidechar register allocation
  496. Revision 1.18 2001/07/30 20:59:29 peter
  497. * m68k updates from v10 merged
  498. Revision 1.17 2001/07/16 13:19:08 jonas
  499. * fixed allocation of register before release in second_cstring_to_pchar
  500. Revision 1.16 2001/07/08 21:00:17 peter
  501. * various widestring updates, it works now mostly without charset
  502. mapping supported
  503. Revision 1.15 2001/05/08 21:06:33 florian
  504. * some more support for widechars commited especially
  505. regarding type casting and constants
  506. Revision 1.14 2001/04/13 01:22:18 peter
  507. * symtable change to classes
  508. * range check generation and errors fixed, make cycle DEBUG=1 works
  509. * memory leaks fixed
  510. Revision 1.13 2001/04/02 21:20:36 peter
  511. * resulttype rewrite
  512. Revision 1.12 2001/01/08 21:45:11 peter
  513. * internalerror for string to chararray
  514. Revision 1.11 2000/12/25 00:07:32 peter
  515. + new tlinkedlist class (merge of old tstringqueue,tcontainer and
  516. tlinkedlist objects)
  517. Revision 1.10 2000/12/07 17:19:46 jonas
  518. * new constant handling: from now on, hex constants >$7fffffff are
  519. parsed as unsigned constants (otherwise, $80000000 got sign extended
  520. and became $ffffffff80000000), all constants in the longint range
  521. become longints, all constants >$7fffffff and <=cardinal($ffffffff)
  522. are cardinals and the rest are int64's.
  523. * added lots of longint typecast to prevent range check errors in the
  524. compiler and rtl
  525. * type casts of symbolic ordinal constants are now preserved
  526. * fixed bug where the original resulttype.def wasn't restored correctly
  527. after doing a 64bit rangecheck
  528. Revision 1.9 2000/12/05 11:44:33 jonas
  529. + new integer regvar handling, should be much more efficient
  530. Revision 1.8 2000/11/29 00:30:46 florian
  531. * unused units removed from uses clause
  532. * some changes for widestrings
  533. Revision 1.7 2000/11/16 15:27:48 jonas
  534. * fixed web bug 1242
  535. Revision 1.6 2000/11/13 11:30:56 florian
  536. * some bugs with interfaces and NIL fixed
  537. Revision 1.5 2000/11/12 23:24:14 florian
  538. * interfaces are basically running
  539. Revision 1.4 2000/11/11 16:00:10 jonas
  540. * optimize converting of 8/16/32 bit constants to 64bit ones
  541. Revision 1.3 2000/11/04 14:25:23 florian
  542. + merged Attila's changes for interfaces, not tested yet
  543. Revision 1.2 2000/10/31 22:02:56 peter
  544. * symtable splitted, no real code changes
  545. Revision 1.1 2000/10/15 09:33:31 peter
  546. * moved n386*.pas to i386/ cpu_target dir
  547. Revision 1.1 2000/10/14 10:14:48 peter
  548. * moehrendorf oct 2000 rewrite
  549. }