nmat.pas 31 KB

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