nmat.pas 26 KB

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