nmat.pas 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820
  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. result:=Tnotnode(left).left;
  517. Tnotnode(left).left:=nil;
  518. exit;
  519. end;
  520. if (left.nodetype in [ltn,lten,equaln,unequaln,gtn,gten]) then
  521. begin
  522. { Not of boolean expression. Turn around the operator and remove
  523. the not. This is not allowed for sets with the gten/lten,
  524. because there is no ltn/gtn support }
  525. if (taddnode(left).left.resulttype.def.deftype<>setdef) or
  526. (left.nodetype in [equaln,unequaln]) then
  527. begin
  528. result:=left;
  529. left.nodetype:=boolean_reverse[left.nodetype];
  530. left:=nil;
  531. exit;
  532. end;
  533. end;
  534. { constant folding }
  535. if (left.nodetype=ordconstn) then
  536. begin
  537. v:=tordconstnode(left).value;
  538. case torddef(left.resulttype.def).typ of
  539. bool8bit,
  540. bool16bit,
  541. bool32bit :
  542. begin
  543. { here we do a boolean(byte(..)) type cast because }
  544. { boolean(<int64>) is buggy in 1.00 }
  545. v:=byte(not(boolean(byte(v))));
  546. end;
  547. uchar,
  548. u8bit :
  549. v:=byte(not byte(v));
  550. s8bit :
  551. v:=shortint(not shortint(v));
  552. uwidechar,
  553. u16bit :
  554. v:=word(not word(v));
  555. s16bit :
  556. v:=smallint(not smallint(v));
  557. u32bit :
  558. v:=cardinal(not cardinal(v));
  559. s32bit :
  560. v:=longint(not longint(v));
  561. u64bit :
  562. v:=int64(not int64(v)); { maybe qword is required }
  563. s64bit :
  564. v:=int64(not int64(v));
  565. else
  566. CGMessage(type_e_mismatch);
  567. end;
  568. t:=cordconstnode.create(v,left.resulttype);
  569. result:=t;
  570. exit;
  571. end;
  572. if is_boolean(resulttype.def) then
  573. begin
  574. end
  575. else
  576. {$ifdef SUPPORT_MMX}
  577. if (cs_mmx in aktlocalswitches) and
  578. is_mmx_able_array(left.resulttype.def) then
  579. begin
  580. end
  581. else
  582. {$endif SUPPORT_MMX}
  583. if is_64bitint(left.resulttype.def) then
  584. begin
  585. end
  586. else if is_integer(left.resulttype.def) then
  587. begin
  588. end
  589. else
  590. begin
  591. if assigned(overloaded_operators[_op_not]) then
  592. notdef:=overloaded_operators[_op_not].defs
  593. else
  594. notdef:=nil;
  595. while assigned(notdef) do
  596. begin
  597. if is_equal(tparaitem(notdef^.def.para.first).paratype.def,left.resulttype.def) and
  598. (tparaitem(notdef^.def.para.first).next=nil) then
  599. begin
  600. t:=ccallnode.create(ccallparanode.create(left,nil),
  601. overloaded_operators[_op_not],nil,nil);
  602. left:=nil;
  603. result:=t;
  604. exit;
  605. end;
  606. notdef:=notdef^.next;
  607. end;
  608. CGMessage(type_e_mismatch);
  609. end;
  610. end;
  611. function tnotnode.pass_1 : tnode;
  612. begin
  613. result:=nil;
  614. firstpass(left);
  615. if codegenerror then
  616. exit;
  617. location.loc:=left.location.loc;
  618. registers32:=left.registers32;
  619. {$ifdef SUPPORT_MMX}
  620. registersmmx:=left.registersmmx;
  621. {$endif SUPPORT_MMX}
  622. if is_boolean(resulttype.def) then
  623. begin
  624. if (location.loc in [LOC_REFERENCE,LOC_CREFERENCE,LOC_CREGISTER]) then
  625. begin
  626. location.loc:=LOC_REGISTER;
  627. if (registers32<1) then
  628. registers32:=1;
  629. end;
  630. { before loading it into flags we need to load it into
  631. a register thus 1 register is need PM }
  632. {$ifdef i386}
  633. if left.location.loc<>LOC_JUMP then
  634. location.loc:=LOC_FLAGS;
  635. {$endif def i386}
  636. end
  637. else
  638. {$ifdef SUPPORT_MMX}
  639. if (cs_mmx in aktlocalswitches) and
  640. is_mmx_able_array(left.resulttype.def) then
  641. begin
  642. if (left.location.loc<>LOC_MMXREGISTER) and
  643. (registersmmx<1) then
  644. registersmmx:=1;
  645. end
  646. else
  647. {$endif SUPPORT_MMX}
  648. if is_64bitint(left.resulttype.def) then
  649. begin
  650. if (location.loc in [LOC_REFERENCE,LOC_CREFERENCE,LOC_CREGISTER]) then
  651. begin
  652. location.loc:=LOC_REGISTER;
  653. if (registers32<2) then
  654. registers32:=2;
  655. end;
  656. end
  657. else if is_integer(left.resulttype.def) then
  658. begin
  659. if (left.location.loc<>LOC_REGISTER) and
  660. (registers32<1) then
  661. registers32:=1;
  662. location.loc:=LOC_REGISTER;
  663. end
  664. end;
  665. {$ifdef state_tracking}
  666. function Tnotnode.track_state_pass(exec_known:boolean):boolean;
  667. begin
  668. track_state_pass:=true;
  669. if left.track_state_pass(exec_known) then
  670. begin
  671. left.resulttype.def:=nil;
  672. do_resulttypepass(left);
  673. end;
  674. end;
  675. {$endif}
  676. begin
  677. cmoddivnode:=tmoddivnode;
  678. cshlshrnode:=tshlshrnode;
  679. cunaryminusnode:=tunaryminusnode;
  680. cnotnode:=tnotnode;
  681. end.
  682. {
  683. $Log$
  684. Revision 1.40 2002-08-25 11:32:33 peter
  685. * don't optimize not([lten,gten]) for setdefs
  686. Revision 1.39 2002/08/25 09:10:58 peter
  687. * fixed not(not()) removal
  688. Revision 1.38 2002/08/15 15:09:42 carl
  689. + fpu emulation helpers (ppu checking also)
  690. Revision 1.37 2002/08/14 19:26:55 carl
  691. + generic int_to_real type conversion
  692. + generic unaryminus node
  693. Revision 1.36 2002/07/20 11:57:54 florian
  694. * types.pas renamed to defbase.pas because D6 contains a types
  695. unit so this would conflicts if D6 programms are compiled
  696. + Willamette/SSE2 instructions to assembler added
  697. Revision 1.35 2002/07/19 11:41:36 daniel
  698. * State tracker work
  699. * The whilen and repeatn are now completely unified into whilerepeatn. This
  700. allows the state tracker to change while nodes automatically into
  701. repeat nodes.
  702. * Resulttypepass improvements to the notn. 'not not a' is optimized away and
  703. 'not(a>b)' is optimized into 'a<=b'.
  704. * Resulttypepass improvements to the whilerepeatn. 'while not a' is optimized
  705. by removing the notn and later switchting the true and falselabels. The
  706. same is done with 'repeat until not a'.
  707. Revision 1.34 2002/05/18 13:34:10 peter
  708. * readded missing revisions
  709. Revision 1.33 2002/05/16 19:46:39 carl
  710. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  711. + try to fix temp allocation (still in ifdef)
  712. + generic constructor calls
  713. + start of tassembler / tmodulebase class cleanup
  714. Revision 1.31 2002/04/07 13:26:10 carl
  715. + change unit use
  716. Revision 1.30 2002/04/02 17:11:29 peter
  717. * tlocation,treference update
  718. * LOC_CONSTANT added for better constant handling
  719. * secondadd splitted in multiple routines
  720. * location_force_reg added for loading a location to a register
  721. of a specified size
  722. * secondassignment parses now first the right and then the left node
  723. (this is compatible with Kylix). This saves a lot of push/pop especially
  724. with string operations
  725. * adapted some routines to use the new cg methods
  726. Revision 1.29 2002/03/04 19:10:11 peter
  727. * removed compiler warnings
  728. Revision 1.28 2002/02/11 11:45:51 michael
  729. * Compilation without mmx support fixed from Peter
  730. }