nadd.pas 50 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279
  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,
  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. right:=gentypeconvnode(right,cshortstringdef);
  398. firstpass(left);
  399. firstpass(right);
  400. { here we call STRCOPY }
  401. procinfo^.flags:=procinfo^.flags or pi_do_call;
  402. calcregisters(self,0,0,0);
  403. location.loc:=LOC_MEM;
  404. end
  405. else
  406. calcregisters(self,1,0,0);
  407. convdone:=true;
  408. end
  409. { is there a 64 bit type ? }
  410. else if ((porddef(rd)^.typ=s64bit) or (porddef(ld)^.typ=s64bit)) and
  411. { the / operator is handled later }
  412. (nodetype<>slashn) then
  413. begin
  414. if (porddef(ld)^.typ<>s64bit) then
  415. begin
  416. left:=gentypeconvnode(left,cs64bitdef);
  417. firstpass(left);
  418. end;
  419. if (porddef(rd)^.typ<>s64bit) then
  420. begin
  421. right:=gentypeconvnode(right,cs64bitdef);
  422. firstpass(right);
  423. end;
  424. calcregisters(self,2,0,0);
  425. convdone:=true;
  426. end
  427. else if ((porddef(rd)^.typ=u64bit) or (porddef(ld)^.typ=u64bit)) and
  428. { the / operator is handled later }
  429. (nodetype<>slashn) then
  430. begin
  431. if (porddef(ld)^.typ<>u64bit) then
  432. begin
  433. left:=gentypeconvnode(left,cu64bitdef);
  434. firstpass(left);
  435. end;
  436. if (porddef(rd)^.typ<>u64bit) then
  437. begin
  438. right:=gentypeconvnode(right,cu64bitdef);
  439. firstpass(right);
  440. end;
  441. calcregisters(self,2,0,0);
  442. convdone:=true;
  443. end
  444. else
  445. { is there a cardinal? }
  446. if ((porddef(rd)^.typ=u32bit) or (porddef(ld)^.typ=u32bit)) and
  447. { the / operator is handled later }
  448. (nodetype<>slashn) then
  449. begin
  450. if is_signed(ld) and
  451. { then rd = u32bit }
  452. { convert positive constants to u32bit }
  453. not(is_constintnode(left) and
  454. (tordconstnode(left).value >= 0)) and
  455. { range/overflow checking on mixed signed/cardinal expressions }
  456. { is only possible if you convert everything to 64bit (JM) }
  457. ((aktlocalswitches * [cs_check_overflow,cs_check_range] <> []) and
  458. (nodetype in [addn,subn,muln])) then
  459. begin
  460. { perform the operation in 64bit }
  461. CGMessage(type_w_mixed_signed_unsigned);
  462. left := gentypeconvnode(left,cs64bitdef);
  463. firstpass(left);
  464. right := gentypeconvnode(right,cs64bitdef);
  465. firstpass(right);
  466. end
  467. else
  468. begin
  469. if is_signed(ld) and
  470. not(is_constintnode(left) and
  471. (tordconstnode(left).value >= 0)) and
  472. (cs_check_range in aktlocalswitches) then
  473. CGMessage(type_w_mixed_signed_unsigned2);
  474. left := gentypeconvnode(left,u32bitdef);
  475. firstpass(left);
  476. if is_signed(rd) and
  477. { then ld = u32bit }
  478. { convert positive constants to u32bit }
  479. not(is_constintnode(right) and
  480. (tordconstnode(right).value >= 0)) and
  481. ((aktlocalswitches * [cs_check_overflow,cs_check_range] <> []) and
  482. (nodetype in [addn,subn,muln])) then
  483. begin
  484. { perform the operation in 64bit }
  485. CGMessage(type_w_mixed_signed_unsigned);
  486. left := gentypeconvnode(left,cs64bitdef);
  487. firstpass(left);
  488. right := gentypeconvnode(right,cs64bitdef);
  489. firstpass(right);
  490. end
  491. else
  492. begin
  493. if is_signed(rd) and
  494. not(is_constintnode(right) and
  495. (tordconstnode(right).value >= 0)) and
  496. (cs_check_range in aktlocalswitches) then
  497. CGMessage(type_w_mixed_signed_unsigned2);
  498. right := gentypeconvnode(right,u32bitdef);
  499. firstpass(right);
  500. end;
  501. end;
  502. { did we convert things to 64bit? }
  503. if porddef(left.resulttype)^.typ = s64bit then
  504. calcregisters(self,2,0,0)
  505. else
  506. begin
  507. calcregisters(self,1,0,0);
  508. { for unsigned mul we need an extra register }
  509. if nodetype=muln then
  510. inc(registers32);
  511. end;
  512. convdone:=true;
  513. end;
  514. end
  515. else
  516. { left side a setdef, must be before string processing,
  517. else array constructor can be seen as array of char (PFV) }
  518. if (ld^.deftype=setdef) {or is_array_constructor(ld)} then
  519. begin
  520. { trying to add a set element? }
  521. if (nodetype=addn) and (rd^.deftype<>setdef) then
  522. begin
  523. if (rt=setelementn) then
  524. begin
  525. if not(is_equal(psetdef(ld)^.elementtype.def,rd)) then
  526. CGMessage(type_e_set_element_are_not_comp);
  527. end
  528. else
  529. CGMessage(type_e_mismatch)
  530. end
  531. else
  532. begin
  533. if not(nodetype in [addn,subn,symdifn,muln,equaln,unequaln
  534. {$IfNDef NoSetInclusion}
  535. ,lten,gten
  536. {$EndIf NoSetInclusion}
  537. ]) then
  538. CGMessage(type_e_set_operation_unknown);
  539. { right def must be a also be set }
  540. if (rd^.deftype<>setdef) or not(is_equal(rd,ld)) then
  541. CGMessage(type_e_set_element_are_not_comp);
  542. end;
  543. { ranges require normsets }
  544. if (psetdef(ld)^.settype=smallset) and
  545. (rt=setelementn) and
  546. assigned(tsetelementnode(right).right) then
  547. begin
  548. { generate a temporary normset def, it'll be destroyed
  549. when the symtable is unloaded }
  550. tempdef:=new(psetdef,init(psetdef(ld)^.elementtype.def,255));
  551. left:=gentypeconvnode(left,tempdef);
  552. firstpass(left);
  553. ld:=left.resulttype;
  554. end;
  555. { if the destination is not a smallset then insert a typeconv
  556. which loads a smallset into a normal set }
  557. if (psetdef(ld)^.settype<>smallset) and
  558. (psetdef(rd)^.settype=smallset) then
  559. begin
  560. if (right.nodetype=setconstn) then
  561. begin
  562. t:=gensetconstnode(tsetconstnode(right).value_set,psetdef(left.resulttype));
  563. tsetconstnode(t).left:=tsetconstnode(right).left;
  564. tsetconstnode(right).left:=nil;
  565. right.free;
  566. right:=t;
  567. end
  568. else
  569. right:=gentypeconvnode(right,psetdef(left.resulttype));
  570. firstpass(right);
  571. end;
  572. { do constant evaluation }
  573. if (right.nodetype=setconstn) and
  574. not assigned(tsetconstnode(right).left) and
  575. (left.nodetype=setconstn) and
  576. not assigned(tsetconstnode(left).left) then
  577. begin
  578. new(resultset);
  579. case nodetype of
  580. addn : begin
  581. for i:=0 to 31 do
  582. resultset^[i]:=
  583. tsetconstnode(right).value_set^[i] or tsetconstnode(left).value_set^[i];
  584. t:=gensetconstnode(resultset,psetdef(ld));
  585. end;
  586. muln : begin
  587. for i:=0 to 31 do
  588. resultset^[i]:=
  589. tsetconstnode(right).value_set^[i] and tsetconstnode(left).value_set^[i];
  590. t:=gensetconstnode(resultset,psetdef(ld));
  591. end;
  592. subn : begin
  593. for i:=0 to 31 do
  594. resultset^[i]:=
  595. tsetconstnode(left).value_set^[i] and not(tsetconstnode(right).value_set^[i]);
  596. t:=gensetconstnode(resultset,psetdef(ld));
  597. end;
  598. symdifn : begin
  599. for i:=0 to 31 do
  600. resultset^[i]:=
  601. tsetconstnode(left).value_set^[i] xor tsetconstnode(right).value_set^[i];
  602. t:=gensetconstnode(resultset,psetdef(ld));
  603. end;
  604. unequaln : begin
  605. b:=true;
  606. for i:=0 to 31 do
  607. if tsetconstnode(right).value_set^[i]=tsetconstnode(left).value_set^[i] then
  608. begin
  609. b:=false;
  610. break;
  611. end;
  612. t:=genordinalconstnode(ord(b),booldef);
  613. end;
  614. equaln : begin
  615. b:=true;
  616. for i:=0 to 31 do
  617. if tsetconstnode(right).value_set^[i]<>tsetconstnode(left).value_set^[i] then
  618. begin
  619. b:=false;
  620. break;
  621. end;
  622. t:=genordinalconstnode(ord(b),booldef);
  623. end;
  624. {$IfNDef NoSetInclusion}
  625. lten : Begin
  626. b := true;
  627. For i := 0 to 31 Do
  628. If (tsetconstnode(right).value_set^[i] And tsetconstnode(left).value_set^[i]) <>
  629. tsetconstnode(left).value_set^[i] Then
  630. Begin
  631. b := false;
  632. Break
  633. End;
  634. t := genordinalconstnode(ord(b),booldef);
  635. End;
  636. gten : Begin
  637. b := true;
  638. For i := 0 to 31 Do
  639. If (tsetconstnode(left).value_set^[i] And tsetconstnode(right).value_set^[i]) <>
  640. tsetconstnode(right).value_set^[i] Then
  641. Begin
  642. b := false;
  643. Break
  644. End;
  645. t := genordinalconstnode(ord(b),booldef);
  646. End;
  647. {$EndIf NoSetInclusion}
  648. end;
  649. dispose(resultset);
  650. firstpass(t);
  651. pass_1:=t;
  652. exit;
  653. end
  654. else
  655. if psetdef(ld)^.settype=smallset then
  656. begin
  657. { are we adding set elements ? }
  658. if right.nodetype=setelementn then
  659. calcregisters(self,2,0,0)
  660. else
  661. calcregisters(self,1,0,0);
  662. location.loc:=LOC_REGISTER;
  663. end
  664. else
  665. begin
  666. calcregisters(self,0,0,0);
  667. { here we call SET... }
  668. procinfo^.flags:=procinfo^.flags or pi_do_call;
  669. location.loc:=LOC_MEM;
  670. end;
  671. convdone:=true;
  672. end
  673. else
  674. { compare pchar to char arrays by addresses
  675. like BP/Delphi }
  676. if (is_pchar(ld) and is_chararray(rd)) or
  677. (is_pchar(rd) and is_chararray(ld)) then
  678. begin
  679. if is_chararray(rd) then
  680. begin
  681. right:=gentypeconvnode(right,ld);
  682. firstpass(right);
  683. end
  684. else
  685. begin
  686. left:=gentypeconvnode(left,rd);
  687. firstpass(left);
  688. end;
  689. location.loc:=LOC_REGISTER;
  690. calcregisters(self,1,0,0);
  691. convdone:=true;
  692. end
  693. else
  694. { is one of the operands a string?,
  695. chararrays are also handled as strings (after conversion) }
  696. if (rd^.deftype=stringdef) or (ld^.deftype=stringdef) or
  697. ((is_chararray(rd) or is_char(rd)) and
  698. (is_chararray(ld) or is_char(ld))) then
  699. begin
  700. if is_widestring(rd) or is_widestring(ld) then
  701. begin
  702. if not(is_widestring(rd)) then
  703. right:=gentypeconvnode(right,cwidestringdef);
  704. if not(is_widestring(ld)) then
  705. left:=gentypeconvnode(left,cwidestringdef);
  706. resulttype:=cwidestringdef;
  707. { this is only for add, the comparisaion is handled later }
  708. location.loc:=LOC_REGISTER;
  709. end
  710. else if is_ansistring(rd) or is_ansistring(ld) then
  711. begin
  712. if not(is_ansistring(rd)) then
  713. right:=gentypeconvnode(right,cansistringdef);
  714. if not(is_ansistring(ld)) then
  715. left:=gentypeconvnode(left,cansistringdef);
  716. { we use ansistrings so no fast exit here }
  717. procinfo^.no_fast_exit:=true;
  718. resulttype:=cansistringdef;
  719. { this is only for add, the comparisaion is handled later }
  720. location.loc:=LOC_REGISTER;
  721. end
  722. else if is_longstring(rd) or is_longstring(ld) then
  723. begin
  724. if not(is_longstring(rd)) then
  725. right:=gentypeconvnode(right,clongstringdef);
  726. if not(is_longstring(ld)) then
  727. left:=gentypeconvnode(left,clongstringdef);
  728. resulttype:=clongstringdef;
  729. { this is only for add, the comparisaion is handled later }
  730. location.loc:=LOC_MEM;
  731. end
  732. else
  733. begin
  734. if not(is_shortstring(rd))
  735. {$ifdef newoptimizations2}
  736. {$ifdef i386}
  737. { shortstring + char handled seperately (JM) }
  738. and (not(cs_optimize in aktglobalswitches) or
  739. (nodetype <> addn) or not(is_char(rd)))
  740. {$endif i386}
  741. {$endif newoptimizations2}
  742. then
  743. right:=gentypeconvnode(right,cshortstringdef);
  744. if not(is_shortstring(ld)) then
  745. left:=gentypeconvnode(left,cshortstringdef);
  746. resulttype:=cshortstringdef;
  747. { this is only for add, the comparisaion is handled later }
  748. location.loc:=LOC_MEM;
  749. end;
  750. { only if there is a type cast we need to do again }
  751. { the first pass }
  752. if left.nodetype=typeconvn then
  753. firstpass(left);
  754. if right.nodetype=typeconvn then
  755. firstpass(right);
  756. { here we call STRCONCAT or STRCMP or STRCOPY }
  757. procinfo^.flags:=procinfo^.flags or pi_do_call;
  758. if location.loc=LOC_MEM then
  759. calcregisters(self,0,0,0)
  760. else
  761. calcregisters(self,1,0,0);
  762. {$ifdef newoptimizations2}
  763. {$ifdef i386}
  764. { not always necessary, only if it is not a constant char and }
  765. { not a regvar, but don't know how to check this here (JM) }
  766. if is_char(rd) then
  767. inc(registers32);
  768. {$endif i386}
  769. {$endif newoptimizations2}
  770. convdone:=true;
  771. end
  772. else
  773. { is one a real float ? }
  774. if (rd^.deftype=floatdef) or (ld^.deftype=floatdef) then
  775. begin
  776. { if one is a fixed, then convert to f32bit }
  777. if ((rd^.deftype=floatdef) and (pfloatdef(rd)^.typ=f32bit)) or
  778. ((ld^.deftype=floatdef) and (pfloatdef(ld)^.typ=f32bit)) then
  779. begin
  780. if not is_integer(rd) or (nodetype<>muln) then
  781. right:=gentypeconvnode(right,s32fixeddef);
  782. if not is_integer(ld) or (nodetype<>muln) then
  783. left:=gentypeconvnode(left,s32fixeddef);
  784. firstpass(left);
  785. firstpass(right);
  786. calcregisters(self,1,0,0);
  787. location.loc:=LOC_REGISTER;
  788. end
  789. else
  790. { convert both to bestreal }
  791. begin
  792. right:=gentypeconvnode(right,bestrealdef^);
  793. left:=gentypeconvnode(left,bestrealdef^);
  794. firstpass(left);
  795. firstpass(right);
  796. calcregisters(self,0,1,0);
  797. location.loc:=LOC_FPU;
  798. end;
  799. convdone:=true;
  800. end
  801. else
  802. { pointer comperation and subtraction }
  803. if (rd^.deftype=pointerdef) and (ld^.deftype=pointerdef) then
  804. begin
  805. location.loc:=LOC_REGISTER;
  806. { right:=gentypeconvnode(right,ld); }
  807. { firstpass(right); }
  808. calcregisters(self,1,0,0);
  809. case nodetype of
  810. equaln,unequaln :
  811. begin
  812. if is_equal(right.resulttype,voidpointerdef) then
  813. begin
  814. right:=gentypeconvnode(right,ld);
  815. firstpass(right);
  816. end
  817. else if is_equal(left.resulttype,voidpointerdef) then
  818. begin
  819. left:=gentypeconvnode(left,rd);
  820. firstpass(left);
  821. end
  822. else if not(is_equal(ld,rd)) then
  823. CGMessage(type_e_mismatch);
  824. end;
  825. ltn,lten,gtn,gten:
  826. begin
  827. if is_equal(right.resulttype,voidpointerdef) then
  828. begin
  829. right:=gentypeconvnode(right,ld);
  830. firstpass(right);
  831. end
  832. else if is_equal(left.resulttype,voidpointerdef) then
  833. begin
  834. left:=gentypeconvnode(left,rd);
  835. firstpass(left);
  836. end
  837. else if not(is_equal(ld,rd)) then
  838. CGMessage(type_e_mismatch);
  839. if not(cs_extsyntax in aktmoduleswitches) then
  840. CGMessage(type_e_mismatch);
  841. end;
  842. subn:
  843. begin
  844. if not(is_equal(ld,rd)) then
  845. CGMessage(type_e_mismatch);
  846. if not(cs_extsyntax in aktmoduleswitches) then
  847. CGMessage(type_e_mismatch);
  848. resulttype:=s32bitdef;
  849. exit;
  850. end;
  851. else CGMessage(type_e_mismatch);
  852. end;
  853. convdone:=true;
  854. end
  855. else
  856. if is_class_or_interface(rd) or is_class_or_interface(ld) then
  857. begin
  858. location.loc:=LOC_REGISTER;
  859. if is_class_or_interface(rd) and is_class_or_interface(ld) then
  860. begin
  861. if pobjectdef(rd)^.is_related(pobjectdef(ld)) then
  862. right:=gentypeconvnode(right,ld)
  863. else
  864. left:=gentypeconvnode(left,rd);
  865. end
  866. else if is_class_or_interface(rd) then
  867. left:=gentypeconvnode(left,rd)
  868. else
  869. right:=gentypeconvnode(right,ld);
  870. firstpass(right);
  871. firstpass(left);
  872. calcregisters(self,1,0,0);
  873. case nodetype of
  874. equaln,unequaln:
  875. ;
  876. else CGMessage(type_e_mismatch);
  877. end;
  878. convdone:=true;
  879. end
  880. else
  881. if (rd^.deftype=classrefdef) and (ld^.deftype=classrefdef) then
  882. begin
  883. location.loc:=LOC_REGISTER;
  884. if pobjectdef(pclassrefdef(rd)^.pointertype.def)^.is_related(pobjectdef(
  885. pclassrefdef(ld)^.pointertype.def)) then
  886. right:=gentypeconvnode(right,ld)
  887. else
  888. left:=gentypeconvnode(left,rd);
  889. firstpass(right);
  890. firstpass(left);
  891. calcregisters(self,1,0,0);
  892. case nodetype of
  893. equaln,unequaln : ;
  894. else CGMessage(type_e_mismatch);
  895. end;
  896. convdone:=true;
  897. end
  898. else
  899. { allows comperasion with nil pointer }
  900. if is_class_or_interface(rd) then
  901. begin
  902. location.loc:=LOC_REGISTER;
  903. left:=gentypeconvnode(left,rd);
  904. firstpass(left);
  905. calcregisters(self,1,0,0);
  906. case nodetype of
  907. equaln,unequaln : ;
  908. else CGMessage(type_e_mismatch);
  909. end;
  910. convdone:=true;
  911. end
  912. else
  913. if is_class_or_interface(ld) then
  914. begin
  915. location.loc:=LOC_REGISTER;
  916. right:=gentypeconvnode(right,ld);
  917. firstpass(right);
  918. calcregisters(self,1,0,0);
  919. case nodetype of
  920. equaln,unequaln : ;
  921. else CGMessage(type_e_mismatch);
  922. end;
  923. convdone:=true;
  924. end
  925. else
  926. if (rd^.deftype=classrefdef) then
  927. begin
  928. left:=gentypeconvnode(left,rd);
  929. firstpass(left);
  930. calcregisters(self,1,0,0);
  931. case nodetype of
  932. equaln,unequaln : ;
  933. else CGMessage(type_e_mismatch);
  934. end;
  935. convdone:=true;
  936. end
  937. else
  938. if (ld^.deftype=classrefdef) then
  939. begin
  940. right:=gentypeconvnode(right,ld);
  941. firstpass(right);
  942. calcregisters(self,1,0,0);
  943. case nodetype of
  944. equaln,unequaln : ;
  945. else
  946. CGMessage(type_e_mismatch);
  947. end;
  948. convdone:=true;
  949. end
  950. else
  951. { support procvar=nil,procvar<>nil }
  952. if ((ld^.deftype=procvardef) and (rt=niln)) or
  953. ((rd^.deftype=procvardef) and (lt=niln)) then
  954. begin
  955. calcregisters(self,1,0,0);
  956. location.loc:=LOC_REGISTER;
  957. case nodetype of
  958. equaln,unequaln : ;
  959. else
  960. CGMessage(type_e_mismatch);
  961. end;
  962. convdone:=true;
  963. end
  964. else
  965. {$ifdef SUPPORT_MMX}
  966. if (cs_mmx in aktlocalswitches) and is_mmx_able_array(ld) and
  967. is_mmx_able_array(rd) and is_equal(ld,rd) then
  968. begin
  969. firstpass(right);
  970. firstpass(left);
  971. case nodetype of
  972. addn,subn,xorn,orn,andn:
  973. ;
  974. { mul is a little bit restricted }
  975. muln:
  976. if not(mmx_type(left.resulttype) in
  977. [mmxu16bit,mmxs16bit,mmxfixed16]) then
  978. CGMessage(type_e_mismatch);
  979. else
  980. CGMessage(type_e_mismatch);
  981. end;
  982. location.loc:=LOC_MMXREGISTER;
  983. calcregisters(self,0,0,1);
  984. convdone:=true;
  985. end
  986. else
  987. {$endif SUPPORT_MMX}
  988. { this is a little bit dangerous, also the left type }
  989. { should be checked! This broke the mmx support }
  990. if (rd^.deftype=pointerdef) or
  991. is_zero_based_array(rd) then
  992. begin
  993. if is_zero_based_array(rd) then
  994. begin
  995. resulttype:=new(ppointerdef,init(parraydef(rd)^.elementtype));
  996. right:=gentypeconvnode(right,resulttype);
  997. firstpass(right);
  998. end;
  999. location.loc:=LOC_REGISTER;
  1000. left:=gentypeconvnode(left,s32bitdef);
  1001. firstpass(left);
  1002. calcregisters(self,1,0,0);
  1003. if nodetype=addn then
  1004. begin
  1005. if not(cs_extsyntax in aktmoduleswitches) or
  1006. (not(is_pchar(ld)) and not(m_add_pointer in aktmodeswitches)) then
  1007. CGMessage(type_e_mismatch);
  1008. { Dirty hack, to support multiple firstpasses (PFV) }
  1009. if (resulttype=nil) and
  1010. (rd^.deftype=pointerdef) and
  1011. (ppointerdef(rd)^.pointertype.def^.size>1) then
  1012. begin
  1013. left:=caddnode.create(muln,left,genordinalconstnode(ppointerdef(rd)^.pointertype.def^.size,s32bitdef));
  1014. firstpass(left);
  1015. end;
  1016. end
  1017. else
  1018. CGMessage(type_e_mismatch);
  1019. convdone:=true;
  1020. end
  1021. else
  1022. if (ld^.deftype=pointerdef) or
  1023. is_zero_based_array(ld) then
  1024. begin
  1025. if is_zero_based_array(ld) then
  1026. begin
  1027. resulttype:=new(ppointerdef,init(parraydef(ld)^.elementtype));
  1028. left:=gentypeconvnode(left,resulttype);
  1029. firstpass(left);
  1030. end;
  1031. location.loc:=LOC_REGISTER;
  1032. right:=gentypeconvnode(right,s32bitdef);
  1033. firstpass(right);
  1034. calcregisters(self,1,0,0);
  1035. case nodetype of
  1036. addn,subn : begin
  1037. if not(cs_extsyntax in aktmoduleswitches) or
  1038. (not(is_pchar(ld)) and not(m_add_pointer in aktmodeswitches)) then
  1039. CGMessage(type_e_mismatch);
  1040. { Dirty hack, to support multiple firstpasses (PFV) }
  1041. if (resulttype=nil) and
  1042. (ld^.deftype=pointerdef) and
  1043. (ppointerdef(ld)^.pointertype.def^.size>1) then
  1044. begin
  1045. right:=caddnode.create(muln,right,
  1046. genordinalconstnode(ppointerdef(ld)^.pointertype.def^.size,s32bitdef));
  1047. firstpass(right);
  1048. end;
  1049. end;
  1050. else
  1051. CGMessage(type_e_mismatch);
  1052. end;
  1053. convdone:=true;
  1054. end
  1055. else
  1056. if (rd^.deftype=procvardef) and (ld^.deftype=procvardef) and is_equal(rd,ld) then
  1057. begin
  1058. calcregisters(self,1,0,0);
  1059. location.loc:=LOC_REGISTER;
  1060. case nodetype of
  1061. equaln,unequaln : ;
  1062. else
  1063. CGMessage(type_e_mismatch);
  1064. end;
  1065. convdone:=true;
  1066. end
  1067. else
  1068. if (ld^.deftype=enumdef) and (rd^.deftype=enumdef) then
  1069. begin
  1070. if not(is_equal(ld,rd)) then
  1071. begin
  1072. right:=gentypeconvnode(right,ld);
  1073. firstpass(right);
  1074. end;
  1075. calcregisters(self,1,0,0);
  1076. case nodetype of
  1077. equaln,unequaln,
  1078. ltn,lten,gtn,gten : ;
  1079. else CGMessage(type_e_mismatch);
  1080. end;
  1081. convdone:=true;
  1082. end;
  1083. { the general solution is to convert to 32 bit int }
  1084. if not convdone then
  1085. begin
  1086. { but an int/int gives real/real! }
  1087. if nodetype=slashn then
  1088. begin
  1089. CGMessage(type_h_use_div_for_int);
  1090. right:=gentypeconvnode(right,bestrealdef^);
  1091. left:=gentypeconvnode(left,bestrealdef^);
  1092. firstpass(left);
  1093. firstpass(right);
  1094. { maybe we need an integer register to save }
  1095. { a reference }
  1096. if ((left.location.loc<>LOC_FPU) or
  1097. (right.location.loc<>LOC_FPU)) and
  1098. (left.registers32=right.registers32) then
  1099. calcregisters(self,1,1,0)
  1100. else
  1101. calcregisters(self,0,1,0);
  1102. location.loc:=LOC_FPU;
  1103. end
  1104. else
  1105. begin
  1106. right:=gentypeconvnode(right,s32bitdef);
  1107. left:=gentypeconvnode(left,s32bitdef);
  1108. firstpass(left);
  1109. firstpass(right);
  1110. calcregisters(self,1,0,0);
  1111. location.loc:=LOC_REGISTER;
  1112. end;
  1113. end;
  1114. if codegenerror then
  1115. exit;
  1116. { determines result type for comparions }
  1117. { here the is a problem with multiple passes }
  1118. { example length(s)+1 gets internal 'longint' type first }
  1119. { if it is a arg it is converted to 'LONGINT' }
  1120. { but a second first pass will reset this to 'longint' }
  1121. case nodetype of
  1122. ltn,lten,gtn,gten,equaln,unequaln:
  1123. begin
  1124. if (not assigned(resulttype)) or
  1125. (resulttype^.deftype=stringdef) then
  1126. resulttype:=booldef;
  1127. if is_64bitint(left.resulttype) then
  1128. location.loc:=LOC_JUMP
  1129. else
  1130. location.loc:=LOC_FLAGS;
  1131. end;
  1132. xorn:
  1133. begin
  1134. if not assigned(resulttype) then
  1135. resulttype:=left.resulttype;
  1136. location.loc:=LOC_REGISTER;
  1137. end;
  1138. addn:
  1139. begin
  1140. if not assigned(resulttype) then
  1141. begin
  1142. { for strings, return is always a 255 char string }
  1143. if is_shortstring(left.resulttype) then
  1144. resulttype:=cshortstringdef
  1145. else
  1146. resulttype:=left.resulttype;
  1147. end;
  1148. end;
  1149. else
  1150. if not assigned(resulttype) then
  1151. resulttype:=left.resulttype;
  1152. end;
  1153. end;
  1154. begin
  1155. caddnode:=taddnode;
  1156. end.
  1157. {
  1158. $Log$
  1159. Revision 1.19 2000-12-16 15:55:32 jonas
  1160. + warning when there is a chance to get a range check error because of
  1161. automatic type conversion to u32bit
  1162. * arithmetic operations with a cardinal and a signed operand are carried
  1163. out in 64bit when range checking is on ("merged" from fixes branch)
  1164. Revision 1.18 2000/11/29 00:30:31 florian
  1165. * unused units removed from uses clause
  1166. * some changes for widestrings
  1167. Revision 1.17 2000/11/20 15:30:42 jonas
  1168. * changed types of values used for constant expression evaluation to
  1169. tconstexprint
  1170. Revision 1.16 2000/11/13 11:30:55 florian
  1171. * some bugs with interfaces and NIL fixed
  1172. Revision 1.15 2000/11/04 14:25:20 florian
  1173. + merged Attila's changes for interfaces, not tested yet
  1174. Revision 1.14 2000/10/31 22:02:47 peter
  1175. * symtable splitted, no real code changes
  1176. Revision 1.13 2000/10/14 10:14:50 peter
  1177. * moehrendorf oct 2000 rewrite
  1178. Revision 1.12 2000/10/01 19:48:23 peter
  1179. * lot of compile updates for cg11
  1180. Revision 1.11 2000/09/30 16:08:45 peter
  1181. * more cg11 updates
  1182. Revision 1.10 2000/09/28 19:49:52 florian
  1183. *** empty log message ***
  1184. Revision 1.9 2000/09/27 21:33:22 florian
  1185. * finally nadd.pas compiles
  1186. Revision 1.8 2000/09/27 20:25:44 florian
  1187. * more stuff fixed
  1188. Revision 1.7 2000/09/27 18:14:31 florian
  1189. * fixed a lot of syntax errors in the n*.pas stuff
  1190. Revision 1.6 2000/09/24 15:06:19 peter
  1191. * use defines.inc
  1192. Revision 1.5 2000/09/22 22:42:52 florian
  1193. * more fixes
  1194. Revision 1.4 2000/09/21 12:22:42 jonas
  1195. * put piece of code between -dnewoptimizations2 since it wasn't
  1196. necessary otherwise
  1197. + support for full boolean evaluation (from tcadd)
  1198. Revision 1.3 2000/09/20 21:50:59 florian
  1199. * updated
  1200. Revision 1.2 2000/08/29 08:24:45 jonas
  1201. * some modifications to -dcardinalmulfix code
  1202. Revision 1.1 2000/08/26 12:24:20 florian
  1203. * initial release
  1204. }