nmat.pas 26 KB

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