2
0

nmat.pas 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866
  1. {
  2. Copyright (c) 2000-2002 by Florian Klaempfl
  3. Type checking and register allocation for math nodes
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. ****************************************************************************
  16. }
  17. unit nmat;
  18. {$i fpcdefs.inc}
  19. interface
  20. uses
  21. node;
  22. type
  23. tmoddivnode = class(tbinopnode)
  24. function pass_1 : tnode;override;
  25. function det_resulttype:tnode;override;
  26. protected
  27. {$ifndef cpu64bit}
  28. { override the following if you want to implement }
  29. { parts explicitely in the code generator (JM) }
  30. function first_moddiv64bitint: tnode; virtual;
  31. {$endif cpu64bit}
  32. function firstoptimize: tnode; virtual;
  33. function first_moddivint: tnode; virtual;
  34. end;
  35. tmoddivnodeclass = class of tmoddivnode;
  36. tshlshrnode = class(tbinopnode)
  37. function pass_1 : tnode;override;
  38. function det_resulttype:tnode;override;
  39. {$ifndef cpu64bit}
  40. { override the following if you want to implement }
  41. { parts explicitely in the code generator (CEC)
  42. Should return nil, if everything will be handled
  43. in the code generator
  44. }
  45. function first_shlshr64bitint: tnode; virtual;
  46. {$endif cpu64bit}
  47. end;
  48. tshlshrnodeclass = class of tshlshrnode;
  49. tunaryminusnode = class(tunarynode)
  50. constructor create(expr : tnode);virtual;
  51. function pass_1 : tnode;override;
  52. function det_resulttype:tnode;override;
  53. end;
  54. tunaryminusnodeclass = class of tunaryminusnode;
  55. tnotnode = class(tunarynode)
  56. constructor create(expr : tnode);virtual;
  57. function pass_1 : tnode;override;
  58. function det_resulttype:tnode;override;
  59. {$ifdef state_tracking}
  60. function track_state_pass(exec_known:boolean):boolean;override;
  61. {$endif}
  62. end;
  63. tnotnodeclass = class of tnotnode;
  64. var
  65. cmoddivnode : tmoddivnodeclass;
  66. cshlshrnode : tshlshrnodeclass;
  67. cunaryminusnode : tunaryminusnodeclass;
  68. cnotnode : tnotnodeclass;
  69. implementation
  70. uses
  71. systems,
  72. verbose,globals,cutils,
  73. globtype,
  74. symconst,symtype,symdef,defutil,
  75. htypechk,pass_1,
  76. cgbase,
  77. ncon,ncnv,ncal,nadd;
  78. {****************************************************************************
  79. TMODDIVNODE
  80. ****************************************************************************}
  81. function tmoddivnode.det_resulttype:tnode;
  82. var
  83. hp,t : tnode;
  84. rd,ld : torddef;
  85. rv,lv : tconstexprint;
  86. begin
  87. result:=nil;
  88. resulttypepass(left);
  89. resulttypepass(right);
  90. set_varstate(left,vs_read,[vsf_must_be_valid]);
  91. set_varstate(right,vs_read,[vsf_must_be_valid]);
  92. if codegenerror then
  93. exit;
  94. { allow operator overloading }
  95. t:=self;
  96. if isbinaryoverloaded(t) then
  97. begin
  98. result:=t;
  99. exit;
  100. end;
  101. { we need 2 orddefs always }
  102. if (left.resulttype.def.deftype<>orddef) then
  103. inserttypeconv(right,sinttype);
  104. if (right.resulttype.def.deftype<>orddef) then
  105. inserttypeconv(right,sinttype);
  106. if codegenerror then
  107. exit;
  108. rd:=torddef(right.resulttype.def);
  109. ld:=torddef(left.resulttype.def);
  110. { check for division by zero }
  111. if is_constintnode(right) then
  112. begin
  113. rv:=tordconstnode(right).value;
  114. if (rv=0) then
  115. begin
  116. Message(parser_e_division_by_zero);
  117. { recover }
  118. rv:=1;
  119. end;
  120. if (rv = 1) then
  121. begin
  122. case nodetype of
  123. modn:
  124. result := cordconstnode.create(0,left.resulttype,true);
  125. divn:
  126. result := left.getcopy;
  127. end;
  128. exit;
  129. end;
  130. if is_constintnode(left) then
  131. begin
  132. lv:=tordconstnode(left).value;
  133. case nodetype of
  134. modn:
  135. if (torddef(ld).typ <> u64bit) or
  136. (torddef(rd).typ <> u64bit) then
  137. t:=genintconstnode(lv mod rv)
  138. else
  139. t:=genintconstnode(int64(qword(lv) mod qword(rv)));
  140. divn:
  141. if (torddef(ld).typ <> u64bit) or
  142. (torddef(rd).typ <> u64bit) then
  143. t:=genintconstnode(lv div rv)
  144. else
  145. t:=genintconstnode(int64(qword(lv) div qword(rv)));
  146. end;
  147. result:=t;
  148. exit;
  149. end;
  150. end;
  151. { if one operand is a cardinal and the other is a positive constant, convert the }
  152. { constant to a cardinal as well so we don't have to do a 64bit division (JM) }
  153. { Do the same for qwords and positive constants as well, otherwise things like }
  154. { "qword mod 10" are evaluated with int64 as result, which is wrong if the }
  155. { "qword" was > high(int64) (JM) }
  156. if (rd.typ in [u32bit,u64bit]) and
  157. is_constintnode(left) and
  158. (tordconstnode(left).value >= 0) then
  159. begin
  160. inserttypeconv(left,right.resulttype);
  161. ld:=torddef(left.resulttype.def);
  162. end;
  163. if (ld.typ in [u32bit,u64bit]) and
  164. is_constintnode(right) and
  165. (tordconstnode(right).value >= 0) then
  166. begin
  167. inserttypeconv(right,left.resulttype);
  168. rd:=torddef(right.resulttype.def);
  169. end;
  170. { when there is one currency value, everything is done
  171. using currency }
  172. if (ld.typ=scurrency) or
  173. (rd.typ=scurrency) then
  174. begin
  175. if (ld.typ<>scurrency) then
  176. inserttypeconv(left,s64currencytype);
  177. if (rd.typ<>scurrency) then
  178. inserttypeconv(right,s64currencytype);
  179. resulttype:=left.resulttype;
  180. end
  181. else
  182. {$ifndef cpu64bit}
  183. { when there is one 64bit value, everything is done
  184. in 64bit }
  185. if (is_64bitint(left.resulttype.def) or
  186. is_64bitint(right.resulttype.def)) then
  187. begin
  188. if is_signed(rd) or is_signed(ld) then
  189. begin
  190. if (ld.typ<>s64bit) then
  191. inserttypeconv(left,s64inttype);
  192. if (rd.typ<>s64bit) then
  193. inserttypeconv(right,s64inttype);
  194. end
  195. else
  196. begin
  197. if (ld.typ<>u64bit) then
  198. inserttypeconv(left,u64inttype);
  199. if (rd.typ<>u64bit) then
  200. inserttypeconv(right,u64inttype);
  201. end;
  202. resulttype:=left.resulttype;
  203. end
  204. else
  205. { when mixing cardinals and signed numbers, convert everythign to 64bit (JM) }
  206. if ((rd.typ = u32bit) and
  207. is_signed(ld)) or
  208. ((ld.typ = u32bit) and
  209. is_signed(rd)) then
  210. begin
  211. CGMessage(type_w_mixed_signed_unsigned);
  212. if (ld.typ<>s64bit) then
  213. inserttypeconv(left,s64inttype);
  214. if (rd.typ<>s64bit) then
  215. inserttypeconv(right,s64inttype);
  216. resulttype:=left.resulttype;
  217. end
  218. else
  219. {$endif cpu64bit}
  220. begin
  221. { Make everything always default singed int }
  222. if not(rd.typ in [torddef(sinttype.def).typ,torddef(uinttype.def).typ]) then
  223. inserttypeconv(right,sinttype);
  224. if not(ld.typ in [torddef(sinttype.def).typ,torddef(uinttype.def).typ]) then
  225. inserttypeconv(left,sinttype);
  226. resulttype:=right.resulttype;
  227. end;
  228. { when the result is currency we need some extra code for
  229. division. this should not be done when the divn node is
  230. created internally }
  231. if (nodetype=divn) and
  232. not(nf_is_currency in flags) and
  233. is_currency(resulttype.def) then
  234. begin
  235. hp:=caddnode.create(muln,getcopy,cordconstnode.create(10000,s64currencytype,false));
  236. include(hp.flags,nf_is_currency);
  237. result:=hp;
  238. end;
  239. end;
  240. function tmoddivnode.first_moddivint: tnode;
  241. {$ifdef cpuneedsdiv32helper}
  242. var
  243. procname: string[31];
  244. begin
  245. result := nil;
  246. { otherwise create a call to a helper }
  247. if nodetype = divn then
  248. procname := 'fpc_div_'
  249. else
  250. procname := 'fpc_mod_';
  251. { only qword needs the unsigned code, the
  252. signed code is also used for currency }
  253. if is_signed(resulttype.def) then
  254. procname := procname + 'longint'
  255. else
  256. procname := procname + 'dword';
  257. result := ccallnode.createintern(procname,ccallparanode.create(left,
  258. ccallparanode.create(right,nil)));
  259. left := nil;
  260. right := nil;
  261. firstpass(result);
  262. end;
  263. {$else cpuneedsdiv32helper}
  264. begin
  265. result:=nil;
  266. end;
  267. {$endif cpuneedsdiv32helper}
  268. {$ifndef cpu64bit}
  269. function tmoddivnode.first_moddiv64bitint: tnode;
  270. var
  271. procname: string[31];
  272. begin
  273. result := nil;
  274. { when currency is used set the result of the
  275. parameters to s64bit, so they are not converted }
  276. if is_currency(resulttype.def) then
  277. begin
  278. left.resulttype:=s64inttype;
  279. right.resulttype:=s64inttype;
  280. end;
  281. { otherwise create a call to a helper }
  282. if nodetype = divn then
  283. procname := 'fpc_div_'
  284. else
  285. procname := 'fpc_mod_';
  286. { only qword needs the unsigned code, the
  287. signed code is also used for currency }
  288. if is_signed(resulttype.def) then
  289. procname := procname + 'int64'
  290. else
  291. procname := procname + 'qword';
  292. result := ccallnode.createintern(procname,ccallparanode.create(left,
  293. ccallparanode.create(right,nil)));
  294. left := nil;
  295. right := nil;
  296. firstpass(result);
  297. end;
  298. {$endif cpu64bit}
  299. function tmoddivnode.firstoptimize: tnode;
  300. var
  301. power{,shiftval} : longint;
  302. newtype: tnodetype;
  303. begin
  304. result := nil;
  305. { divide/mod a number by a constant which is a power of 2? }
  306. if (cs_optimize in aktglobalswitches) and
  307. (right.nodetype = ordconstn) and
  308. { ((nodetype = divn) or
  309. not is_signed(resulttype.def)) and}
  310. (not is_signed(resulttype.def)) and
  311. ispowerof2(tordconstnode(right).value,power) then
  312. begin
  313. if nodetype = divn then
  314. begin
  315. (*
  316. if is_signed(resulttype.def) then
  317. begin
  318. if is_64bitint(left.resulttype.def) then
  319. if not (cs_littlesize in aktglobalswitches) then
  320. shiftval := 63
  321. else
  322. { the shift code is a lot bigger than the call to }
  323. { the divide helper }
  324. exit
  325. else
  326. shiftval := 31;
  327. { we reuse left twice, so create once a copy of it }
  328. { !!! if left is a call is -> call gets executed twice }
  329. left := caddnode.create(addn,left,
  330. caddnode.create(andn,
  331. cshlshrnode.create(sarn,left.getcopy,
  332. cordconstnode.create(shiftval,sinttype,false)),
  333. cordconstnode.create(tordconstnode(right).value-1,
  334. right.resulttype,false)));
  335. newtype := sarn;
  336. end
  337. else
  338. *)
  339. newtype := shrn;
  340. tordconstnode(right).value := power;
  341. result := cshlshrnode.create(newtype,left,right)
  342. end
  343. else
  344. begin
  345. dec(tordconstnode(right).value);
  346. result := caddnode.create(andn,left,right);
  347. end;
  348. { left and right are reused }
  349. left := nil;
  350. right := nil;
  351. firstpass(result);
  352. exit;
  353. end;
  354. end;
  355. function tmoddivnode.pass_1 : tnode;
  356. begin
  357. result:=nil;
  358. firstpass(left);
  359. firstpass(right);
  360. if codegenerror then
  361. exit;
  362. { Try to optimize mod/div }
  363. result := firstoptimize;
  364. if assigned(result) then
  365. exit;
  366. {$ifndef cpu64bit}
  367. { 64bit }
  368. if (left.resulttype.def.deftype=orddef) and
  369. (right.resulttype.def.deftype=orddef) and
  370. (is_64bitint(left.resulttype.def) or is_64bitint(right.resulttype.def)) then
  371. begin
  372. result := first_moddiv64bitint;
  373. if assigned(result) then
  374. exit;
  375. expectloc:=LOC_REGISTER;
  376. calcregisters(self,2,0,0);
  377. end
  378. else
  379. {$endif cpu64bit}
  380. begin
  381. result := first_moddivint;
  382. if assigned(result) then
  383. exit;
  384. left_right_max;
  385. if left.registersint<=right.registersint then
  386. inc(registersint);
  387. end;
  388. expectloc:=LOC_REGISTER;
  389. end;
  390. {****************************************************************************
  391. TSHLSHRNODE
  392. ****************************************************************************}
  393. function tshlshrnode.det_resulttype:tnode;
  394. var
  395. t : tnode;
  396. begin
  397. result:=nil;
  398. resulttypepass(left);
  399. resulttypepass(right);
  400. set_varstate(right,vs_read,[vsf_must_be_valid]);
  401. set_varstate(left,vs_read,[vsf_must_be_valid]);
  402. if codegenerror then
  403. exit;
  404. { constant folding }
  405. if is_constintnode(left) and is_constintnode(right) then
  406. begin
  407. case nodetype of
  408. shrn:
  409. t:=genintconstnode(tordconstnode(left).value shr tordconstnode(right).value);
  410. shln:
  411. t:=genintconstnode(tordconstnode(left).value shl tordconstnode(right).value);
  412. end;
  413. result:=t;
  414. exit;
  415. end;
  416. { allow operator overloading }
  417. t:=self;
  418. if isbinaryoverloaded(t) then
  419. begin
  420. result:=t;
  421. exit;
  422. end;
  423. { calculations for ordinals < 32 bit have to be done in
  424. 32 bit for backwards compatibility. That way 'shl 33' is
  425. the same as 'shl 1'. It's ugly but compatible with delphi/tp/gcc }
  426. if (not is_64bit(left.resulttype.def)) and
  427. (torddef(left.resulttype.def).typ<>u32bit) then
  428. inserttypeconv(left,s32inttype);
  429. inserttypeconv(right,sinttype);
  430. resulttype:=left.resulttype;
  431. end;
  432. {$ifndef cpu64bit}
  433. function tshlshrnode.first_shlshr64bitint: tnode;
  434. var
  435. procname: string[31];
  436. begin
  437. result := nil;
  438. { otherwise create a call to a helper }
  439. if nodetype = shln then
  440. procname := 'fpc_shl_int64'
  441. else
  442. procname := 'fpc_shr_int64';
  443. { this order of parameters works at least for the arm,
  444. however it should work for any calling conventions (FK) }
  445. result := ccallnode.createintern(procname,ccallparanode.create(right,
  446. ccallparanode.create(left,nil)));
  447. left := nil;
  448. right := nil;
  449. firstpass(result);
  450. end;
  451. {$endif cpu64bit}
  452. function tshlshrnode.pass_1 : tnode;
  453. var
  454. regs : longint;
  455. begin
  456. result:=nil;
  457. firstpass(left);
  458. firstpass(right);
  459. if codegenerror then
  460. exit;
  461. {$ifndef cpu64bit}
  462. { 64 bit ints have their own shift handling }
  463. if is_64bit(left.resulttype.def) then
  464. begin
  465. result := first_shlshr64bitint;
  466. if assigned(result) then
  467. exit;
  468. regs:=2;
  469. end
  470. else
  471. {$endif cpu64bit}
  472. begin
  473. regs:=1
  474. end;
  475. if (right.nodetype<>ordconstn) then
  476. inc(regs);
  477. expectloc:=LOC_REGISTER;
  478. calcregisters(self,regs,0,0);
  479. end;
  480. {****************************************************************************
  481. TUNARYMINUSNODE
  482. ****************************************************************************}
  483. constructor tunaryminusnode.create(expr : tnode);
  484. begin
  485. inherited create(unaryminusn,expr);
  486. end;
  487. function tunaryminusnode.det_resulttype : tnode;
  488. var
  489. t : tnode;
  490. begin
  491. result:=nil;
  492. resulttypepass(left);
  493. set_varstate(left,vs_read,[vsf_must_be_valid]);
  494. if codegenerror then
  495. exit;
  496. { constant folding }
  497. if is_constintnode(left) then
  498. begin
  499. result:=genintconstnode(-tordconstnode(left).value);
  500. exit;
  501. end;
  502. if is_constrealnode(left) then
  503. begin
  504. trealconstnode(left).value_real:=-trealconstnode(left).value_real;
  505. result:=left;
  506. left:=nil;
  507. exit;
  508. end;
  509. resulttype:=left.resulttype;
  510. if (left.resulttype.def.deftype=floatdef) then
  511. begin
  512. end
  513. {$ifdef SUPPORT_MMX}
  514. else if (cs_mmx in aktlocalswitches) and
  515. is_mmx_able_array(left.resulttype.def) then
  516. begin
  517. { if saturation is on, left.resulttype.def isn't
  518. "mmx able" (FK)
  519. if (cs_mmx_saturation in aktlocalswitches^) and
  520. (torddef(tarraydef(resulttype.def).definition).typ in
  521. [s32bit,u32bit]) then
  522. CGMessage(type_e_mismatch);
  523. }
  524. end
  525. {$endif SUPPORT_MMX}
  526. {$ifndef cpu64bit}
  527. else if is_64bitint(left.resulttype.def) then
  528. begin
  529. end
  530. {$endif cpu64bit}
  531. else if (left.resulttype.def.deftype=orddef) then
  532. begin
  533. inserttypeconv(left,sinttype);
  534. resulttype:=left.resulttype;
  535. end
  536. else
  537. begin
  538. { allow operator overloading }
  539. t:=self;
  540. if isunaryoverloaded(t) then
  541. begin
  542. result:=t;
  543. exit;
  544. end;
  545. CGMessage(type_e_mismatch);
  546. end;
  547. end;
  548. { generic code }
  549. { overridden by: }
  550. { i386 }
  551. function tunaryminusnode.pass_1 : tnode;
  552. begin
  553. result:=nil;
  554. firstpass(left);
  555. if codegenerror then
  556. exit;
  557. registersint:=left.registersint;
  558. registersfpu:=left.registersfpu;
  559. {$ifdef SUPPORT_MMX}
  560. registersmmx:=left.registersmmx;
  561. {$endif SUPPORT_MMX}
  562. if (left.resulttype.def.deftype=floatdef) then
  563. begin
  564. if (left.expectloc<>LOC_REGISTER) and
  565. (registersfpu<1) then
  566. registersfpu:=1;
  567. expectloc:=LOC_FPUREGISTER;
  568. end
  569. {$ifdef SUPPORT_MMX}
  570. else if (cs_mmx in aktlocalswitches) and
  571. is_mmx_able_array(left.resulttype.def) then
  572. begin
  573. if (left.expectloc<>LOC_MMXREGISTER) and
  574. (registersmmx<1) then
  575. registersmmx:=1;
  576. end
  577. {$endif SUPPORT_MMX}
  578. {$ifndef cpu64bit}
  579. else if is_64bit(left.resulttype.def) then
  580. begin
  581. if (left.expectloc<>LOC_REGISTER) and
  582. (registersint<2) then
  583. registersint:=2;
  584. expectloc:=LOC_REGISTER;
  585. end
  586. {$endif cpu64bit}
  587. else if (left.resulttype.def.deftype=orddef) then
  588. begin
  589. if (left.expectloc<>LOC_REGISTER) and
  590. (registersint<1) then
  591. registersint:=1;
  592. expectloc:=LOC_REGISTER;
  593. end;
  594. end;
  595. {****************************************************************************
  596. TNOTNODE
  597. ****************************************************************************}
  598. const
  599. boolean_reverse:array[ltn..unequaln] of Tnodetype=(
  600. gten,gtn,lten,ltn,unequaln,equaln
  601. );
  602. constructor tnotnode.create(expr : tnode);
  603. begin
  604. inherited create(notn,expr);
  605. end;
  606. function tnotnode.det_resulttype : tnode;
  607. var
  608. t : tnode;
  609. tt : ttype;
  610. v : tconstexprint;
  611. begin
  612. result:=nil;
  613. resulttypepass(left);
  614. set_varstate(left,vs_read,[]);
  615. if codegenerror then
  616. exit;
  617. resulttype:=left.resulttype;
  618. { Try optmimizing ourself away }
  619. if left.nodetype=notn then
  620. begin
  621. { Double not. Remove both }
  622. result:=Tnotnode(left).left;
  623. Tnotnode(left).left:=nil;
  624. exit;
  625. end;
  626. if (left.nodetype in [ltn,lten,equaln,unequaln,gtn,gten]) then
  627. begin
  628. { Not of boolean expression. Turn around the operator and remove
  629. the not. This is not allowed for sets with the gten/lten,
  630. because there is no ltn/gtn support }
  631. if (taddnode(left).left.resulttype.def.deftype<>setdef) or
  632. (left.nodetype in [equaln,unequaln]) then
  633. begin
  634. result:=left;
  635. left.nodetype:=boolean_reverse[left.nodetype];
  636. left:=nil;
  637. exit;
  638. end;
  639. end;
  640. { constant folding }
  641. if (left.nodetype=ordconstn) then
  642. begin
  643. v:=tordconstnode(left).value;
  644. tt:=left.resulttype;
  645. case torddef(left.resulttype.def).typ of
  646. bool8bit,
  647. bool16bit,
  648. bool32bit :
  649. begin
  650. { here we do a boolean(byte(..)) type cast because }
  651. { boolean(<int64>) is buggy in 1.00 }
  652. v:=byte(not(boolean(byte(v))));
  653. end;
  654. uchar,
  655. uwidechar,
  656. u8bit,
  657. s8bit,
  658. u16bit,
  659. s16bit,
  660. u32bit,
  661. s32bit,
  662. s64bit,
  663. u64bit :
  664. begin
  665. v:=int64(not int64(v)); { maybe qword is required }
  666. int_to_type(v,tt);
  667. end;
  668. else
  669. CGMessage(type_e_mismatch);
  670. end;
  671. t:=cordconstnode.create(v,tt,true);
  672. result:=t;
  673. exit;
  674. end;
  675. if is_boolean(resulttype.def) then
  676. begin
  677. end
  678. else
  679. {$ifdef SUPPORT_MMX}
  680. if (cs_mmx in aktlocalswitches) and
  681. is_mmx_able_array(left.resulttype.def) then
  682. begin
  683. end
  684. else
  685. {$endif SUPPORT_MMX}
  686. {$ifndef cpu64bit}
  687. if is_64bitint(left.resulttype.def) then
  688. begin
  689. end
  690. else
  691. {$endif cpu64bit}
  692. if is_integer(left.resulttype.def) then
  693. begin
  694. end
  695. else
  696. begin
  697. { allow operator overloading }
  698. t:=self;
  699. if isunaryoverloaded(t) then
  700. begin
  701. result:=t;
  702. exit;
  703. end;
  704. CGMessage(type_e_mismatch);
  705. end;
  706. end;
  707. function tnotnode.pass_1 : tnode;
  708. begin
  709. result:=nil;
  710. firstpass(left);
  711. if codegenerror then
  712. exit;
  713. expectloc:=left.expectloc;
  714. registersint:=left.registersint;
  715. {$ifdef SUPPORT_MMX}
  716. registersmmx:=left.registersmmx;
  717. {$endif SUPPORT_MMX}
  718. if is_boolean(resulttype.def) then
  719. begin
  720. if (expectloc in [LOC_REFERENCE,LOC_CREFERENCE,LOC_CREGISTER]) then
  721. begin
  722. expectloc:=LOC_REGISTER;
  723. if (registersint<1) then
  724. registersint:=1;
  725. end;
  726. { before loading it into flags we need to load it into
  727. a register thus 1 register is need PM }
  728. {$ifdef cpuflags}
  729. if left.expectloc<>LOC_JUMP then
  730. expectloc:=LOC_FLAGS;
  731. {$endif def cpuflags}
  732. end
  733. else
  734. {$ifdef SUPPORT_MMX}
  735. if (cs_mmx in aktlocalswitches) and
  736. is_mmx_able_array(left.resulttype.def) then
  737. begin
  738. if (left.expectloc<>LOC_MMXREGISTER) and
  739. (registersmmx<1) then
  740. registersmmx:=1;
  741. end
  742. else
  743. {$endif SUPPORT_MMX}
  744. {$ifndef cpu64bit}
  745. if is_64bit(left.resulttype.def) then
  746. begin
  747. if (expectloc in [LOC_REFERENCE,LOC_CREFERENCE,LOC_CREGISTER]) then
  748. begin
  749. expectloc:=LOC_REGISTER;
  750. if (registersint<2) then
  751. registersint:=2;
  752. end;
  753. end
  754. else
  755. {$endif cpu64bit}
  756. if is_integer(left.resulttype.def) then
  757. begin
  758. if (left.expectloc<>LOC_REGISTER) and
  759. (registersint<1) then
  760. registersint:=1;
  761. expectloc:=LOC_REGISTER;
  762. end;
  763. end;
  764. {$ifdef state_tracking}
  765. function Tnotnode.track_state_pass(exec_known:boolean):boolean;
  766. begin
  767. track_state_pass:=true;
  768. if left.track_state_pass(exec_known) then
  769. begin
  770. left.resulttype.def:=nil;
  771. do_resulttypepass(left);
  772. end;
  773. end;
  774. {$endif}
  775. begin
  776. cmoddivnode:=tmoddivnode;
  777. cshlshrnode:=tshlshrnode;
  778. cunaryminusnode:=tunaryminusnode;
  779. cnotnode:=tnotnode;
  780. end.