nmat.pas 30 KB

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