nadd.pas 50 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282
  1. {
  2. $Id$
  3. Copyright (c) 1998-2000 by Florian Klaempfl
  4. Type checking and register allocation for add 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 nadd;
  19. {$i defines.inc}
  20. interface
  21. uses
  22. node;
  23. type
  24. taddnode = class(tbinopnode)
  25. procedure make_bool_equal_size;
  26. function pass_1 : tnode;override;
  27. end;
  28. var
  29. { caddnode is used to create nodes of the add type }
  30. { the virtual constructor allows to assign }
  31. { another class type to caddnode => processor }
  32. { specific node types can be created }
  33. caddnode : class of taddnode;
  34. implementation
  35. uses
  36. globtype,systems,
  37. cutils,verbose,globals,
  38. symconst,symtype,symdef,types,
  39. cpuinfo,
  40. {$ifdef newcg}
  41. cgbase,
  42. {$else newcg}
  43. hcodegen,
  44. {$endif newcg}
  45. htypechk,pass_1,
  46. nmat,ncnv,nld,ncon,nset,nopt,
  47. cpubase;
  48. {*****************************************************************************
  49. TADDNODE
  50. *****************************************************************************}
  51. {$ifdef fpc}
  52. {$maxfpuregisters 0}
  53. {$endif fpc}
  54. procedure taddnode.make_bool_equal_size;
  55. begin
  56. if porddef(left.resulttype)^.typ>porddef(right.resulttype)^.typ then
  57. begin
  58. right:=gentypeconvnode(right,porddef(left.resulttype));
  59. ttypeconvnode(right).convtype:=tc_bool_2_int;
  60. include(right.flags,nf_explizit);
  61. firstpass(right);
  62. end
  63. else
  64. if porddef(left.resulttype)^.typ<porddef(right.resulttype)^.typ then
  65. begin
  66. left:=gentypeconvnode(left,porddef(right.resulttype));
  67. ttypeconvnode(left).convtype:=tc_bool_2_int;
  68. include(left.flags,nf_explizit);
  69. firstpass(left);
  70. end;
  71. end;
  72. function taddnode.pass_1 : tnode;
  73. var
  74. t,hp : tnode;
  75. ot,
  76. lt,rt : tnodetype;
  77. rv,lv : tconstexprint;
  78. rvd,lvd : bestreal;
  79. resdef,
  80. rd,ld : pdef;
  81. tempdef : pdef;
  82. concatstrings : boolean;
  83. { to evalute const sets }
  84. resultset : pconstset;
  85. i : longint;
  86. b : boolean;
  87. convdone : boolean;
  88. s1,s2 : pchar;
  89. l1,l2 : longint;
  90. begin
  91. pass_1:=nil;
  92. { first do the two subtrees }
  93. firstpass(left);
  94. firstpass(right);
  95. if codegenerror then
  96. exit;
  97. { convert array constructors to sets, because there is no other operator
  98. possible for array constructors }
  99. if is_array_constructor(left.resulttype) then
  100. arrayconstructor_to_set(tarrayconstructornode(left));
  101. if is_array_constructor(right.resulttype) then
  102. arrayconstructor_to_set(tarrayconstructornode(right));
  103. { both left and right need to be valid }
  104. set_varstate(left,true);
  105. set_varstate(right,true);
  106. { load easier access variables }
  107. lt:=left.nodetype;
  108. rt:=right.nodetype;
  109. rd:=right.resulttype;
  110. ld:=left.resulttype;
  111. convdone:=false;
  112. hp:=self;
  113. if isbinaryoverloaded(hp) then
  114. begin
  115. pass_1:=hp;
  116. exit;
  117. end;
  118. { compact consts }
  119. { convert int consts to real consts, if the }
  120. { other operand is a real const }
  121. if (rt=realconstn) and is_constintnode(left) then
  122. begin
  123. t:=genrealconstnode(tordconstnode(left).value,right.resulttype);
  124. left.free;
  125. left:=t;
  126. lt:=realconstn;
  127. end;
  128. if (lt=realconstn) and is_constintnode(right) then
  129. begin
  130. t:=genrealconstnode(tordconstnode(right).value,left.resulttype);
  131. right.free;
  132. right:=t;
  133. rt:=realconstn;
  134. end;
  135. { both are int constants, also allow operations on two equal enums
  136. in fpc mode (Needed for conversion of C code) }
  137. if ((lt=ordconstn) and (rt=ordconstn)) and
  138. ((is_constintnode(left) and is_constintnode(right)) or
  139. (is_constboolnode(left) and is_constboolnode(right) and
  140. (nodetype in [ltn,lten,gtn,gten,equaln,unequaln,andn,xorn,orn]))) then
  141. begin
  142. { xor, and, or are handled different from arithmetic }
  143. { operations regarding the result type }
  144. { return a boolean for boolean operations (and,xor,or) }
  145. if is_constboolnode(left) then
  146. resdef:=booldef
  147. else if is_64bitint(rd) or is_64bitint(ld) then
  148. resdef:=cs64bitdef
  149. else
  150. resdef:=s32bitdef;
  151. lv:=tordconstnode(left).value;
  152. rv:=tordconstnode(right).value;
  153. case nodetype of
  154. addn : t:=genintconstnode(lv+rv);
  155. subn : t:=genintconstnode(lv-rv);
  156. muln : t:=genintconstnode(lv*rv);
  157. xorn : t:=genordinalconstnode(lv xor rv,resdef);
  158. orn: t:=genordinalconstnode(lv or rv,resdef);
  159. andn: t:=genordinalconstnode(lv and rv,resdef);
  160. ltn : t:=genordinalconstnode(ord(lv<rv),booldef);
  161. lten : t:=genordinalconstnode(ord(lv<=rv),booldef);
  162. gtn : t:=genordinalconstnode(ord(lv>rv),booldef);
  163. gten : t:=genordinalconstnode(ord(lv>=rv),booldef);
  164. equaln : t:=genordinalconstnode(ord(lv=rv),booldef);
  165. unequaln : t:=genordinalconstnode(ord(lv<>rv),booldef);
  166. slashn : begin
  167. { int/int becomes a real }
  168. if int(rv)=0 then
  169. begin
  170. Message(parser_e_invalid_float_operation);
  171. t:=genrealconstnode(0,bestrealdef^);
  172. end
  173. else
  174. t:=genrealconstnode(int(lv)/int(rv),bestrealdef^);
  175. firstpass(t);
  176. end;
  177. else
  178. CGMessage(type_e_mismatch);
  179. end;
  180. pass_1:=t;
  181. exit;
  182. end;
  183. { both real constants ? }
  184. if (lt=realconstn) and (rt=realconstn) then
  185. begin
  186. lvd:=trealconstnode(left).value_real;
  187. rvd:=trealconstnode(right).value_real;
  188. case nodetype of
  189. addn : t:=genrealconstnode(lvd+rvd,bestrealdef^);
  190. subn : t:=genrealconstnode(lvd-rvd,bestrealdef^);
  191. muln : t:=genrealconstnode(lvd*rvd,bestrealdef^);
  192. starstarn,
  193. caretn : begin
  194. if lvd<0 then
  195. begin
  196. Message(parser_e_invalid_float_operation);
  197. t:=genrealconstnode(0,bestrealdef^);
  198. end
  199. else if lvd=0 then
  200. t:=genrealconstnode(1.0,bestrealdef^)
  201. else
  202. t:=genrealconstnode(exp(ln(lvd)*rvd),bestrealdef^);
  203. end;
  204. slashn :
  205. begin
  206. if rvd=0 then
  207. begin
  208. Message(parser_e_invalid_float_operation);
  209. t:=genrealconstnode(0,bestrealdef^);
  210. end
  211. else
  212. t:=genrealconstnode(lvd/rvd,bestrealdef^);
  213. end;
  214. ltn : t:=genordinalconstnode(ord(lvd<rvd),booldef);
  215. lten : t:=genordinalconstnode(ord(lvd<=rvd),booldef);
  216. gtn : t:=genordinalconstnode(ord(lvd>rvd),booldef);
  217. gten : t:=genordinalconstnode(ord(lvd>=rvd),booldef);
  218. equaln : t:=genordinalconstnode(ord(lvd=rvd),booldef);
  219. unequaln : t:=genordinalconstnode(ord(lvd<>rvd),booldef);
  220. else
  221. CGMessage(type_e_mismatch);
  222. end;
  223. pass_1:=t;
  224. exit;
  225. end;
  226. { concating strings ? }
  227. concatstrings:=false;
  228. s1:=nil;
  229. s2:=nil;
  230. if (lt=ordconstn) and (rt=ordconstn) and
  231. is_char(ld) and is_char(rd) then
  232. begin
  233. s1:=strpnew(char(byte(tordconstnode(left).value)));
  234. s2:=strpnew(char(byte(tordconstnode(right).value)));
  235. l1:=1;
  236. l2:=1;
  237. concatstrings:=true;
  238. end
  239. else
  240. if (lt=stringconstn) and (rt=ordconstn) and is_char(rd) then
  241. begin
  242. s1:=tstringconstnode(left).getpcharcopy;
  243. l1:=tstringconstnode(left).len;
  244. s2:=strpnew(char(byte(tordconstnode(right).value)));
  245. l2:=1;
  246. concatstrings:=true;
  247. end
  248. else
  249. if (lt=ordconstn) and (rt=stringconstn) and is_char(ld) then
  250. begin
  251. s1:=strpnew(char(byte(tordconstnode(left).value)));
  252. l1:=1;
  253. s2:=tstringconstnode(right).getpcharcopy;
  254. l2:=tstringconstnode(right).len;
  255. concatstrings:=true;
  256. end
  257. else if (lt=stringconstn) and (rt=stringconstn) then
  258. begin
  259. s1:=tstringconstnode(left).getpcharcopy;
  260. l1:=tstringconstnode(left).len;
  261. s2:=tstringconstnode(right).getpcharcopy;
  262. l2:=tstringconstnode(right).len;
  263. concatstrings:=true;
  264. end;
  265. { I will need to translate all this to ansistrings !!! }
  266. if concatstrings then
  267. begin
  268. case nodetype of
  269. addn :
  270. t:=genpcharconstnode(concatansistrings(s1,s2,l1,l2),l1+l2);
  271. ltn :
  272. t:=genordinalconstnode(byte(compareansistrings(s1,s2,l1,l2)<0),booldef);
  273. lten :
  274. t:=genordinalconstnode(byte(compareansistrings(s1,s2,l1,l2)<=0),booldef);
  275. gtn :
  276. t:=genordinalconstnode(byte(compareansistrings(s1,s2,l1,l2)>0),booldef);
  277. gten :
  278. t:=genordinalconstnode(byte(compareansistrings(s1,s2,l1,l2)>=0),booldef);
  279. equaln :
  280. t:=genordinalconstnode(byte(compareansistrings(s1,s2,l1,l2)=0),booldef);
  281. unequaln :
  282. t:=genordinalconstnode(byte(compareansistrings(s1,s2,l1,l2)<>0),booldef);
  283. end;
  284. ansistringdispose(s1,l1);
  285. ansistringdispose(s2,l2);
  286. pass_1:=t;
  287. exit;
  288. end;
  289. { if both are orddefs then check sub types }
  290. if (ld^.deftype=orddef) and (rd^.deftype=orddef) then
  291. begin
  292. { 2 booleans ? }
  293. if is_boolean(ld) and is_boolean(rd) then
  294. begin
  295. if (cs_full_boolean_eval in aktlocalswitches) or
  296. (nodetype in [xorn,ltn,lten,gtn,gten]) then
  297. begin
  298. make_bool_equal_size;
  299. if (left.location.loc in [LOC_JUMP,LOC_FLAGS]) and
  300. (left.location.loc in [LOC_JUMP,LOC_FLAGS]) then
  301. calcregisters(self,2,0,0)
  302. else
  303. calcregisters(self,1,0,0);
  304. end
  305. else
  306. case nodetype of
  307. andn,
  308. orn:
  309. begin
  310. make_bool_equal_size;
  311. calcregisters(self,0,0,0);
  312. location.loc:=LOC_JUMP;
  313. end;
  314. unequaln,
  315. equaln:
  316. begin
  317. make_bool_equal_size;
  318. { Remove any compares with constants }
  319. if (left.nodetype=ordconstn) then
  320. begin
  321. hp:=right;
  322. b:=(tordconstnode(left).value<>0);
  323. ot:=nodetype;
  324. left.free;
  325. left:=nil;
  326. right:=nil;
  327. if (not(b) and (ot=equaln)) or
  328. (b and (ot=unequaln)) then
  329. begin
  330. hp:=cnotnode.create(hp);
  331. firstpass(hp);
  332. end;
  333. pass_1:=hp;
  334. exit;
  335. end;
  336. if (right.nodetype=ordconstn) then
  337. begin
  338. hp:=left;
  339. b:=(tordconstnode(right).value<>0);
  340. ot:=nodetype;
  341. right.free;
  342. right:=nil;
  343. left:=nil;
  344. if (not(b) and (ot=equaln)) or
  345. (b and (ot=unequaln)) then
  346. begin
  347. hp:=cnotnode.create(hp);
  348. firstpass(hp);
  349. end;
  350. pass_1:=hp;
  351. exit;
  352. end;
  353. if (left.location.loc in [LOC_JUMP,LOC_FLAGS]) and
  354. (left.location.loc in [LOC_JUMP,LOC_FLAGS]) then
  355. calcregisters(self,2,0,0)
  356. else
  357. calcregisters(self,1,0,0);
  358. end;
  359. else
  360. CGMessage(type_e_mismatch);
  361. end;
  362. (*
  363. { these one can't be in flags! }
  364. Yes they can, secondadd converts the loc_flags to a register.
  365. The typeconversions below are simply removed by firsttypeconv()
  366. because the resulttype of left = left.resulttype
  367. (surprise! :) (JM)
  368. if nodetype in [xorn,unequaln,equaln] then
  369. begin
  370. if left.location.loc=LOC_FLAGS then
  371. begin
  372. left:=gentypeconvnode(left,porddef(left.resulttype));
  373. left.convtype:=tc_bool_2_int;
  374. left.explizit:=true;
  375. firstpass(left);
  376. end;
  377. if right.location.loc=LOC_FLAGS then
  378. begin
  379. right:=gentypeconvnode(right,porddef(right.resulttype));
  380. right.convtype:=tc_bool_2_int;
  381. right.explizit:=true;
  382. firstpass(right);
  383. end;
  384. { readjust registers }
  385. calcregisters(p,1,0,0);
  386. end;
  387. *)
  388. convdone:=true;
  389. end
  390. else
  391. { Both are chars? only convert to shortstrings for addn }
  392. if is_char(rd) and is_char(ld) then
  393. begin
  394. if nodetype=addn then
  395. begin
  396. left:=gentypeconvnode(left,cshortstringdef);
  397. firstpass(left);
  398. hp := genaddsstringcharoptnode(self);
  399. firstpass(hp);
  400. pass_1 := hp;
  401. exit;
  402. end
  403. else
  404. calcregisters(self,1,0,0);
  405. convdone:=true;
  406. end
  407. { is there a 64 bit type ? }
  408. else if ((porddef(rd)^.typ=s64bit) or (porddef(ld)^.typ=s64bit)) and
  409. { the / operator is handled later }
  410. (nodetype<>slashn) then
  411. begin
  412. if (porddef(ld)^.typ<>s64bit) then
  413. begin
  414. left:=gentypeconvnode(left,cs64bitdef);
  415. firstpass(left);
  416. end;
  417. if (porddef(rd)^.typ<>s64bit) then
  418. begin
  419. right:=gentypeconvnode(right,cs64bitdef);
  420. firstpass(right);
  421. end;
  422. calcregisters(self,2,0,0);
  423. convdone:=true;
  424. end
  425. else if ((porddef(rd)^.typ=u64bit) or (porddef(ld)^.typ=u64bit)) and
  426. { the / operator is handled later }
  427. (nodetype<>slashn) then
  428. begin
  429. if (porddef(ld)^.typ<>u64bit) then
  430. begin
  431. left:=gentypeconvnode(left,cu64bitdef);
  432. firstpass(left);
  433. end;
  434. if (porddef(rd)^.typ<>u64bit) then
  435. begin
  436. right:=gentypeconvnode(right,cu64bitdef);
  437. firstpass(right);
  438. end;
  439. calcregisters(self,2,0,0);
  440. convdone:=true;
  441. end
  442. else
  443. { is there a cardinal? }
  444. if ((porddef(rd)^.typ=u32bit) or (porddef(ld)^.typ=u32bit)) and
  445. { the / operator is handled later }
  446. (nodetype<>slashn) then
  447. begin
  448. if is_signed(ld) and
  449. { then rd = u32bit }
  450. { convert positive constants to u32bit }
  451. not(is_constintnode(left) and
  452. (tordconstnode(left).value >= 0)) and
  453. { range/overflow checking on mixed signed/cardinal expressions }
  454. { is only possible if you convert everything to 64bit (JM) }
  455. ((aktlocalswitches * [cs_check_overflow,cs_check_range] <> []) and
  456. (nodetype in [addn,subn,muln])) then
  457. begin
  458. { perform the operation in 64bit }
  459. CGMessage(type_w_mixed_signed_unsigned);
  460. left := gentypeconvnode(left,cs64bitdef);
  461. firstpass(left);
  462. right := gentypeconvnode(right,cs64bitdef);
  463. firstpass(right);
  464. end
  465. else
  466. begin
  467. if is_signed(ld) and
  468. not(is_constintnode(left) and
  469. (tordconstnode(left).value >= 0)) and
  470. (cs_check_range in aktlocalswitches) then
  471. CGMessage(type_w_mixed_signed_unsigned2);
  472. left := gentypeconvnode(left,u32bitdef);
  473. firstpass(left);
  474. if is_signed(rd) and
  475. { then ld = u32bit }
  476. { convert positive constants to u32bit }
  477. not(is_constintnode(right) and
  478. (tordconstnode(right).value >= 0)) and
  479. ((aktlocalswitches * [cs_check_overflow,cs_check_range] <> []) and
  480. (nodetype in [addn,subn,muln])) then
  481. begin
  482. { perform the operation in 64bit }
  483. CGMessage(type_w_mixed_signed_unsigned);
  484. left := gentypeconvnode(left,cs64bitdef);
  485. firstpass(left);
  486. right := gentypeconvnode(right,cs64bitdef);
  487. firstpass(right);
  488. end
  489. else
  490. begin
  491. if is_signed(rd) and
  492. not(is_constintnode(right) and
  493. (tordconstnode(right).value >= 0)) and
  494. (cs_check_range in aktlocalswitches) then
  495. CGMessage(type_w_mixed_signed_unsigned2);
  496. right := gentypeconvnode(right,u32bitdef);
  497. firstpass(right);
  498. end;
  499. end;
  500. { did we convert things to 64bit? }
  501. if porddef(left.resulttype)^.typ = s64bit then
  502. calcregisters(self,2,0,0)
  503. else
  504. begin
  505. calcregisters(self,1,0,0);
  506. { for unsigned mul we need an extra register }
  507. if nodetype=muln then
  508. inc(registers32);
  509. end;
  510. convdone:=true;
  511. end;
  512. end
  513. else
  514. { left side a setdef, must be before string processing,
  515. else array constructor can be seen as array of char (PFV) }
  516. if (ld^.deftype=setdef) {or is_array_constructor(ld)} then
  517. begin
  518. { trying to add a set element? }
  519. if (nodetype=addn) and (rd^.deftype<>setdef) then
  520. begin
  521. if (rt=setelementn) then
  522. begin
  523. if not(is_equal(psetdef(ld)^.elementtype.def,rd)) then
  524. CGMessage(type_e_set_element_are_not_comp);
  525. end
  526. else
  527. CGMessage(type_e_mismatch)
  528. end
  529. else
  530. begin
  531. if not(nodetype in [addn,subn,symdifn,muln,equaln,unequaln
  532. {$IfNDef NoSetInclusion}
  533. ,lten,gten
  534. {$EndIf NoSetInclusion}
  535. ]) then
  536. CGMessage(type_e_set_operation_unknown);
  537. { right def must be a also be set }
  538. if (rd^.deftype<>setdef) or not(is_equal(rd,ld)) then
  539. CGMessage(type_e_set_element_are_not_comp);
  540. end;
  541. { ranges require normsets }
  542. if (psetdef(ld)^.settype=smallset) and
  543. (rt=setelementn) and
  544. assigned(tsetelementnode(right).right) then
  545. begin
  546. { generate a temporary normset def, it'll be destroyed
  547. when the symtable is unloaded }
  548. tempdef:=new(psetdef,init(psetdef(ld)^.elementtype.def,255));
  549. left:=gentypeconvnode(left,tempdef);
  550. firstpass(left);
  551. ld:=left.resulttype;
  552. end;
  553. { if the destination is not a smallset then insert a typeconv
  554. which loads a smallset into a normal set }
  555. if (psetdef(ld)^.settype<>smallset) and
  556. (psetdef(rd)^.settype=smallset) then
  557. begin
  558. if (right.nodetype=setconstn) then
  559. begin
  560. t:=gensetconstnode(tsetconstnode(right).value_set,psetdef(left.resulttype));
  561. tsetconstnode(t).left:=tsetconstnode(right).left;
  562. tsetconstnode(right).left:=nil;
  563. right.free;
  564. right:=t;
  565. end
  566. else
  567. right:=gentypeconvnode(right,psetdef(left.resulttype));
  568. firstpass(right);
  569. end;
  570. { do constant evaluation }
  571. if (right.nodetype=setconstn) and
  572. not assigned(tsetconstnode(right).left) and
  573. (left.nodetype=setconstn) and
  574. not assigned(tsetconstnode(left).left) then
  575. begin
  576. new(resultset);
  577. case nodetype of
  578. addn : begin
  579. for i:=0 to 31 do
  580. resultset^[i]:=
  581. tsetconstnode(right).value_set^[i] or tsetconstnode(left).value_set^[i];
  582. t:=gensetconstnode(resultset,psetdef(ld));
  583. end;
  584. muln : begin
  585. for i:=0 to 31 do
  586. resultset^[i]:=
  587. tsetconstnode(right).value_set^[i] and tsetconstnode(left).value_set^[i];
  588. t:=gensetconstnode(resultset,psetdef(ld));
  589. end;
  590. subn : begin
  591. for i:=0 to 31 do
  592. resultset^[i]:=
  593. tsetconstnode(left).value_set^[i] and not(tsetconstnode(right).value_set^[i]);
  594. t:=gensetconstnode(resultset,psetdef(ld));
  595. end;
  596. symdifn : begin
  597. for i:=0 to 31 do
  598. resultset^[i]:=
  599. tsetconstnode(left).value_set^[i] xor tsetconstnode(right).value_set^[i];
  600. t:=gensetconstnode(resultset,psetdef(ld));
  601. end;
  602. unequaln : begin
  603. b:=true;
  604. for i:=0 to 31 do
  605. if tsetconstnode(right).value_set^[i]=tsetconstnode(left).value_set^[i] then
  606. begin
  607. b:=false;
  608. break;
  609. end;
  610. t:=genordinalconstnode(ord(b),booldef);
  611. end;
  612. equaln : begin
  613. b:=true;
  614. for i:=0 to 31 do
  615. if tsetconstnode(right).value_set^[i]<>tsetconstnode(left).value_set^[i] then
  616. begin
  617. b:=false;
  618. break;
  619. end;
  620. t:=genordinalconstnode(ord(b),booldef);
  621. end;
  622. {$IfNDef NoSetInclusion}
  623. lten : Begin
  624. b := true;
  625. For i := 0 to 31 Do
  626. If (tsetconstnode(right).value_set^[i] And tsetconstnode(left).value_set^[i]) <>
  627. tsetconstnode(left).value_set^[i] Then
  628. Begin
  629. b := false;
  630. Break
  631. End;
  632. t := genordinalconstnode(ord(b),booldef);
  633. End;
  634. gten : Begin
  635. b := true;
  636. For i := 0 to 31 Do
  637. If (tsetconstnode(left).value_set^[i] And tsetconstnode(right).value_set^[i]) <>
  638. tsetconstnode(right).value_set^[i] Then
  639. Begin
  640. b := false;
  641. Break
  642. End;
  643. t := genordinalconstnode(ord(b),booldef);
  644. End;
  645. {$EndIf NoSetInclusion}
  646. end;
  647. dispose(resultset);
  648. firstpass(t);
  649. pass_1:=t;
  650. exit;
  651. end
  652. else
  653. if psetdef(ld)^.settype=smallset then
  654. begin
  655. { are we adding set elements ? }
  656. if right.nodetype=setelementn then
  657. calcregisters(self,2,0,0)
  658. else
  659. calcregisters(self,1,0,0);
  660. location.loc:=LOC_REGISTER;
  661. end
  662. else
  663. begin
  664. calcregisters(self,0,0,0);
  665. { here we call SET... }
  666. procinfo^.flags:=procinfo^.flags or pi_do_call;
  667. location.loc:=LOC_MEM;
  668. end;
  669. convdone:=true;
  670. end
  671. else
  672. { compare pchar to char arrays by addresses
  673. like BP/Delphi }
  674. if (is_pchar(ld) and is_chararray(rd)) or
  675. (is_pchar(rd) and is_chararray(ld)) then
  676. begin
  677. if is_chararray(rd) then
  678. begin
  679. right:=gentypeconvnode(right,ld);
  680. firstpass(right);
  681. end
  682. else
  683. begin
  684. left:=gentypeconvnode(left,rd);
  685. firstpass(left);
  686. end;
  687. location.loc:=LOC_REGISTER;
  688. calcregisters(self,1,0,0);
  689. convdone:=true;
  690. end
  691. else
  692. { is one of the operands a string?,
  693. chararrays are also handled as strings (after conversion) }
  694. if (rd^.deftype=stringdef) or (ld^.deftype=stringdef) or
  695. ((is_chararray(rd) or is_char(rd)) and
  696. (is_chararray(ld) or is_char(ld))) then
  697. begin
  698. if is_widestring(rd) or is_widestring(ld) then
  699. begin
  700. if not(is_widestring(rd)) then
  701. right:=gentypeconvnode(right,cwidestringdef);
  702. if not(is_widestring(ld)) then
  703. left:=gentypeconvnode(left,cwidestringdef);
  704. resulttype:=cwidestringdef;
  705. { this is only for add, the comparisaion is handled later }
  706. location.loc:=LOC_REGISTER;
  707. end
  708. else if is_ansistring(rd) or is_ansistring(ld) then
  709. begin
  710. if not(is_ansistring(rd)) then
  711. right:=gentypeconvnode(right,cansistringdef);
  712. if not(is_ansistring(ld)) then
  713. left:=gentypeconvnode(left,cansistringdef);
  714. { we use ansistrings so no fast exit here }
  715. procinfo^.no_fast_exit:=true;
  716. resulttype:=cansistringdef;
  717. { this is only for add, the comparisaion is handled later }
  718. location.loc:=LOC_REGISTER;
  719. end
  720. else if is_longstring(rd) or is_longstring(ld) then
  721. begin
  722. if not(is_longstring(rd)) then
  723. right:=gentypeconvnode(right,clongstringdef);
  724. if not(is_longstring(ld)) then
  725. left:=gentypeconvnode(left,clongstringdef);
  726. resulttype:=clongstringdef;
  727. { this is only for add, the comparisaion is handled later }
  728. location.loc:=LOC_MEM;
  729. end
  730. else
  731. begin
  732. if canbeaddsstringcharoptnode(self) then
  733. begin
  734. hp := genaddsstringcharoptnode(self);
  735. firstpass(hp);
  736. pass_1 := hp;
  737. exit;
  738. end;
  739. if canbeaddsstringcsstringoptnode(self) then
  740. begin
  741. hp := genaddsstringcsstringoptnode(self);
  742. firstpass(hp);
  743. pass_1 := hp;
  744. exit;
  745. end;
  746. if not(is_shortstring(ld)) then
  747. left:=gentypeconvnode(left,cshortstringdef);
  748. if not(is_shortstring(rd)) then
  749. right:=gentypeconvnode(right,cshortstringdef);
  750. resulttype:=left.resulttype;
  751. { this is only for add, the comparisaion is handled later }
  752. location.loc:=LOC_MEM;
  753. end;
  754. { only if there is a type cast we need to do again }
  755. { the first pass }
  756. if left.nodetype=typeconvn then
  757. firstpass(left);
  758. if right.nodetype=typeconvn then
  759. firstpass(right);
  760. { here we call STRCONCAT or STRCMP or STRCOPY }
  761. procinfo^.flags:=procinfo^.flags or pi_do_call;
  762. if location.loc=LOC_MEM then
  763. calcregisters(self,0,0,0)
  764. else
  765. calcregisters(self,1,0,0);
  766. convdone:=true;
  767. end
  768. else
  769. { is one a real float ? }
  770. if (rd^.deftype=floatdef) or (ld^.deftype=floatdef) then
  771. begin
  772. { if one is a fixed, then convert to f32bit }
  773. if ((rd^.deftype=floatdef) and (pfloatdef(rd)^.typ=f32bit)) or
  774. ((ld^.deftype=floatdef) and (pfloatdef(ld)^.typ=f32bit)) then
  775. begin
  776. if not is_integer(rd) or (nodetype<>muln) then
  777. right:=gentypeconvnode(right,s32fixeddef);
  778. if not is_integer(ld) or (nodetype<>muln) then
  779. left:=gentypeconvnode(left,s32fixeddef);
  780. firstpass(left);
  781. firstpass(right);
  782. calcregisters(self,1,0,0);
  783. location.loc:=LOC_REGISTER;
  784. end
  785. else
  786. { convert both to bestreal }
  787. begin
  788. right:=gentypeconvnode(right,bestrealdef^);
  789. left:=gentypeconvnode(left,bestrealdef^);
  790. firstpass(left);
  791. firstpass(right);
  792. calcregisters(self,0,1,0);
  793. location.loc:=LOC_FPU;
  794. end;
  795. convdone:=true;
  796. end
  797. else
  798. { pointer comperation and subtraction }
  799. if (rd^.deftype=pointerdef) and (ld^.deftype=pointerdef) then
  800. begin
  801. location.loc:=LOC_REGISTER;
  802. { right:=gentypeconvnode(right,ld); }
  803. { firstpass(right); }
  804. calcregisters(self,1,0,0);
  805. case nodetype of
  806. equaln,unequaln :
  807. begin
  808. if is_equal(right.resulttype,voidpointerdef) then
  809. begin
  810. right:=gentypeconvnode(right,ld);
  811. firstpass(right);
  812. end
  813. else if is_equal(left.resulttype,voidpointerdef) then
  814. begin
  815. left:=gentypeconvnode(left,rd);
  816. firstpass(left);
  817. end
  818. else if not(is_equal(ld,rd)) then
  819. CGMessage(type_e_mismatch);
  820. end;
  821. ltn,lten,gtn,gten:
  822. begin
  823. if is_equal(right.resulttype,voidpointerdef) then
  824. begin
  825. right:=gentypeconvnode(right,ld);
  826. firstpass(right);
  827. end
  828. else if is_equal(left.resulttype,voidpointerdef) then
  829. begin
  830. left:=gentypeconvnode(left,rd);
  831. firstpass(left);
  832. end
  833. else if not(is_equal(ld,rd)) then
  834. CGMessage(type_e_mismatch);
  835. if not(cs_extsyntax in aktmoduleswitches) then
  836. CGMessage(type_e_mismatch);
  837. end;
  838. subn:
  839. begin
  840. if not(is_equal(ld,rd)) then
  841. CGMessage(type_e_mismatch);
  842. if not(cs_extsyntax in aktmoduleswitches) then
  843. CGMessage(type_e_mismatch);
  844. resulttype:=s32bitdef;
  845. exit;
  846. end;
  847. else CGMessage(type_e_mismatch);
  848. end;
  849. convdone:=true;
  850. end
  851. else
  852. if is_class_or_interface(rd) or is_class_or_interface(ld) then
  853. begin
  854. location.loc:=LOC_REGISTER;
  855. if is_class_or_interface(rd) and is_class_or_interface(ld) then
  856. begin
  857. if pobjectdef(rd)^.is_related(pobjectdef(ld)) then
  858. right:=gentypeconvnode(right,ld)
  859. else
  860. left:=gentypeconvnode(left,rd);
  861. end
  862. else if is_class_or_interface(rd) then
  863. left:=gentypeconvnode(left,rd)
  864. else
  865. right:=gentypeconvnode(right,ld);
  866. firstpass(right);
  867. firstpass(left);
  868. calcregisters(self,1,0,0);
  869. case nodetype of
  870. equaln,unequaln:
  871. ;
  872. else CGMessage(type_e_mismatch);
  873. end;
  874. convdone:=true;
  875. end
  876. else
  877. if (rd^.deftype=classrefdef) and (ld^.deftype=classrefdef) then
  878. begin
  879. location.loc:=LOC_REGISTER;
  880. if pobjectdef(pclassrefdef(rd)^.pointertype.def)^.is_related(pobjectdef(
  881. pclassrefdef(ld)^.pointertype.def)) then
  882. right:=gentypeconvnode(right,ld)
  883. else
  884. left:=gentypeconvnode(left,rd);
  885. firstpass(right);
  886. firstpass(left);
  887. calcregisters(self,1,0,0);
  888. case nodetype of
  889. equaln,unequaln : ;
  890. else CGMessage(type_e_mismatch);
  891. end;
  892. convdone:=true;
  893. end
  894. else
  895. { allows comperasion with nil pointer }
  896. if is_class_or_interface(rd) then
  897. begin
  898. location.loc:=LOC_REGISTER;
  899. left:=gentypeconvnode(left,rd);
  900. firstpass(left);
  901. calcregisters(self,1,0,0);
  902. case nodetype of
  903. equaln,unequaln : ;
  904. else CGMessage(type_e_mismatch);
  905. end;
  906. convdone:=true;
  907. end
  908. else
  909. if is_class_or_interface(ld) then
  910. begin
  911. location.loc:=LOC_REGISTER;
  912. right:=gentypeconvnode(right,ld);
  913. firstpass(right);
  914. calcregisters(self,1,0,0);
  915. case nodetype of
  916. equaln,unequaln : ;
  917. else CGMessage(type_e_mismatch);
  918. end;
  919. convdone:=true;
  920. end
  921. else
  922. if (rd^.deftype=classrefdef) then
  923. begin
  924. left:=gentypeconvnode(left,rd);
  925. firstpass(left);
  926. calcregisters(self,1,0,0);
  927. case nodetype of
  928. equaln,unequaln : ;
  929. else CGMessage(type_e_mismatch);
  930. end;
  931. convdone:=true;
  932. end
  933. else
  934. if (ld^.deftype=classrefdef) then
  935. begin
  936. right:=gentypeconvnode(right,ld);
  937. firstpass(right);
  938. calcregisters(self,1,0,0);
  939. case nodetype of
  940. equaln,unequaln : ;
  941. else
  942. CGMessage(type_e_mismatch);
  943. end;
  944. convdone:=true;
  945. end
  946. else
  947. { support procvar=nil,procvar<>nil }
  948. if ((ld^.deftype=procvardef) and (rt=niln)) or
  949. ((rd^.deftype=procvardef) and (lt=niln)) then
  950. begin
  951. calcregisters(self,1,0,0);
  952. location.loc:=LOC_REGISTER;
  953. case nodetype of
  954. equaln,unequaln : ;
  955. else
  956. CGMessage(type_e_mismatch);
  957. end;
  958. convdone:=true;
  959. end
  960. else
  961. {$ifdef SUPPORT_MMX}
  962. if (cs_mmx in aktlocalswitches) and is_mmx_able_array(ld) and
  963. is_mmx_able_array(rd) and is_equal(ld,rd) then
  964. begin
  965. firstpass(right);
  966. firstpass(left);
  967. case nodetype of
  968. addn,subn,xorn,orn,andn:
  969. ;
  970. { mul is a little bit restricted }
  971. muln:
  972. if not(mmx_type(left.resulttype) in
  973. [mmxu16bit,mmxs16bit,mmxfixed16]) then
  974. CGMessage(type_e_mismatch);
  975. else
  976. CGMessage(type_e_mismatch);
  977. end;
  978. location.loc:=LOC_MMXREGISTER;
  979. calcregisters(self,0,0,1);
  980. convdone:=true;
  981. end
  982. else
  983. {$endif SUPPORT_MMX}
  984. { this is a little bit dangerous, also the left type }
  985. { should be checked! This broke the mmx support }
  986. if (rd^.deftype=pointerdef) or
  987. is_zero_based_array(rd) then
  988. begin
  989. if is_zero_based_array(rd) then
  990. begin
  991. resulttype:=new(ppointerdef,init(parraydef(rd)^.elementtype));
  992. right:=gentypeconvnode(right,resulttype);
  993. firstpass(right);
  994. end;
  995. location.loc:=LOC_REGISTER;
  996. left:=gentypeconvnode(left,s32bitdef);
  997. firstpass(left);
  998. calcregisters(self,1,0,0);
  999. if nodetype=addn then
  1000. begin
  1001. if not(cs_extsyntax in aktmoduleswitches) or
  1002. (not(is_pchar(ld)) and not(m_add_pointer in aktmodeswitches)) then
  1003. CGMessage(type_e_mismatch);
  1004. { Dirty hack, to support multiple firstpasses (PFV) }
  1005. if (resulttype=nil) and
  1006. (rd^.deftype=pointerdef) and
  1007. (ppointerdef(rd)^.pointertype.def^.size>1) then
  1008. begin
  1009. left:=caddnode.create(muln,left,genordinalconstnode(ppointerdef(rd)^.pointertype.def^.size,s32bitdef));
  1010. firstpass(left);
  1011. end;
  1012. end
  1013. else
  1014. CGMessage(type_e_mismatch);
  1015. convdone:=true;
  1016. end
  1017. else
  1018. if (ld^.deftype=pointerdef) or
  1019. is_zero_based_array(ld) then
  1020. begin
  1021. if is_zero_based_array(ld) then
  1022. begin
  1023. resulttype:=new(ppointerdef,init(parraydef(ld)^.elementtype));
  1024. left:=gentypeconvnode(left,resulttype);
  1025. firstpass(left);
  1026. end;
  1027. location.loc:=LOC_REGISTER;
  1028. right:=gentypeconvnode(right,s32bitdef);
  1029. firstpass(right);
  1030. calcregisters(self,1,0,0);
  1031. case nodetype of
  1032. addn,subn : begin
  1033. if not(cs_extsyntax in aktmoduleswitches) or
  1034. (not(is_pchar(ld)) and not(m_add_pointer in aktmodeswitches)) then
  1035. CGMessage(type_e_mismatch);
  1036. { Dirty hack, to support multiple firstpasses (PFV) }
  1037. if (resulttype=nil) and
  1038. (ld^.deftype=pointerdef) and
  1039. (ppointerdef(ld)^.pointertype.def^.size>1) then
  1040. begin
  1041. right:=caddnode.create(muln,right,
  1042. genordinalconstnode(ppointerdef(ld)^.pointertype.def^.size,s32bitdef));
  1043. firstpass(right);
  1044. end;
  1045. end;
  1046. else
  1047. CGMessage(type_e_mismatch);
  1048. end;
  1049. convdone:=true;
  1050. end
  1051. else
  1052. if (rd^.deftype=procvardef) and (ld^.deftype=procvardef) and is_equal(rd,ld) then
  1053. begin
  1054. calcregisters(self,1,0,0);
  1055. location.loc:=LOC_REGISTER;
  1056. case nodetype of
  1057. equaln,unequaln : ;
  1058. else
  1059. CGMessage(type_e_mismatch);
  1060. end;
  1061. convdone:=true;
  1062. end
  1063. else
  1064. if (ld^.deftype=enumdef) and (rd^.deftype=enumdef) then
  1065. begin
  1066. if not(is_equal(ld,rd)) then
  1067. begin
  1068. right:=gentypeconvnode(right,ld);
  1069. firstpass(right);
  1070. end;
  1071. calcregisters(self,1,0,0);
  1072. case nodetype of
  1073. equaln,unequaln,
  1074. ltn,lten,gtn,gten : ;
  1075. else CGMessage(type_e_mismatch);
  1076. end;
  1077. convdone:=true;
  1078. end;
  1079. { the general solution is to convert to 32 bit int }
  1080. if not convdone then
  1081. begin
  1082. { but an int/int gives real/real! }
  1083. if nodetype=slashn then
  1084. begin
  1085. CGMessage(type_h_use_div_for_int);
  1086. right:=gentypeconvnode(right,bestrealdef^);
  1087. left:=gentypeconvnode(left,bestrealdef^);
  1088. firstpass(left);
  1089. firstpass(right);
  1090. { maybe we need an integer register to save }
  1091. { a reference }
  1092. if ((left.location.loc<>LOC_FPU) or
  1093. (right.location.loc<>LOC_FPU)) and
  1094. (left.registers32=right.registers32) then
  1095. calcregisters(self,1,1,0)
  1096. else
  1097. calcregisters(self,0,1,0);
  1098. location.loc:=LOC_FPU;
  1099. end
  1100. else
  1101. begin
  1102. right:=gentypeconvnode(right,s32bitdef);
  1103. left:=gentypeconvnode(left,s32bitdef);
  1104. firstpass(left);
  1105. firstpass(right);
  1106. calcregisters(self,1,0,0);
  1107. location.loc:=LOC_REGISTER;
  1108. end;
  1109. end;
  1110. if codegenerror then
  1111. exit;
  1112. { determines result type for comparions }
  1113. { here the is a problem with multiple passes }
  1114. { example length(s)+1 gets internal 'longint' type first }
  1115. { if it is a arg it is converted to 'LONGINT' }
  1116. { but a second first pass will reset this to 'longint' }
  1117. case nodetype of
  1118. ltn,lten,gtn,gten,equaln,unequaln:
  1119. begin
  1120. if (not assigned(resulttype)) or
  1121. (resulttype^.deftype=stringdef) then
  1122. resulttype:=booldef;
  1123. if is_64bitint(left.resulttype) then
  1124. location.loc:=LOC_JUMP
  1125. else
  1126. location.loc:=LOC_FLAGS;
  1127. end;
  1128. xorn:
  1129. begin
  1130. if not assigned(resulttype) then
  1131. resulttype:=left.resulttype;
  1132. location.loc:=LOC_REGISTER;
  1133. end;
  1134. addn:
  1135. begin
  1136. if not assigned(resulttype) then
  1137. begin
  1138. { for strings, return is always a 255 char string }
  1139. if is_shortstring(left.resulttype) then
  1140. resulttype:=cshortstringdef
  1141. else
  1142. resulttype:=left.resulttype;
  1143. end;
  1144. end;
  1145. else
  1146. if not assigned(resulttype) then
  1147. resulttype:=left.resulttype;
  1148. end;
  1149. end;
  1150. begin
  1151. caddnode:=taddnode;
  1152. end.
  1153. {
  1154. $Log$
  1155. Revision 1.20 2000-12-31 11:14:10 jonas
  1156. + implemented/fixed docompare() mathods for all nodes (not tested)
  1157. + nopt.pas, nadd.pas, i386/n386opt.pas: optimized nodes for adding strings
  1158. and constant strings/chars together
  1159. * n386add.pas: don't copy temp strings (of size 256) to another temp string
  1160. when adding
  1161. Revision 1.19 2000/12/16 15:55:32 jonas
  1162. + warning when there is a chance to get a range check error because of
  1163. automatic type conversion to u32bit
  1164. * arithmetic operations with a cardinal and a signed operand are carried
  1165. out in 64bit when range checking is on ("merged" from fixes branch)
  1166. Revision 1.18 2000/11/29 00:30:31 florian
  1167. * unused units removed from uses clause
  1168. * some changes for widestrings
  1169. Revision 1.17 2000/11/20 15:30:42 jonas
  1170. * changed types of values used for constant expression evaluation to
  1171. tconstexprint
  1172. Revision 1.16 2000/11/13 11:30:55 florian
  1173. * some bugs with interfaces and NIL fixed
  1174. Revision 1.15 2000/11/04 14:25:20 florian
  1175. + merged Attila's changes for interfaces, not tested yet
  1176. Revision 1.14 2000/10/31 22:02:47 peter
  1177. * symtable splitted, no real code changes
  1178. Revision 1.13 2000/10/14 10:14:50 peter
  1179. * moehrendorf oct 2000 rewrite
  1180. Revision 1.12 2000/10/01 19:48:23 peter
  1181. * lot of compile updates for cg11
  1182. Revision 1.11 2000/09/30 16:08:45 peter
  1183. * more cg11 updates
  1184. Revision 1.10 2000/09/28 19:49:52 florian
  1185. *** empty log message ***
  1186. Revision 1.9 2000/09/27 21:33:22 florian
  1187. * finally nadd.pas compiles
  1188. Revision 1.8 2000/09/27 20:25:44 florian
  1189. * more stuff fixed
  1190. Revision 1.7 2000/09/27 18:14:31 florian
  1191. * fixed a lot of syntax errors in the n*.pas stuff
  1192. Revision 1.6 2000/09/24 15:06:19 peter
  1193. * use defines.inc
  1194. Revision 1.5 2000/09/22 22:42:52 florian
  1195. * more fixes
  1196. Revision 1.4 2000/09/21 12:22:42 jonas
  1197. * put piece of code between -dnewoptimizations2 since it wasn't
  1198. necessary otherwise
  1199. + support for full boolean evaluation (from tcadd)
  1200. Revision 1.3 2000/09/20 21:50:59 florian
  1201. * updated
  1202. Revision 1.2 2000/08/29 08:24:45 jonas
  1203. * some modifications to -dcardinalmulfix code
  1204. Revision 1.1 2000/08/26 12:24:20 florian
  1205. * initial release
  1206. }