nmat.pas 32 KB

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