nmat.pas 26 KB

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