n386cnv.pas 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626
  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.30 2002-03-04 19:10:13 peter
  457. * removed compiler warnings
  458. Revision 1.29 2001/12/30 17:24:46 jonas
  459. * range checking is now processor independent (part in cgobj,
  460. part in cg64f32) and should work correctly again (it needed
  461. some changes after the changes of the low and high of
  462. tordef's to int64)
  463. * maketojumpbool() is now processor independent (in ncgutil)
  464. * getregister32 is now called getregisterint
  465. Revision 1.28 2001/12/11 08:14:17 jonas
  466. * part of my fix for dynarray -> open array conversion, forgot to
  467. commit yesterday :(
  468. Revision 1.27 2001/11/02 23:24:12 jonas
  469. * fixed web bug 1665 (allow char to chararray type conversion) ("merged")
  470. Revision 1.26 2001/09/30 21:28:34 peter
  471. * int64->boolean fixed
  472. Revision 1.25 2001/09/30 16:12:47 jonas
  473. - removed unnecessary i386 pass_2 of as- and isnode and added dummy generic ones
  474. Revision 1.24 2001/09/29 21:32:47 jonas
  475. * almost all second pass typeconvnode helpers are now processor independent
  476. * fixed converting boolean to int64/qword
  477. * fixed register allocation bugs which could cause internalerror 10
  478. * isnode and asnode are completely processor indepent now as well
  479. * fpc_do_as now returns its class argument (necessary to be able to use it
  480. properly with compilerproc)
  481. Revision 1.23 2001/09/03 13:27:42 jonas
  482. * compilerproc implementation of set addition/substraction/...
  483. * changed the declaration of some set helpers somewhat to accomodate the
  484. above change
  485. * i386 still uses the old code for comparisons of sets, because its
  486. helpers return the results in the flags
  487. * dummy tc_normal_2_small_set type conversion because I need the original
  488. resulttype of the set add nodes
  489. NOTE: you have to start a cycle with 1.0.5!
  490. Revision 1.22 2001/08/29 19:49:03 jonas
  491. * some fixes in compilerprocs for chararray to string conversions
  492. * conversion from string to chararray is now also done via compilerprocs
  493. Revision 1.21 2001/08/28 13:24:47 jonas
  494. + compilerproc implementation of most string-related type conversions
  495. - removed all code from the compiler which has been replaced by
  496. compilerproc implementations (using $ifdef hascompilerproc is not
  497. necessary in the compiler)
  498. Revision 1.20 2001/08/26 13:36:57 florian
  499. * some cg reorganisation
  500. * some PPC updates
  501. Revision 1.19 2001/08/01 21:44:59 peter
  502. * fixed empty pwidechar register allocation
  503. Revision 1.18 2001/07/30 20:59:29 peter
  504. * m68k updates from v10 merged
  505. Revision 1.17 2001/07/16 13:19:08 jonas
  506. * fixed allocation of register before release in second_cstring_to_pchar
  507. Revision 1.16 2001/07/08 21:00:17 peter
  508. * various widestring updates, it works now mostly without charset
  509. mapping supported
  510. Revision 1.15 2001/05/08 21:06:33 florian
  511. * some more support for widechars commited especially
  512. regarding type casting and constants
  513. Revision 1.14 2001/04/13 01:22:18 peter
  514. * symtable change to classes
  515. * range check generation and errors fixed, make cycle DEBUG=1 works
  516. * memory leaks fixed
  517. Revision 1.13 2001/04/02 21:20:36 peter
  518. * resulttype rewrite
  519. Revision 1.12 2001/01/08 21:45:11 peter
  520. * internalerror for string to chararray
  521. Revision 1.11 2000/12/25 00:07:32 peter
  522. + new tlinkedlist class (merge of old tstringqueue,tcontainer and
  523. tlinkedlist objects)
  524. Revision 1.10 2000/12/07 17:19:46 jonas
  525. * new constant handling: from now on, hex constants >$7fffffff are
  526. parsed as unsigned constants (otherwise, $80000000 got sign extended
  527. and became $ffffffff80000000), all constants in the longint range
  528. become longints, all constants >$7fffffff and <=cardinal($ffffffff)
  529. are cardinals and the rest are int64's.
  530. * added lots of longint typecast to prevent range check errors in the
  531. compiler and rtl
  532. * type casts of symbolic ordinal constants are now preserved
  533. * fixed bug where the original resulttype.def wasn't restored correctly
  534. after doing a 64bit rangecheck
  535. Revision 1.9 2000/12/05 11:44:33 jonas
  536. + new integer regvar handling, should be much more efficient
  537. Revision 1.8 2000/11/29 00:30:46 florian
  538. * unused units removed from uses clause
  539. * some changes for widestrings
  540. Revision 1.7 2000/11/16 15:27:48 jonas
  541. * fixed web bug 1242
  542. Revision 1.6 2000/11/13 11:30:56 florian
  543. * some bugs with interfaces and NIL fixed
  544. Revision 1.5 2000/11/12 23:24:14 florian
  545. * interfaces are basically running
  546. Revision 1.4 2000/11/11 16:00:10 jonas
  547. * optimize converting of 8/16/32 bit constants to 64bit ones
  548. Revision 1.3 2000/11/04 14:25:23 florian
  549. + merged Attila's changes for interfaces, not tested yet
  550. Revision 1.2 2000/10/31 22:02:56 peter
  551. * symtable splitted, no real code changes
  552. Revision 1.1 2000/10/15 09:33:31 peter
  553. * moved n386*.pas to i386/ cpu_target dir
  554. Revision 1.1 2000/10/14 10:14:48 peter
  555. * moehrendorf oct 2000 rewrite
  556. }