nmat.pas 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766
  1. {
  2. $Id$
  3. Copyright (c) 2000-2002 by Florian Klaempfl
  4. Type checking and register allocation for math 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 nmat;
  19. {$i fpcdefs.inc}
  20. interface
  21. uses
  22. node;
  23. type
  24. tmoddivnode = class(tbinopnode)
  25. function pass_1 : tnode;override;
  26. function det_resulttype:tnode;override;
  27. protected
  28. { override the following if you want to implement }
  29. { parts explicitely in the code generator (JM) }
  30. function first_moddiv64bitint: tnode; virtual;
  31. function firstoptimize: tnode; virtual;
  32. end;
  33. tmoddivnodeclass = class of tmoddivnode;
  34. tshlshrnode = class(tbinopnode)
  35. function pass_1 : tnode;override;
  36. function det_resulttype:tnode;override;
  37. end;
  38. tshlshrnodeclass = class of tshlshrnode;
  39. tunaryminusnode = class(tunarynode)
  40. constructor create(expr : tnode);virtual;
  41. function pass_1 : tnode;override;
  42. function det_resulttype:tnode;override;
  43. end;
  44. tunaryminusnodeclass = class of tunaryminusnode;
  45. tnotnode = class(tunarynode)
  46. constructor create(expr : tnode);virtual;
  47. function pass_1 : tnode;override;
  48. function det_resulttype:tnode;override;
  49. {$ifdef state_tracking}
  50. function track_state_pass(exec_known:boolean):boolean;override;
  51. {$endif}
  52. end;
  53. tnotnodeclass = class of tnotnode;
  54. var
  55. cmoddivnode : tmoddivnodeclass;
  56. cshlshrnode : tshlshrnodeclass;
  57. cunaryminusnode : tunaryminusnodeclass;
  58. cnotnode : tnotnodeclass;
  59. implementation
  60. uses
  61. systems,tokens,
  62. verbose,globals,cutils,
  63. globtype,
  64. symconst,symtype,symtable,symdef,defbase,
  65. htypechk,pass_1,cpubase,
  66. cgbase,
  67. ncon,ncnv,ncal,nadd;
  68. {****************************************************************************
  69. TMODDIVNODE
  70. ****************************************************************************}
  71. function tmoddivnode.det_resulttype:tnode;
  72. var
  73. t : tnode;
  74. rd,ld : tdef;
  75. rv,lv : tconstexprint;
  76. begin
  77. result:=nil;
  78. resulttypepass(left);
  79. resulttypepass(right);
  80. set_varstate(left,true);
  81. set_varstate(right,true);
  82. if codegenerror then
  83. exit;
  84. { constant folding }
  85. if is_constintnode(left) and is_constintnode(right) then
  86. begin
  87. rv:=tordconstnode(right).value;
  88. lv:=tordconstnode(left).value;
  89. { check for division by zero }
  90. if (rv=0) then
  91. begin
  92. Message(parser_e_division_by_zero);
  93. { recover }
  94. rv:=1;
  95. end;
  96. case nodetype of
  97. modn:
  98. t:=genintconstnode(lv mod rv);
  99. divn:
  100. t:=genintconstnode(lv div rv);
  101. end;
  102. result:=t;
  103. exit;
  104. end;
  105. { allow operator overloading }
  106. t:=self;
  107. if isbinaryoverloaded(t) then
  108. begin
  109. result:=t;
  110. exit;
  111. end;
  112. { if one operand is a cardinal and the other is a positive constant, convert the }
  113. { constant to a cardinal as well so we don't have to do a 64bit division (JM) }
  114. { Do the same for qwords and positive constants as well, otherwise things like }
  115. { "qword mod 10" are evaluated with int64 as result, which is wrong if the }
  116. { "qword" was > high(int64) (JM) }
  117. if (left.resulttype.def.deftype=orddef) and (right.resulttype.def.deftype=orddef) then
  118. if (torddef(right.resulttype.def).typ in [u32bit,u64bit]) and
  119. is_constintnode(left) and
  120. (tordconstnode(left).value >= 0) then
  121. inserttypeconv(left,right.resulttype)
  122. else if (torddef(left.resulttype.def).typ in [u32bit,u64bit]) and
  123. is_constintnode(right) and
  124. (tordconstnode(right).value >= 0) then
  125. inserttypeconv(right,left.resulttype);
  126. if (left.resulttype.def.deftype=orddef) and (right.resulttype.def.deftype=orddef) and
  127. (is_64bitint(left.resulttype.def) or is_64bitint(right.resulttype.def) or
  128. { when mixing cardinals and signed numbers, convert everythign to 64bit (JM) }
  129. ((torddef(right.resulttype.def).typ = u32bit) and
  130. is_signed(left.resulttype.def)) or
  131. ((torddef(left.resulttype.def).typ = u32bit) and
  132. is_signed(right.resulttype.def))) then
  133. begin
  134. rd:=right.resulttype.def;
  135. ld:=left.resulttype.def;
  136. { issue warning if necessary }
  137. if not (is_64bitint(left.resulttype.def) or is_64bitint(right.resulttype.def)) then
  138. CGMessage(type_w_mixed_signed_unsigned);
  139. if is_signed(rd) or is_signed(ld) then
  140. begin
  141. if (torddef(ld).typ<>s64bit) then
  142. inserttypeconv(left,cs64bittype);
  143. if (torddef(rd).typ<>s64bit) then
  144. inserttypeconv(right,cs64bittype);
  145. end
  146. else
  147. begin
  148. if (torddef(ld).typ<>u64bit) then
  149. inserttypeconv(left,cu64bittype);
  150. if (torddef(rd).typ<>u64bit) then
  151. inserttypeconv(right,cu64bittype);
  152. end;
  153. resulttype:=left.resulttype;
  154. end
  155. else
  156. begin
  157. if not(right.resulttype.def.deftype=orddef) or
  158. not(torddef(right.resulttype.def).typ in [s32bit,u32bit]) then
  159. inserttypeconv(right,s32bittype);
  160. if not(left.resulttype.def.deftype=orddef) or
  161. not(torddef(left.resulttype.def).typ in [s32bit,u32bit]) then
  162. inserttypeconv(left,s32bittype);
  163. { the resulttype.def depends on the right side, because the left becomes }
  164. { always 64 bit }
  165. resulttype:=right.resulttype;
  166. end;
  167. end;
  168. function tmoddivnode.first_moddiv64bitint: tnode;
  169. var
  170. procname: string[31];
  171. begin
  172. result := nil;
  173. { otherwise create a call to a helper }
  174. if nodetype = divn then
  175. procname := 'fpc_div_'
  176. else
  177. procname := 'fpc_mod_';
  178. if is_signed(resulttype.def) then
  179. procname := procname + 'int64'
  180. else
  181. procname := procname + 'qword';
  182. result := ccallnode.createintern(procname,ccallparanode.create(left,
  183. ccallparanode.create(right,nil)));
  184. left := nil;
  185. right := nil;
  186. firstpass(result);
  187. end;
  188. function tmoddivnode.firstoptimize: tnode;
  189. var
  190. power{,shiftval} : longint;
  191. newtype: tnodetype;
  192. begin
  193. result := nil;
  194. { divide/mod a number by a constant which is a power of 2? }
  195. if (cs_optimize in aktglobalswitches) and
  196. (right.nodetype = ordconstn) and
  197. { ((nodetype = divn) or
  198. not is_signed(resulttype.def)) and}
  199. (not is_signed(resulttype.def)) and
  200. ispowerof2(tordconstnode(right).value,power) then
  201. begin
  202. if nodetype = divn then
  203. begin
  204. (*
  205. if is_signed(resulttype.def) then
  206. begin
  207. if is_64bitint(left.resulttype.def) then
  208. if not (cs_littlesize in aktglobalswitches) then
  209. shiftval := 63
  210. else
  211. { the shift code is a lot bigger than the call to }
  212. { the divide helper }
  213. exit
  214. else
  215. shiftval := 31;
  216. { we reuse left twice, so create once a copy of it }
  217. { !!! if left is a call is -> call gets executed twice }
  218. left := caddnode.create(addn,left,
  219. caddnode.create(andn,
  220. cshlshrnode.create(sarn,left.getcopy,
  221. cordconstnode.create(shiftval,s32bittype)),
  222. cordconstnode.create(tordconstnode(right).value-1,
  223. right.resulttype)));
  224. newtype := sarn;
  225. end
  226. else
  227. *)
  228. newtype := shrn;
  229. tordconstnode(right).value := power;
  230. result := cshlshrnode.create(newtype,left,right)
  231. end
  232. else
  233. begin
  234. dec(tordconstnode(right).value);
  235. result := caddnode.create(andn,left,right);
  236. end;
  237. { left and right are reused }
  238. left := nil;
  239. right := nil;
  240. firstpass(result);
  241. exit;
  242. end;
  243. end;
  244. function tmoddivnode.pass_1 : tnode;
  245. begin
  246. result:=nil;
  247. firstpass(left);
  248. firstpass(right);
  249. if codegenerror then
  250. exit;
  251. result := firstoptimize;
  252. if assigned(result) then
  253. exit;
  254. { 64bit }
  255. if (left.resulttype.def.deftype=orddef) and (right.resulttype.def.deftype=orddef) and
  256. (is_64bitint(left.resulttype.def) or is_64bitint(right.resulttype.def)) then
  257. begin
  258. result := first_moddiv64bitint;
  259. if assigned(result) then
  260. exit;
  261. location.loc:=LOC_REGISTER;
  262. calcregisters(self,2,0,0);
  263. end
  264. else
  265. begin
  266. left_right_max;
  267. if left.registers32<=right.registers32 then
  268. inc(registers32);
  269. end;
  270. location.loc:=LOC_REGISTER;
  271. end;
  272. {****************************************************************************
  273. TSHLSHRNODE
  274. ****************************************************************************}
  275. function tshlshrnode.det_resulttype:tnode;
  276. var
  277. t : tnode;
  278. begin
  279. result:=nil;
  280. resulttypepass(left);
  281. resulttypepass(right);
  282. set_varstate(right,true);
  283. set_varstate(left,true);
  284. if codegenerror then
  285. exit;
  286. { constant folding }
  287. if is_constintnode(left) and is_constintnode(right) then
  288. begin
  289. case nodetype of
  290. shrn:
  291. t:=genintconstnode(tordconstnode(left).value shr tordconstnode(right).value);
  292. shln:
  293. t:=genintconstnode(tordconstnode(left).value shl tordconstnode(right).value);
  294. end;
  295. result:=t;
  296. exit;
  297. end;
  298. { allow operator overloading }
  299. t:=self;
  300. if isbinaryoverloaded(t) then
  301. begin
  302. result:=t;
  303. exit;
  304. end;
  305. { 64 bit ints have their own shift handling }
  306. if not(is_64bitint(left.resulttype.def)) then
  307. begin
  308. if torddef(left.resulttype.def).typ <> u32bit then
  309. inserttypeconv(left,s32bittype);
  310. end;
  311. inserttypeconv(right,s32bittype);
  312. resulttype:=left.resulttype;
  313. end;
  314. function tshlshrnode.pass_1 : tnode;
  315. var
  316. regs : longint;
  317. begin
  318. result:=nil;
  319. firstpass(left);
  320. firstpass(right);
  321. if codegenerror then
  322. exit;
  323. { 64 bit ints have their own shift handling }
  324. if not(is_64bitint(left.resulttype.def)) then
  325. regs:=1
  326. else
  327. regs:=2;
  328. if (right.nodetype<>ordconstn) then
  329. inc(regs);
  330. location.loc:=LOC_REGISTER;
  331. calcregisters(self,regs,0,0);
  332. end;
  333. {****************************************************************************
  334. TUNARYMINUSNODE
  335. ****************************************************************************}
  336. constructor tunaryminusnode.create(expr : tnode);
  337. begin
  338. inherited create(unaryminusn,expr);
  339. end;
  340. function tunaryminusnode.det_resulttype : tnode;
  341. var
  342. t : tnode;
  343. minusdef : pprocdeflist;
  344. begin
  345. result:=nil;
  346. resulttypepass(left);
  347. set_varstate(left,true);
  348. if codegenerror then
  349. exit;
  350. { constant folding }
  351. if is_constintnode(left) then
  352. begin
  353. tordconstnode(left).value:=-tordconstnode(left).value;
  354. result:=left;
  355. left:=nil;
  356. exit;
  357. end;
  358. if is_constrealnode(left) then
  359. begin
  360. trealconstnode(left).value_real:=-trealconstnode(left).value_real;
  361. result:=left;
  362. left:=nil;
  363. exit;
  364. end;
  365. resulttype:=left.resulttype;
  366. if (left.resulttype.def.deftype=floatdef) then
  367. begin
  368. end
  369. {$ifdef SUPPORT_MMX}
  370. else if (cs_mmx in aktlocalswitches) and
  371. is_mmx_able_array(left.resulttype.def) then
  372. begin
  373. { if saturation is on, left.resulttype.def isn't
  374. "mmx able" (FK)
  375. if (cs_mmx_saturation in aktlocalswitches^) and
  376. (torddef(tarraydef(resulttype.def).definition).typ in
  377. [s32bit,u32bit]) then
  378. CGMessage(type_e_mismatch);
  379. }
  380. end
  381. {$endif SUPPORT_MMX}
  382. else if is_64bitint(left.resulttype.def) then
  383. begin
  384. end
  385. else if (left.resulttype.def.deftype=orddef) then
  386. begin
  387. inserttypeconv(left,s32bittype);
  388. resulttype:=left.resulttype;
  389. end
  390. else
  391. begin
  392. if assigned(overloaded_operators[_minus]) then
  393. minusdef:=overloaded_operators[_minus].defs
  394. else
  395. minusdef:=nil;
  396. while assigned(minusdef) do
  397. begin
  398. if is_equal(tparaitem(minusdef^.def.para.first).paratype.def,left.resulttype.def) and
  399. (tparaitem(minusdef^.def.para.first).next=nil) then
  400. begin
  401. t:=ccallnode.create(ccallparanode.create(left,nil),
  402. overloaded_operators[_minus],nil,nil);
  403. left:=nil;
  404. result:=t;
  405. exit;
  406. end;
  407. minusdef:=minusdef^.next;
  408. end;
  409. CGMessage(type_e_mismatch);
  410. end;
  411. end;
  412. { generic code }
  413. { overridden by: }
  414. { i386 }
  415. function tunaryminusnode.pass_1 : tnode;
  416. begin
  417. result:=nil;
  418. firstpass(left);
  419. if codegenerror then
  420. exit;
  421. registers32:=left.registers32;
  422. registersfpu:=left.registersfpu;
  423. {$ifdef SUPPORT_MMX}
  424. registersmmx:=left.registersmmx;
  425. {$endif SUPPORT_MMX}
  426. if (left.resulttype.def.deftype=floatdef) then
  427. begin
  428. if (left.location.loc<>LOC_REGISTER) and
  429. (registersfpu<1) then
  430. registersfpu:=1;
  431. location.loc:=LOC_REGISTER;
  432. end
  433. {$ifdef SUPPORT_MMX}
  434. else if (cs_mmx in aktlocalswitches) and
  435. is_mmx_able_array(left.resulttype.def) then
  436. begin
  437. if (left.location.loc<>LOC_MMXREGISTER) and
  438. (registersmmx<1) then
  439. registersmmx:=1;
  440. end
  441. {$endif SUPPORT_MMX}
  442. else if is_64bitint(left.resulttype.def) then
  443. begin
  444. if (left.location.loc<>LOC_REGISTER) and
  445. (registers32<2) then
  446. registers32:=2;
  447. location.loc:=LOC_REGISTER;
  448. end
  449. else if (left.resulttype.def.deftype=orddef) then
  450. begin
  451. if (left.location.loc<>LOC_REGISTER) and
  452. (registers32<1) then
  453. registers32:=1;
  454. location.loc:=LOC_REGISTER;
  455. end;
  456. end;
  457. {****************************************************************************
  458. TNOTNODE
  459. ****************************************************************************}
  460. const boolean_reverse:array[ltn..unequaln] of Tnodetype=
  461. (gten,gtn,lten,ltn,unequaln,equaln);
  462. constructor tnotnode.create(expr : tnode);
  463. begin
  464. inherited create(notn,expr);
  465. end;
  466. function tnotnode.det_resulttype : tnode;
  467. var
  468. t : tnode;
  469. notdef : pprocdeflist;
  470. v : tconstexprint;
  471. begin
  472. result:=nil;
  473. resulttypepass(left);
  474. set_varstate(left,true);
  475. if codegenerror then
  476. exit;
  477. resulttype:=left.resulttype;
  478. {Try optmimizing ourself away.}
  479. if left.nodetype=notn then
  480. begin
  481. {Double not. Remove both.}
  482. t:=Tnotnode(left).left;
  483. Tnotnode(left).left:=nil;
  484. left:=t;
  485. result:=t;
  486. exit;
  487. end;
  488. if left.nodetype in [ltn,lten,equaln,unequaln,gtn,gten] then
  489. begin
  490. {Not of boolean expression. Turn around the operator and remove
  491. the not.}
  492. result:=left;
  493. left.nodetype:=boolean_reverse[left.nodetype];
  494. left:=nil;
  495. exit;
  496. end;
  497. { constant folding }
  498. if (left.nodetype=ordconstn) then
  499. begin
  500. v:=tordconstnode(left).value;
  501. case torddef(left.resulttype.def).typ of
  502. bool8bit,
  503. bool16bit,
  504. bool32bit :
  505. begin
  506. { here we do a boolean(byte(..)) type cast because }
  507. { boolean(<int64>) is buggy in 1.00 }
  508. v:=byte(not(boolean(byte(v))));
  509. end;
  510. uchar,
  511. u8bit :
  512. v:=byte(not byte(v));
  513. s8bit :
  514. v:=shortint(not shortint(v));
  515. uwidechar,
  516. u16bit :
  517. v:=word(not word(v));
  518. s16bit :
  519. v:=smallint(not smallint(v));
  520. u32bit :
  521. v:=cardinal(not cardinal(v));
  522. s32bit :
  523. v:=longint(not longint(v));
  524. u64bit :
  525. v:=int64(not int64(v)); { maybe qword is required }
  526. s64bit :
  527. v:=int64(not int64(v));
  528. else
  529. CGMessage(type_e_mismatch);
  530. end;
  531. t:=cordconstnode.create(v,left.resulttype);
  532. result:=t;
  533. exit;
  534. end;
  535. if is_boolean(resulttype.def) then
  536. begin
  537. end
  538. else
  539. {$ifdef SUPPORT_MMX}
  540. if (cs_mmx in aktlocalswitches) and
  541. is_mmx_able_array(left.resulttype.def) then
  542. begin
  543. end
  544. else
  545. {$endif SUPPORT_MMX}
  546. if is_64bitint(left.resulttype.def) then
  547. begin
  548. end
  549. else if is_integer(left.resulttype.def) then
  550. begin
  551. end
  552. else
  553. begin
  554. if assigned(overloaded_operators[_op_not]) then
  555. notdef:=overloaded_operators[_op_not].defs
  556. else
  557. notdef:=nil;
  558. while assigned(notdef) do
  559. begin
  560. if is_equal(tparaitem(notdef^.def.para.first).paratype.def,left.resulttype.def) and
  561. (tparaitem(notdef^.def.para.first).next=nil) then
  562. begin
  563. t:=ccallnode.create(ccallparanode.create(left,nil),
  564. overloaded_operators[_op_not],nil,nil);
  565. left:=nil;
  566. result:=t;
  567. exit;
  568. end;
  569. notdef:=notdef^.next;
  570. end;
  571. CGMessage(type_e_mismatch);
  572. end;
  573. end;
  574. function tnotnode.pass_1 : tnode;
  575. begin
  576. result:=nil;
  577. firstpass(left);
  578. if codegenerror then
  579. exit;
  580. location.loc:=left.location.loc;
  581. registers32:=left.registers32;
  582. {$ifdef SUPPORT_MMX}
  583. registersmmx:=left.registersmmx;
  584. {$endif SUPPORT_MMX}
  585. if is_boolean(resulttype.def) then
  586. begin
  587. if (location.loc in [LOC_REFERENCE,LOC_CREFERENCE,LOC_CREGISTER]) then
  588. begin
  589. location.loc:=LOC_REGISTER;
  590. if (registers32<1) then
  591. registers32:=1;
  592. end;
  593. { before loading it into flags we need to load it into
  594. a register thus 1 register is need PM }
  595. {$ifdef i386}
  596. if left.location.loc<>LOC_JUMP then
  597. location.loc:=LOC_FLAGS;
  598. {$endif def i386}
  599. end
  600. else
  601. {$ifdef SUPPORT_MMX}
  602. if (cs_mmx in aktlocalswitches) and
  603. is_mmx_able_array(left.resulttype.def) then
  604. begin
  605. if (left.location.loc<>LOC_MMXREGISTER) and
  606. (registersmmx<1) then
  607. registersmmx:=1;
  608. end
  609. else
  610. {$endif SUPPORT_MMX}
  611. if is_64bitint(left.resulttype.def) then
  612. begin
  613. if (location.loc in [LOC_REFERENCE,LOC_CREFERENCE,LOC_CREGISTER]) then
  614. begin
  615. location.loc:=LOC_REGISTER;
  616. if (registers32<2) then
  617. registers32:=2;
  618. end;
  619. end
  620. else if is_integer(left.resulttype.def) then
  621. begin
  622. if (left.location.loc<>LOC_REGISTER) and
  623. (registers32<1) then
  624. registers32:=1;
  625. location.loc:=LOC_REGISTER;
  626. end
  627. end;
  628. {$ifdef state_tracking}
  629. function Tnotnode.track_state_pass(exec_known:boolean):boolean;
  630. begin
  631. track_state_pass:=true;
  632. if left.track_state_pass(exec_known) then
  633. begin
  634. left.resulttype.def:=nil;
  635. do_resulttypepass(left);
  636. end;
  637. end;
  638. {$endif}
  639. begin
  640. cmoddivnode:=tmoddivnode;
  641. cshlshrnode:=tshlshrnode;
  642. cunaryminusnode:=tunaryminusnode;
  643. cnotnode:=tnotnode;
  644. end.
  645. {
  646. $Log$
  647. Revision 1.36 2002-07-20 11:57:54 florian
  648. * types.pas renamed to defbase.pas because D6 contains a types
  649. unit so this would conflicts if D6 programms are compiled
  650. + Willamette/SSE2 instructions to assembler added
  651. Revision 1.35 2002/07/19 11:41:36 daniel
  652. * State tracker work
  653. * The whilen and repeatn are now completely unified into whilerepeatn. This
  654. allows the state tracker to change while nodes automatically into
  655. repeat nodes.
  656. * Resulttypepass improvements to the notn. 'not not a' is optimized away and
  657. 'not(a>b)' is optimized into 'a<=b'.
  658. * Resulttypepass improvements to the whilerepeatn. 'while not a' is optimized
  659. by removing the notn and later switchting the true and falselabels. The
  660. same is done with 'repeat until not a'.
  661. Revision 1.34 2002/05/18 13:34:10 peter
  662. * readded missing revisions
  663. Revision 1.33 2002/05/16 19:46:39 carl
  664. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  665. + try to fix temp allocation (still in ifdef)
  666. + generic constructor calls
  667. + start of tassembler / tmodulebase class cleanup
  668. Revision 1.31 2002/04/07 13:26:10 carl
  669. + change unit use
  670. Revision 1.30 2002/04/02 17:11:29 peter
  671. * tlocation,treference update
  672. * LOC_CONSTANT added for better constant handling
  673. * secondadd splitted in multiple routines
  674. * location_force_reg added for loading a location to a register
  675. of a specified size
  676. * secondassignment parses now first the right and then the left node
  677. (this is compatible with Kylix). This saves a lot of push/pop especially
  678. with string operations
  679. * adapted some routines to use the new cg methods
  680. Revision 1.29 2002/03/04 19:10:11 peter
  681. * removed compiler warnings
  682. Revision 1.28 2002/02/11 11:45:51 michael
  683. * Compilation without mmx support fixed from Peter
  684. }