n386inl.pas 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676
  1. {
  2. $Id$
  3. Copyright (c) 1998-2000 by Florian Klaempfl
  4. Generate i386 inline 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 n386inl;
  19. {$i defines.inc}
  20. interface
  21. uses
  22. node,ninl;
  23. type
  24. ti386inlinenode = class(tinlinenode)
  25. procedure pass_2;override;
  26. end;
  27. implementation
  28. uses
  29. globtype,systems,
  30. cutils,verbose,globals,fmodule,
  31. symconst,symtype,symdef,aasm,types,
  32. cginfo,cgbase,pass_1,pass_2,
  33. cpubase,
  34. nbas,ncon,ncal,ncnv,nld,
  35. cga,tgobj,n386util,ncgutil,cgobj,cg64f32,rgobj,rgcpu;
  36. {*****************************************************************************
  37. TI386INLINENODE
  38. *****************************************************************************}
  39. procedure ti386inlinenode.pass_2;
  40. const
  41. {tfloattype = (s32real,s64real,s80real,s64bit,f16bit,f32bit);}
  42. { float_name: array[tfloattype] of string[8]=
  43. ('S32REAL','S64REAL','S80REAL','S64BIT','F16BIT','F32BIT'); }
  44. addsubop:array[in_inc_x..in_dec_x] of TOpCG=(OP_ADD,OP_SUB);
  45. var
  46. asmop : tasmop;
  47. {inc/dec}
  48. addconstant : boolean;
  49. addvalue : longint;
  50. href : treference;
  51. hp2 : tstringconstnode;
  52. l : longint;
  53. ispushed : boolean;
  54. hregisterhi,
  55. hregister : tregister;
  56. lengthlab,
  57. otlabel,oflabel{,l1} : tasmlabel;
  58. oldpushedparasize : longint;
  59. cgop : TOpCG;
  60. cgsize : TCGSize;
  61. begin
  62. { save & reset pushedparasize }
  63. oldpushedparasize:=pushedparasize;
  64. pushedparasize:=0;
  65. case inlinenumber of
  66. in_assert_x_y:
  67. begin
  68. { the node should be removed in the firstpass }
  69. if not (cs_do_assertion in aktlocalswitches) then
  70. internalerror(7123458);
  71. otlabel:=truelabel;
  72. oflabel:=falselabel;
  73. getlabel(truelabel);
  74. getlabel(falselabel);
  75. secondpass(tcallparanode(left).left);
  76. maketojumpbool(tcallparanode(left).left,lr_load_regvars);
  77. emitlab(falselabel);
  78. { erroraddr }
  79. emit_reg(A_PUSH,S_L,R_EBP);
  80. { lineno }
  81. emit_const(A_PUSH,S_L,aktfilepos.line);
  82. { filename string }
  83. hp2:=cstringconstnode.createstr(current_module.sourcefiles.get_file_name(aktfilepos.fileindex),st_shortstring);
  84. firstpass(hp2);
  85. secondpass(hp2);
  86. if codegenerror then
  87. exit;
  88. emitpushreferenceaddr(hp2.location.reference);
  89. hp2.free;
  90. { push msg }
  91. secondpass(tcallparanode(tcallparanode(left).right).left);
  92. emitpushreferenceaddr(tcallparanode(tcallparanode(left).right).left.location.reference);
  93. { call }
  94. emitcall('FPC_ASSERT');
  95. emitlab(truelabel);
  96. truelabel:=otlabel;
  97. falselabel:=oflabel;
  98. end;
  99. in_sizeof_x,
  100. in_typeof_x :
  101. begin
  102. location_reset(location,LOC_REGISTER,OS_ADDR);
  103. { for both cases load vmt }
  104. if left.nodetype=typen then
  105. begin
  106. location.register:=rg.getregisterint(exprasmlist);
  107. emit_sym_ofs_reg(A_MOV,
  108. S_L,newasmsymbol(tobjectdef(left.resulttype.def).vmt_mangledname),0,
  109. location.register);
  110. end
  111. else
  112. begin
  113. secondpass(left);
  114. location_release(exprasmlist,left.location);
  115. location.register:=rg.getregisterint(exprasmlist);
  116. { load VMT pointer }
  117. inc(left.location.reference.offset,
  118. tobjectdef(left.resulttype.def).vmt_offset);
  119. emit_ref_reg(A_MOV,S_L,left.location.reference,location.register);
  120. end;
  121. { in sizeof load size }
  122. if inlinenumber=in_sizeof_x then
  123. begin
  124. reference_reset_base(href,location.register,0);
  125. emit_ref_reg(A_MOV,S_L,href,location.register);
  126. end;
  127. end;
  128. in_length_x :
  129. begin
  130. secondpass(left);
  131. { length in ansi strings is at offset -8 }
  132. if is_ansistring(left.resulttype.def) or
  133. is_widestring(left.resulttype.def) then
  134. begin
  135. if left.location.loc<>LOC_REGISTER then
  136. begin
  137. location_release(exprasmlist,left.location);
  138. hregister:=rg.getregisterint(exprasmlist);
  139. cg.a_load_loc_reg(exprasmlist,left.location,hregister);
  140. end
  141. else
  142. hregister:=left.location.register;
  143. reference_reset_base(href,hregister,-8);
  144. getlabel(lengthlab);
  145. emit_reg_reg(A_OR,S_L,hregister,hregister);
  146. emitjmp(C_Z,lengthlab);
  147. emit_ref_reg(A_MOV,S_L,href,hregister);
  148. emitlab(lengthlab);
  149. location_reset(location,LOC_REGISTER,OS_INT);
  150. location.register:=hregister;
  151. end
  152. else
  153. begin
  154. location_copy(location,left.location);
  155. location.size:=OS_8;
  156. end;
  157. end;
  158. in_pred_x,
  159. in_succ_x:
  160. begin
  161. secondpass(left);
  162. if inlinenumber=in_pred_x then
  163. cgop:=OP_SUB
  164. else
  165. cgop:=OP_ADD;
  166. cgsize:=def_cgsize(resulttype.def);
  167. { we need a value in a register }
  168. location_copy(location,left.location);
  169. location_force_reg(location,cgsize,false);
  170. if cgsize in [OS_64,OS_S64] then
  171. tcg64f32(cg).a_op64_const_reg(exprasmlist,cgop,1,0,
  172. location.registerlow,location.registerhigh)
  173. else
  174. cg.a_op_const_reg(exprasmlist,cgop,1,location.register);
  175. emitoverflowcheck(self);
  176. cg.g_rangecheck(exprasmlist,self,resulttype.def);
  177. end;
  178. in_dec_x,
  179. in_inc_x :
  180. begin
  181. { set defaults }
  182. addconstant:=true;
  183. { load first parameter, must be a reference }
  184. secondpass(tcallparanode(left).left);
  185. cgsize:=def_cgsize(tcallparanode(left).left.resulttype.def);
  186. { get addvalue }
  187. case tcallparanode(left).left.resulttype.def.deftype of
  188. orddef,
  189. enumdef :
  190. addvalue:=1;
  191. pointerdef :
  192. begin
  193. if is_void(tpointerdef(tcallparanode(left).left.resulttype.def).pointertype.def) then
  194. addvalue:=1
  195. else
  196. addvalue:=tpointerdef(tcallparanode(left).left.resulttype.def).pointertype.def.size;
  197. end;
  198. else
  199. internalerror(10081);
  200. end;
  201. { second argument specified?, must be a s32bit in register }
  202. if assigned(tcallparanode(left).right) then
  203. begin
  204. ispushed:=maybe_push(tcallparanode(tcallparanode(left).right).left.registers32,
  205. tcallparanode(left).left,false);
  206. secondpass(tcallparanode(tcallparanode(left).right).left);
  207. if ispushed then
  208. restore(tcallparanode(left).left,false);
  209. { when constant, just multiply the addvalue }
  210. if is_constintnode(tcallparanode(tcallparanode(left).right).left) then
  211. addvalue:=addvalue*get_ordinal_value(tcallparanode(tcallparanode(left).right).left)
  212. else
  213. begin
  214. location_force_reg(tcallparanode(tcallparanode(left).right).left.location,cgsize,false);
  215. hregister:=tcallparanode(tcallparanode(left).right).left.location.register;
  216. hregisterhi:=tcallparanode(tcallparanode(left).right).left.location.registerhigh;
  217. { insert multiply with addvalue if its >1 }
  218. if addvalue>1 then
  219. cg.a_op_const_reg(exprasmlist,OP_IMUL,addvalue,hregister);
  220. addconstant:=false;
  221. end;
  222. end;
  223. { write the add instruction }
  224. if addconstant then
  225. begin
  226. if cgsize in [OS_64,OS_S64] then
  227. tcg64f32(cg).a_op64_const_loc(exprasmlist,addsubop[inlinenumber],
  228. addvalue,0,tcallparanode(left).left.location)
  229. else
  230. cg.a_op_const_loc(exprasmlist,addsubop[inlinenumber],
  231. addvalue,tcallparanode(left).left.location);
  232. end
  233. else
  234. begin
  235. if cgsize in [OS_64,OS_S64] then
  236. tcg64f32(cg).a_op64_reg_loc(exprasmlist,addsubop[inlinenumber],
  237. hregister,hregisterhi,tcallparanode(left).left.location)
  238. else
  239. cg.a_op_reg_loc(exprasmlist,addsubop[inlinenumber],
  240. hregister,tcallparanode(left).left.location);
  241. location_release(exprasmlist,tcallparanode(tcallparanode(left).right).left.location);
  242. end;
  243. emitoverflowcheck(tcallparanode(left).left);
  244. cg.g_rangecheck(exprasmlist,tcallparanode(left).left,tcallparanode(left).left.resulttype.def);
  245. end;
  246. in_typeinfo_x:
  247. begin
  248. location_reset(location,LOC_REGISTER,OS_ADDR);
  249. location.register:=rg.getregisterint(exprasmlist);
  250. reference_reset_symbol(href,tstoreddef(ttypenode(tcallparanode(left).left).resulttype.def).get_rtti_label(fullrtti),0);
  251. emit_ref_reg(A_LEA,S_L,href,location.register);
  252. end;
  253. in_assigned_x :
  254. begin
  255. secondpass(tcallparanode(left).left);
  256. location_release(exprasmlist,tcallparanode(left).left.location);
  257. if (tcallparanode(left).left.location.loc in [LOC_REGISTER,LOC_CREGISTER]) then
  258. begin
  259. emit_reg_reg(A_OR,S_L,
  260. tcallparanode(left).left.location.register,
  261. tcallparanode(left).left.location.register);
  262. end
  263. else
  264. begin
  265. emit_const_ref(A_CMP,S_L,0,tcallparanode(left).left.location.reference);
  266. end;
  267. location_reset(location,LOC_FLAGS,OS_NO);
  268. location.resflags:=F_NE;
  269. end;
  270. in_include_x_y,
  271. in_exclude_x_y:
  272. begin
  273. location_copy(location,left.location);
  274. secondpass(tcallparanode(left).left);
  275. if tcallparanode(tcallparanode(left).right).left.nodetype=ordconstn then
  276. begin
  277. { calculate bit position }
  278. l:=1 shl (tordconstnode(tcallparanode(tcallparanode(left).right).left).value mod 32);
  279. { determine operator }
  280. if inlinenumber=in_include_x_y then
  281. asmop:=A_OR
  282. else
  283. begin
  284. asmop:=A_AND;
  285. l:=not(l);
  286. end;
  287. if (tcallparanode(left).left.location.loc=LOC_REFERENCE) then
  288. begin
  289. inc(tcallparanode(left).left.location.reference.offset,
  290. (tordconstnode(tcallparanode(tcallparanode(left).right).left).value div 32)*4);
  291. emit_const_ref(asmop,S_L,l,tcallparanode(left).left.location.reference);
  292. location_release(exprasmlist,tcallparanode(left).left.location);
  293. end
  294. else
  295. { LOC_CREGISTER }
  296. begin
  297. secondpass(tcallparanode(left).left);
  298. emit_const_reg(asmop,S_L,
  299. l,tcallparanode(left).left.location.register);
  300. end;
  301. end
  302. else
  303. begin
  304. { generate code for the element to set }
  305. ispushed:=maybe_push(tcallparanode(tcallparanode(left).right).left.registers32,
  306. tcallparanode(left).left,false);
  307. secondpass(tcallparanode(tcallparanode(left).right).left);
  308. if ispushed then
  309. restore(tcallparanode(left).left,false);
  310. { determine asm operator }
  311. if inlinenumber=in_include_x_y then
  312. asmop:=A_BTS
  313. else
  314. asmop:=A_BTR;
  315. if tcallparanode(tcallparanode(left).right).left.location.loc in [LOC_CREGISTER,LOC_REGISTER] then
  316. { we don't need a mod 32 because this is done automatically }
  317. { by the bts instruction. For proper checking we would }
  318. { note: bts doesn't do any mod'ing, that's why we can also use }
  319. { it for normalsets! (JM) }
  320. { need a cmp and jmp, but this should be done by the }
  321. { type cast code which does range checking if necessary (FK) }
  322. begin
  323. hregister := rg.makeregsize(tcallparanode(tcallparanode(left).right).left.location.register,OS_INT);
  324. end
  325. else
  326. begin
  327. rg.getexplicitregisterint(exprasmlist,R_EDI);
  328. hregister:=R_EDI;
  329. end;
  330. cg.a_load_loc_reg(exprasmlist,tcallparanode(tcallparanode(left).right).left.location,hregister);
  331. if (tcallparanode(left).left.location.loc=LOC_REFERENCE) then
  332. emit_reg_ref(asmop,S_L,hregister,tcallparanode(left).left.location.reference)
  333. else
  334. emit_reg_reg(asmop,S_L,hregister,tcallparanode(left).left.location.register);
  335. if hregister = R_EDI then
  336. rg.ungetregisterint(exprasmlist,R_EDI);
  337. end;
  338. end;
  339. in_pi:
  340. begin
  341. location_reset(location,LOC_FPUREGISTER,def_cgsize(resulttype.def));
  342. emit_none(A_FLDPI,S_NO);
  343. inc(trgcpu(rg).fpuvaroffset);
  344. location.register:=R_ST;
  345. end;
  346. in_sin_extended,
  347. in_arctan_extended,
  348. in_abs_extended,
  349. in_sqr_extended,
  350. in_sqrt_extended,
  351. in_ln_extended,
  352. in_cos_extended:
  353. begin
  354. location_reset(location,LOC_FPUREGISTER,def_cgsize(resulttype.def));
  355. location.register:=R_ST;
  356. secondpass(left);
  357. case left.location.loc of
  358. LOC_FPUREGISTER:
  359. ;
  360. LOC_CFPUREGISTER:
  361. begin
  362. cg.a_loadfpu_reg_reg(exprasmlist,
  363. left.location.register,location.register);
  364. end;
  365. LOC_REFERENCE,LOC_CREFERENCE:
  366. begin
  367. cg.a_loadfpu_ref_reg(exprasmlist,
  368. def_cgsize(left.resulttype.def),
  369. left.location.reference,location.register);
  370. location_release(exprasmlist,left.location);
  371. end
  372. else
  373. internalerror(309991);
  374. end;
  375. case inlinenumber of
  376. in_sin_extended,
  377. in_cos_extended:
  378. begin
  379. if inlinenumber=in_sin_extended then
  380. emit_none(A_FSIN,S_NO)
  381. else
  382. emit_none(A_FCOS,S_NO);
  383. {
  384. getlabel(l1);
  385. emit_reg(A_FNSTSW,S_NO,R_AX);
  386. emit_none(A_SAHF,S_NO);
  387. emitjmp(C_NP,l1);
  388. emit_reg(A_FSTP,S_NO,R_ST0);
  389. emit_none(A_FLDZ,S_NO);
  390. emitlab(l1);
  391. }
  392. end;
  393. in_arctan_extended:
  394. begin
  395. emit_none(A_FLD1,S_NO);
  396. emit_none(A_FPATAN,S_NO);
  397. end;
  398. in_abs_extended:
  399. emit_none(A_FABS,S_NO);
  400. in_sqr_extended:
  401. begin
  402. (* emit_reg(A_FLD,S_NO,R_ST0);
  403. { emit_none(A_FMULP,S_NO); nasm does not accept this PM }
  404. emit_reg_reg(A_FMULP,S_NO,R_ST0,R_ST1);
  405. can be shorten to *)
  406. emit_reg_reg(A_FMUL,S_NO,R_ST0,R_ST0);
  407. end;
  408. in_sqrt_extended:
  409. emit_none(A_FSQRT,S_NO);
  410. in_ln_extended:
  411. begin
  412. emit_none(A_FLDLN2,S_NO);
  413. emit_none(A_FXCH,S_NO);
  414. emit_none(A_FYL2X,S_NO);
  415. end;
  416. end;
  417. end;
  418. {$ifdef SUPPORT_MMX}
  419. in_mmx_pcmpeqb..in_mmx_pcmpgtw:
  420. begin
  421. location_reset(location,LOC_MMXREGISTER,OS_NO);
  422. if left.location.loc=LOC_REGISTER then
  423. begin
  424. {!!!!!!!}
  425. end
  426. else if tcallparanode(left).left.location.loc=LOC_REGISTER then
  427. begin
  428. {!!!!!!!}
  429. end
  430. else
  431. begin
  432. {!!!!!!!}
  433. end;
  434. end;
  435. {$endif SUPPORT_MMX}
  436. else internalerror(9);
  437. end;
  438. { reset pushedparasize }
  439. pushedparasize:=oldpushedparasize;
  440. end;
  441. begin
  442. cinlinenode:=ti386inlinenode;
  443. end.
  444. {
  445. $Log$
  446. Revision 1.39 2002-04-23 19:16:35 peter
  447. * add pinline unit that inserts compiler supported functions using
  448. one or more statements
  449. * moved finalize and setlength from ninl to pinline
  450. Revision 1.38 2002/04/21 15:35:54 carl
  451. * changeregsize -> rg.makeregsize
  452. Revision 1.37 2002/04/19 15:39:35 peter
  453. * removed some more routines from cga
  454. * moved location_force_reg/mem to ncgutil
  455. * moved arrayconstructnode secondpass to ncgld
  456. Revision 1.36 2002/04/15 19:44:21 peter
  457. * fixed stackcheck that would be called recursively when a stack
  458. error was found
  459. * generic changeregsize(reg,size) for i386 register resizing
  460. * removed some more routines from cga unit
  461. * fixed returnvalue handling
  462. * fixed default stacksize of linux and go32v2, 8kb was a bit small :-)
  463. Revision 1.35 2002/04/04 19:06:11 peter
  464. * removed unused units
  465. * use tlocation.size in cg.a_*loc*() routines
  466. Revision 1.34 2002/04/02 17:11:36 peter
  467. * tlocation,treference update
  468. * LOC_CONSTANT added for better constant handling
  469. * secondadd splitted in multiple routines
  470. * location_force_reg added for loading a location to a register
  471. of a specified size
  472. * secondassignment parses now first the right and then the left node
  473. (this is compatible with Kylix). This saves a lot of push/pop especially
  474. with string operations
  475. * adapted some routines to use the new cg methods
  476. Revision 1.33 2002/03/31 20:26:39 jonas
  477. + a_loadfpu_* and a_loadmm_* methods in tcg
  478. * register allocation is now handled by a class and is mostly processor
  479. independent (+rgobj.pas and i386/rgcpu.pas)
  480. * temp allocation is now handled by a class (+tgobj.pas, -i386\tgcpu.pas)
  481. * some small improvements and fixes to the optimizer
  482. * some register allocation fixes
  483. * some fpuvaroffset fixes in the unary minus node
  484. * push/popusedregisters is now called rg.save/restoreusedregisters and
  485. (for i386) uses temps instead of push/pop's when using -Op3 (that code is
  486. also better optimizable)
  487. * fixed and optimized register saving/restoring for new/dispose nodes
  488. * LOC_FPU locations now also require their "register" field to be set to
  489. R_ST, not R_ST0 (the latter is used for LOC_CFPUREGISTER locations only)
  490. - list field removed of the tnode class because it's not used currently
  491. and can cause hard-to-find bugs
  492. Revision 1.32 2002/03/04 19:10:14 peter
  493. * removed compiler warnings
  494. Revision 1.31 2001/12/30 17:24:46 jonas
  495. * range checking is now processor independent (part in cgobj,
  496. part in cg64f32) and should work correctly again (it needed
  497. some changes after the changes of the low and high of
  498. tordef's to int64)
  499. * maketojumpbool() is now processor independent (in ncgutil)
  500. * getregister32 is now called getregisterint
  501. Revision 1.30 2001/12/10 14:34:04 jonas
  502. * fixed type conversions from dynamic arrays to open arrays
  503. Revision 1.29 2001/12/04 15:59:03 jonas
  504. * converted lo/hi to processor independent code, generated code is the
  505. same as before (when turning on the optimizer)
  506. Revision 1.28 2001/12/02 16:19:17 jonas
  507. * less unnecessary regvar loading with if-statements
  508. Revision 1.26 2001/09/28 20:38:51 jonas
  509. * fixed big bug in my previous changes (the arguent for bts/btr is always
  510. a 32 bit register, but it wasn't cleared properly if the value was only
  511. an 8 bit one)
  512. Revision 1.25 2001/09/27 13:03:18 jonas
  513. * fixed bug reported by sg about self not being restored after calling
  514. setlength
  515. Revision 1.24 2001/09/04 14:32:45 jonas
  516. * simplified det_resulttype code for include/exclude
  517. * include/exclude doesn't use any helpers anymore in the i386 secondpass
  518. Revision 1.23 2001/08/30 20:13:57 peter
  519. * rtti/init table updates
  520. * rttisym for reusable global rtti/init info
  521. * support published for interfaces
  522. Revision 1.22 2001/08/28 13:24:47 jonas
  523. + compilerproc implementation of most string-related type conversions
  524. - removed all code from the compiler which has been replaced by
  525. compilerproc implementations (using ($ifdef hascompilerproc) is not
  526. necessary in the compiler)
  527. Revision 1.21 2001/08/26 13:36:58 florian
  528. * some cg reorganisation
  529. * some PPC updates
  530. Revision 1.20 2001/08/24 12:33:54 jonas
  531. * fixed big bug in handle_str that caused it to (almost) always call
  532. fpc_<stringtype>_longint
  533. * fixed small bug in handle_read_write that caused wrong warnigns about
  534. uninitialized vars with read(ln)
  535. + handle_val (processor independent val() handling)
  536. Revision 1.19 2001/08/23 14:28:36 jonas
  537. + tempcreate/ref/delete nodes (allows the use of temps in the
  538. resulttype and first pass)
  539. * made handling of read(ln)/write(ln) processor independent
  540. * moved processor independent handling for str and reset/rewrite-typed
  541. from firstpass to resulttype pass
  542. * changed names of helpers in text.inc to be generic for use as
  543. compilerprocs + added "iocheck" directive for most of them
  544. * reading of ordinals is done by procedures instead of functions
  545. because otherwise FPC_IOCHECK overwrote the result before it could
  546. be stored elsewhere (range checking still works)
  547. * compilerprocs can now be used in the system unit before they are
  548. implemented
  549. * added note to errore.msg that booleans can't be read using read/readln
  550. Revision 1.18 2001/08/13 15:39:52 jonas
  551. * made in_reset_typedfile/in_rewrite_typedfile handling processor
  552. independent
  553. Revision 1.17 2001/08/13 12:41:57 jonas
  554. * made code for str(x,y) completely processor independent
  555. Revision 1.16 2001/07/10 18:01:08 peter
  556. * internal length for ansistring and widestrings
  557. Revision 1.15 2001/07/08 21:00:18 peter
  558. * various widestring updates, it works now mostly without charset
  559. mapping supported
  560. Revision 1.14 2001/04/13 01:22:19 peter
  561. * symtable change to classes
  562. * range check generation and errors fixed, make cycle DEBUG=1 works
  563. * memory leaks fixed
  564. Revision 1.13 2001/04/02 21:20:37 peter
  565. * resulttype rewrite
  566. Revision 1.12 2001/03/13 11:52:48 jonas
  567. * fixed some memory leaks
  568. Revision 1.11 2000/12/25 00:07:33 peter
  569. + new tlinkedlist class (merge of old tstringqueue,tcontainer and
  570. tlinkedlist objects)
  571. Revision 1.10 2000/12/09 22:51:37 florian
  572. * helper name of val for qword fixed
  573. Revision 1.9 2000/12/07 17:19:46 jonas
  574. * new constant handling: from now on, hex constants >$7fffffff are
  575. parsed as unsigned constants (otherwise, $80000000 got sign extended
  576. and became $ffffffff80000000), all constants in the longint range
  577. become longints, all constants >$7fffffff and <=cardinal($ffffffff)
  578. are cardinals and the rest are int64's.
  579. * added lots of longint typecast to prevent range check errors in the
  580. compiler and rtl
  581. * type casts of symbolic ordinal constants are now preserved
  582. * fixed bug where the original resulttype.def wasn't restored correctly
  583. after doing a 64bit rangecheck
  584. Revision 1.8 2000/12/05 11:44:33 jonas
  585. + new integer regvar handling, should be much more efficient
  586. Revision 1.7 2000/11/29 00:30:47 florian
  587. * unused units removed from uses clause
  588. * some changes for widestrings
  589. Revision 1.6 2000/11/12 23:24:15 florian
  590. * interfaces are basically running
  591. Revision 1.5 2000/11/09 17:46:56 florian
  592. * System.TypeInfo fixed
  593. + System.Finalize implemented
  594. + some new keywords for interface support added
  595. Revision 1.4 2000/10/31 22:02:56 peter
  596. * symtable splitted, no real code changes
  597. Revision 1.3 2000/10/26 14:15:07 jonas
  598. * fixed setlength for shortstrings
  599. Revision 1.2 2000/10/21 18:16:13 florian
  600. * a lot of changes:
  601. - basic dyn. array support
  602. - basic C++ support
  603. - some work for interfaces done
  604. ....
  605. Revision 1.1 2000/10/15 09:33:31 peter
  606. * moved n386*.pas to i386/ cpu_target dir
  607. Revision 1.2 2000/10/15 09:08:58 peter
  608. * use System for the systemunit instead of target dependent
  609. Revision 1.1 2000/10/14 10:14:49 peter
  610. * moehrendorf oct 2000 rewrite
  611. }