nmat.pas 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810
  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 : pprocdeflist;
  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. if assigned(overloaded_operators[_minus]) then
  427. minusdef:=overloaded_operators[_minus].defs
  428. else
  429. minusdef:=nil;
  430. while assigned(minusdef) do
  431. begin
  432. if is_equal(tparaitem(minusdef^.def.para.first).paratype.def,left.resulttype.def) and
  433. (tparaitem(minusdef^.def.para.first).next=nil) then
  434. begin
  435. t:=ccallnode.create(ccallparanode.create(left,nil),
  436. overloaded_operators[_minus],nil,nil);
  437. left:=nil;
  438. result:=t;
  439. exit;
  440. end;
  441. minusdef:=minusdef^.next;
  442. end;
  443. CGMessage(type_e_mismatch);
  444. end;
  445. end;
  446. { generic code }
  447. { overridden by: }
  448. { i386 }
  449. function tunaryminusnode.pass_1 : tnode;
  450. begin
  451. result:=nil;
  452. firstpass(left);
  453. if codegenerror then
  454. exit;
  455. registers32:=left.registers32;
  456. registersfpu:=left.registersfpu;
  457. {$ifdef SUPPORT_MMX}
  458. registersmmx:=left.registersmmx;
  459. {$endif SUPPORT_MMX}
  460. if (left.resulttype.def.deftype=floatdef) then
  461. begin
  462. if (left.location.loc<>LOC_REGISTER) and
  463. (registersfpu<1) then
  464. registersfpu:=1;
  465. location.loc:=LOC_FPUREGISTER;
  466. end
  467. {$ifdef SUPPORT_MMX}
  468. else if (cs_mmx in aktlocalswitches) and
  469. is_mmx_able_array(left.resulttype.def) then
  470. begin
  471. if (left.location.loc<>LOC_MMXREGISTER) and
  472. (registersmmx<1) then
  473. registersmmx:=1;
  474. end
  475. {$endif SUPPORT_MMX}
  476. else if is_64bitint(left.resulttype.def) then
  477. begin
  478. if (left.location.loc<>LOC_REGISTER) and
  479. (registers32<2) then
  480. registers32:=2;
  481. location.loc:=LOC_REGISTER;
  482. end
  483. else if (left.resulttype.def.deftype=orddef) then
  484. begin
  485. if (left.location.loc<>LOC_REGISTER) and
  486. (registers32<1) then
  487. registers32:=1;
  488. location.loc:=LOC_REGISTER;
  489. end;
  490. end;
  491. {****************************************************************************
  492. TNOTNODE
  493. ****************************************************************************}
  494. const boolean_reverse:array[ltn..unequaln] of Tnodetype=
  495. (gten,gtn,lten,ltn,unequaln,equaln);
  496. constructor tnotnode.create(expr : tnode);
  497. begin
  498. inherited create(notn,expr);
  499. end;
  500. function tnotnode.det_resulttype : tnode;
  501. var
  502. t : tnode;
  503. notdef : pprocdeflist;
  504. v : tconstexprint;
  505. begin
  506. result:=nil;
  507. resulttypepass(left);
  508. set_varstate(left,true);
  509. if codegenerror then
  510. exit;
  511. resulttype:=left.resulttype;
  512. {Try optmimizing ourself away.}
  513. if left.nodetype=notn then
  514. begin
  515. {Double not. Remove both.}
  516. t:=Tnotnode(left).left;
  517. Tnotnode(left).left:=nil;
  518. left:=t;
  519. result:=t;
  520. exit;
  521. end;
  522. if left.nodetype in [ltn,lten,equaln,unequaln,gtn,gten] then
  523. begin
  524. {Not of boolean expression. Turn around the operator and remove
  525. the not.}
  526. result:=left;
  527. left.nodetype:=boolean_reverse[left.nodetype];
  528. left:=nil;
  529. exit;
  530. end;
  531. { constant folding }
  532. if (left.nodetype=ordconstn) then
  533. begin
  534. v:=tordconstnode(left).value;
  535. case torddef(left.resulttype.def).typ of
  536. bool8bit,
  537. bool16bit,
  538. bool32bit :
  539. begin
  540. { here we do a boolean(byte(..)) type cast because }
  541. { boolean(<int64>) is buggy in 1.00 }
  542. v:=byte(not(boolean(byte(v))));
  543. end;
  544. uchar,
  545. u8bit :
  546. v:=byte(not byte(v));
  547. s8bit :
  548. v:=shortint(not shortint(v));
  549. uwidechar,
  550. u16bit :
  551. v:=word(not word(v));
  552. s16bit :
  553. v:=smallint(not smallint(v));
  554. u32bit :
  555. v:=cardinal(not cardinal(v));
  556. s32bit :
  557. v:=longint(not longint(v));
  558. u64bit :
  559. v:=int64(not int64(v)); { maybe qword is required }
  560. s64bit :
  561. v:=int64(not int64(v));
  562. else
  563. CGMessage(type_e_mismatch);
  564. end;
  565. t:=cordconstnode.create(v,left.resulttype);
  566. result:=t;
  567. exit;
  568. end;
  569. if is_boolean(resulttype.def) then
  570. begin
  571. end
  572. else
  573. {$ifdef SUPPORT_MMX}
  574. if (cs_mmx in aktlocalswitches) and
  575. is_mmx_able_array(left.resulttype.def) then
  576. begin
  577. end
  578. else
  579. {$endif SUPPORT_MMX}
  580. if is_64bitint(left.resulttype.def) then
  581. begin
  582. end
  583. else if is_integer(left.resulttype.def) then
  584. begin
  585. end
  586. else
  587. begin
  588. if assigned(overloaded_operators[_op_not]) then
  589. notdef:=overloaded_operators[_op_not].defs
  590. else
  591. notdef:=nil;
  592. while assigned(notdef) do
  593. begin
  594. if is_equal(tparaitem(notdef^.def.para.first).paratype.def,left.resulttype.def) and
  595. (tparaitem(notdef^.def.para.first).next=nil) then
  596. begin
  597. t:=ccallnode.create(ccallparanode.create(left,nil),
  598. overloaded_operators[_op_not],nil,nil);
  599. left:=nil;
  600. result:=t;
  601. exit;
  602. end;
  603. notdef:=notdef^.next;
  604. end;
  605. CGMessage(type_e_mismatch);
  606. end;
  607. end;
  608. function tnotnode.pass_1 : tnode;
  609. begin
  610. result:=nil;
  611. firstpass(left);
  612. if codegenerror then
  613. exit;
  614. location.loc:=left.location.loc;
  615. registers32:=left.registers32;
  616. {$ifdef SUPPORT_MMX}
  617. registersmmx:=left.registersmmx;
  618. {$endif SUPPORT_MMX}
  619. if is_boolean(resulttype.def) then
  620. begin
  621. if (location.loc in [LOC_REFERENCE,LOC_CREFERENCE,LOC_CREGISTER]) then
  622. begin
  623. location.loc:=LOC_REGISTER;
  624. if (registers32<1) then
  625. registers32:=1;
  626. end;
  627. { before loading it into flags we need to load it into
  628. a register thus 1 register is need PM }
  629. {$ifdef i386}
  630. if left.location.loc<>LOC_JUMP then
  631. location.loc:=LOC_FLAGS;
  632. {$endif def i386}
  633. end
  634. else
  635. {$ifdef SUPPORT_MMX}
  636. if (cs_mmx in aktlocalswitches) and
  637. is_mmx_able_array(left.resulttype.def) then
  638. begin
  639. if (left.location.loc<>LOC_MMXREGISTER) and
  640. (registersmmx<1) then
  641. registersmmx:=1;
  642. end
  643. else
  644. {$endif SUPPORT_MMX}
  645. if is_64bitint(left.resulttype.def) then
  646. begin
  647. if (location.loc in [LOC_REFERENCE,LOC_CREFERENCE,LOC_CREGISTER]) then
  648. begin
  649. location.loc:=LOC_REGISTER;
  650. if (registers32<2) then
  651. registers32:=2;
  652. end;
  653. end
  654. else if is_integer(left.resulttype.def) then
  655. begin
  656. if (left.location.loc<>LOC_REGISTER) and
  657. (registers32<1) then
  658. registers32:=1;
  659. location.loc:=LOC_REGISTER;
  660. end
  661. end;
  662. {$ifdef state_tracking}
  663. function Tnotnode.track_state_pass(exec_known:boolean):boolean;
  664. begin
  665. track_state_pass:=true;
  666. if left.track_state_pass(exec_known) then
  667. begin
  668. left.resulttype.def:=nil;
  669. do_resulttypepass(left);
  670. end;
  671. end;
  672. {$endif}
  673. begin
  674. cmoddivnode:=tmoddivnode;
  675. cshlshrnode:=tshlshrnode;
  676. cunaryminusnode:=tunaryminusnode;
  677. cnotnode:=tnotnode;
  678. end.
  679. {
  680. $Log$
  681. Revision 1.38 2002-08-15 15:09:42 carl
  682. + fpu emulation helpers (ppu checking also)
  683. Revision 1.37 2002/08/14 19:26:55 carl
  684. + generic int_to_real type conversion
  685. + generic unaryminus node
  686. Revision 1.36 2002/07/20 11:57:54 florian
  687. * types.pas renamed to defbase.pas because D6 contains a types
  688. unit so this would conflicts if D6 programms are compiled
  689. + Willamette/SSE2 instructions to assembler added
  690. Revision 1.35 2002/07/19 11:41:36 daniel
  691. * State tracker work
  692. * The whilen and repeatn are now completely unified into whilerepeatn. This
  693. allows the state tracker to change while nodes automatically into
  694. repeat nodes.
  695. * Resulttypepass improvements to the notn. 'not not a' is optimized away and
  696. 'not(a>b)' is optimized into 'a<=b'.
  697. * Resulttypepass improvements to the whilerepeatn. 'while not a' is optimized
  698. by removing the notn and later switchting the true and falselabels. The
  699. same is done with 'repeat until not a'.
  700. Revision 1.34 2002/05/18 13:34:10 peter
  701. * readded missing revisions
  702. Revision 1.33 2002/05/16 19:46:39 carl
  703. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  704. + try to fix temp allocation (still in ifdef)
  705. + generic constructor calls
  706. + start of tassembler / tmodulebase class cleanup
  707. Revision 1.31 2002/04/07 13:26:10 carl
  708. + change unit use
  709. Revision 1.30 2002/04/02 17:11:29 peter
  710. * tlocation,treference update
  711. * LOC_CONSTANT added for better constant handling
  712. * secondadd splitted in multiple routines
  713. * location_force_reg added for loading a location to a register
  714. of a specified size
  715. * secondassignment parses now first the right and then the left node
  716. (this is compatible with Kylix). This saves a lot of push/pop especially
  717. with string operations
  718. * adapted some routines to use the new cg methods
  719. Revision 1.29 2002/03/04 19:10:11 peter
  720. * removed compiler warnings
  721. Revision 1.28 2002/02/11 11:45:51 michael
  722. * Compilation without mmx support fixed from Peter
  723. }